perf session: Pass the perf_session to the event handling operations
[deliverable/linux.git] / tools / perf / util / data_map.c
CommitLineData
016e92fb
FW
1#include "data_map.h"
2#include "symbol.h"
3#include "util.h"
4#include "debug.h"
5
6
7static struct perf_file_handler *curr_handler;
8static unsigned long mmap_window = 32;
9static char __cwd[PATH_MAX];
10
d8f66248
ACM
11static int process_event_stub(event_t *event __used,
12 struct perf_session *session __used)
016e92fb 13{
62daacb5 14 dump_printf(": unhandled!\n");
016e92fb
FW
15 return 0;
16}
17
18void register_perf_file_handler(struct perf_file_handler *handler)
19{
20 if (!handler->process_sample_event)
21 handler->process_sample_event = process_event_stub;
22 if (!handler->process_mmap_event)
23 handler->process_mmap_event = process_event_stub;
24 if (!handler->process_comm_event)
25 handler->process_comm_event = process_event_stub;
26 if (!handler->process_fork_event)
27 handler->process_fork_event = process_event_stub;
28 if (!handler->process_exit_event)
29 handler->process_exit_event = process_event_stub;
30 if (!handler->process_lost_event)
31 handler->process_lost_event = process_event_stub;
32 if (!handler->process_read_event)
33 handler->process_read_event = process_event_stub;
34 if (!handler->process_throttle_event)
35 handler->process_throttle_event = process_event_stub;
36 if (!handler->process_unthrottle_event)
37 handler->process_unthrottle_event = process_event_stub;
38
39 curr_handler = handler;
40}
41
62daacb5
ACM
42static const char *event__name[] = {
43 [0] = "TOTAL",
44 [PERF_RECORD_MMAP] = "MMAP",
45 [PERF_RECORD_LOST] = "LOST",
46 [PERF_RECORD_COMM] = "COMM",
47 [PERF_RECORD_EXIT] = "EXIT",
48 [PERF_RECORD_THROTTLE] = "THROTTLE",
49 [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
50 [PERF_RECORD_FORK] = "FORK",
51 [PERF_RECORD_READ] = "READ",
52 [PERF_RECORD_SAMPLE] = "SAMPLE",
53};
54
55unsigned long event__total[PERF_RECORD_MAX];
56
57void event__print_totals(void)
58{
59 int i;
60 for (i = 0; i < PERF_RECORD_MAX; ++i)
61 pr_info("%10s events: %10ld\n",
62 event__name[i], event__total[i]);
63}
64
d8f66248
ACM
65static int process_event(event_t *event, struct perf_session *session,
66 unsigned long offset, unsigned long head)
016e92fb
FW
67{
68 trace_event(event);
69
62daacb5
ACM
70 if (event->header.type < PERF_RECORD_MAX) {
71 dump_printf("%p [%p]: PERF_RECORD_%s",
72 (void *)(offset + head),
73 (void *)(long)(event->header.size),
74 event__name[event->header.type]);
75 ++event__total[0];
76 ++event__total[event->header.type];
77 }
78
016e92fb
FW
79 switch (event->header.type) {
80 case PERF_RECORD_SAMPLE:
d8f66248 81 return curr_handler->process_sample_event(event, session);
016e92fb 82 case PERF_RECORD_MMAP:
d8f66248 83 return curr_handler->process_mmap_event(event, session);
016e92fb 84 case PERF_RECORD_COMM:
d8f66248 85 return curr_handler->process_comm_event(event, session);
016e92fb 86 case PERF_RECORD_FORK:
d8f66248 87 return curr_handler->process_fork_event(event, session);
016e92fb 88 case PERF_RECORD_EXIT:
d8f66248 89 return curr_handler->process_exit_event(event, session);
016e92fb 90 case PERF_RECORD_LOST:
d8f66248 91 return curr_handler->process_lost_event(event, session);
016e92fb 92 case PERF_RECORD_READ:
d8f66248 93 return curr_handler->process_read_event(event, session);
016e92fb 94 case PERF_RECORD_THROTTLE:
d8f66248 95 return curr_handler->process_throttle_event(event, session);
016e92fb 96 case PERF_RECORD_UNTHROTTLE:
d8f66248 97 return curr_handler->process_unthrottle_event(event, session);
016e92fb
FW
98 default:
99 curr_handler->total_unknown++;
100 return -1;
101 }
102}
103
716d69e4 104int perf_header__read_build_ids(int input, u64 offset, u64 size)
8d06367f 105{
8d06367f
ACM
106 struct build_id_event bev;
107 char filename[PATH_MAX];
716d69e4 108 u64 limit = offset + size;
8d06367f
ACM
109 int err = -1;
110
9e827dd0 111 while (offset < limit) {
8d06367f
ACM
112 struct dso *dso;
113 ssize_t len;
114
115 if (read(input, &bev, sizeof(bev)) != sizeof(bev))
116 goto out;
117
118 len = bev.header.size - sizeof(bev);
119 if (read(input, filename, len) != len)
120 goto out;
121
122 dso = dsos__findnew(filename);
123 if (dso != NULL)
124 dso__set_build_id(dso, &bev.build_id);
125
126 offset += bev.header.size;
127 }
128 err = 0;
129out:
130 return err;
131}
132
94c744b6
ACM
133int perf_session__process_events(struct perf_session *self,
134 int full_paths, int *cwdlen, char **cwd)
016e92fb 135{
6b0cb5f9 136 int err;
016e92fb
FW
137 unsigned long head, shift;
138 unsigned long offset = 0;
016e92fb
FW
139 size_t page_size;
140 u64 sample_type;
141 event_t *event;
142 uint32_t size;
016e92fb
FW
143 char *buf;
144
6b0cb5f9
ACM
145 if (curr_handler == NULL) {
146 pr_debug("Forgot to register perf file handler\n");
147 return -EINVAL;
148 }
016e92fb
FW
149
150 page_size = getpagesize();
151
94c744b6
ACM
152 head = self->header.data_offset;
153 sample_type = perf_header__sample_type(&self->header);
016e92fb 154
6b0cb5f9
ACM
155 err = -EINVAL;
156 if (curr_handler->sample_type_check &&
157 curr_handler->sample_type_check(sample_type) < 0)
94c744b6 158 goto out_err;
016e92fb 159
016e92fb
FW
160 if (!full_paths) {
161 if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
6b0cb5f9
ACM
162 pr_err("failed to get the current directory\n");
163 err = -errno;
94c744b6 164 goto out_err;
016e92fb
FW
165 }
166 *cwd = __cwd;
167 *cwdlen = strlen(*cwd);
168 } else {
169 *cwd = NULL;
170 *cwdlen = 0;
171 }
172
173 shift = page_size * (head / page_size);
174 offset += shift;
175 head -= shift;
176
177remap:
6b0cb5f9 178 buf = mmap(NULL, page_size * mmap_window, PROT_READ,
94c744b6 179 MAP_SHARED, self->fd, offset);
016e92fb 180 if (buf == MAP_FAILED) {
6b0cb5f9
ACM
181 pr_err("failed to mmap file\n");
182 err = -errno;
94c744b6 183 goto out_err;
016e92fb
FW
184 }
185
186more:
187 event = (event_t *)(buf + head);
188
189 size = event->header.size;
190 if (!size)
191 size = 8;
192
193 if (head + event->header.size >= page_size * mmap_window) {
194 int munmap_ret;
195
196 shift = page_size * (head / page_size);
197
198 munmap_ret = munmap(buf, page_size * mmap_window);
199 assert(munmap_ret == 0);
200
201 offset += shift;
202 head -= shift;
203 goto remap;
204 }
205
206 size = event->header.size;
207
208 dump_printf("\n%p [%p]: event: %d\n",
209 (void *)(offset + head),
210 (void *)(long)event->header.size,
211 event->header.type);
212
d8f66248 213 if (!size || process_event(event, self, offset, head) < 0) {
016e92fb
FW
214
215 dump_printf("%p [%p]: skipping unknown header type: %d\n",
216 (void *)(offset + head),
217 (void *)(long)(event->header.size),
218 event->header.type);
219
220 /*
221 * assume we lost track of the stream, check alignment, and
222 * increment a single u64 in the hope to catch on again 'soon'.
223 */
224
225 if (unlikely(head & 7))
226 head &= ~7ULL;
227
228 size = 8;
229 }
230
231 head += size;
232
94c744b6 233 if (offset + head >= self->header.data_offset + self->header.data_size)
016e92fb
FW
234 goto done;
235
94c744b6 236 if (offset + head < self->size)
016e92fb
FW
237 goto more;
238
239done:
6b0cb5f9 240 err = 0;
94c744b6 241out_err:
6b0cb5f9 242 return err;
016e92fb 243}
This page took 0.058249 seconds and 5 git commands to generate.