diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-27 13:29:22 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-27 14:22:01 -0500 |
commit | 62daacb51a2bf8480e6f6b3696b03f102fc15eb0 (patch) | |
tree | 5b9ed87005a5e59bcc95dd9a42e3d09d6481362d /tools/perf/util | |
parent | 1de8e24520ffdcf2a90c842eed937f59079a2abd (diff) |
perf tools: Reorganize event processing routines, lotsa dups killed
While implementing event__preprocess_sample, that will do all of
the symbol lookup in one convenient function, I noticed that
util/process_event.[ch] were not being used at all, then started
looking if there were other functions that could be shared
and...
All those functions really don't need to receive offset + head,
the only thing they did was common to all of them, so do it at
one place instead.
Stats about number of each type of event processed now is done
in a central place.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: John Kacur <jkacur@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1259346563-12568-11-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/data_map.c | 56 | ||||
-rw-r--r-- | tools/perf/util/data_map.h | 2 | ||||
-rw-r--r-- | tools/perf/util/event.c | 74 | ||||
-rw-r--r-- | tools/perf/util/event.h | 17 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 7 | ||||
-rw-r--r-- | tools/perf/util/process_event.c | 53 | ||||
-rw-r--r-- | tools/perf/util/process_event.h | 29 | ||||
-rw-r--r-- | tools/perf/util/process_events.c | 64 | ||||
-rw-r--r-- | tools/perf/util/process_events.h | 35 |
9 files changed, 135 insertions, 202 deletions
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index b238462b8983..ca0bedf637c2 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c | |||
@@ -8,11 +8,9 @@ static struct perf_file_handler *curr_handler; | |||
8 | static unsigned long mmap_window = 32; | 8 | static unsigned long mmap_window = 32; |
9 | static char __cwd[PATH_MAX]; | 9 | static char __cwd[PATH_MAX]; |
10 | 10 | ||
11 | static int | 11 | static int process_event_stub(event_t *event __used) |
12 | process_event_stub(event_t *event __used, | ||
13 | unsigned long offset __used, | ||
14 | unsigned long head __used) | ||
15 | { | 12 | { |
13 | dump_printf(": unhandled!\n"); | ||
16 | return 0; | 14 | return 0; |
17 | } | 15 | } |
18 | 16 | ||
@@ -40,30 +38,62 @@ void register_perf_file_handler(struct perf_file_handler *handler) | |||
40 | curr_handler = handler; | 38 | curr_handler = handler; |
41 | } | 39 | } |
42 | 40 | ||
41 | static const char *event__name[] = { | ||
42 | [0] = "TOTAL", | ||
43 | [PERF_RECORD_MMAP] = "MMAP", | ||
44 | [PERF_RECORD_LOST] = "LOST", | ||
45 | [PERF_RECORD_COMM] = "COMM", | ||
46 | [PERF_RECORD_EXIT] = "EXIT", | ||
47 | [PERF_RECORD_THROTTLE] = "THROTTLE", | ||
48 | [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", | ||
49 | [PERF_RECORD_FORK] = "FORK", | ||
50 | [PERF_RECORD_READ] = "READ", | ||
51 | [PERF_RECORD_SAMPLE] = "SAMPLE", | ||
52 | }; | ||
53 | |||
54 | unsigned long event__total[PERF_RECORD_MAX]; | ||
55 | |||
56 | void event__print_totals(void) | ||
57 | { | ||
58 | int i; | ||
59 | for (i = 0; i < PERF_RECORD_MAX; ++i) | ||
60 | pr_info("%10s events: %10ld\n", | ||
61 | event__name[i], event__total[i]); | ||
62 | } | ||
63 | |||
43 | static int | 64 | static int |
44 | process_event(event_t *event, unsigned long offset, unsigned long head) | 65 | process_event(event_t *event, unsigned long offset, unsigned long head) |
45 | { | 66 | { |
46 | trace_event(event); | 67 | trace_event(event); |
47 | 68 | ||
69 | if (event->header.type < PERF_RECORD_MAX) { | ||
70 | dump_printf("%p [%p]: PERF_RECORD_%s", | ||
71 | (void *)(offset + head), | ||
72 | (void *)(long)(event->header.size), | ||
73 | event__name[event->header.type]); | ||
74 | ++event__total[0]; | ||
75 | ++event__total[event->header.type]; | ||
76 | } | ||
77 | |||
48 | switch (event->header.type) { | 78 | switch (event->header.type) { |
49 | case PERF_RECORD_SAMPLE: | 79 | case PERF_RECORD_SAMPLE: |
50 | return curr_handler->process_sample_event(event, offset, head); | 80 | return curr_handler->process_sample_event(event); |
51 | case PERF_RECORD_MMAP: | 81 | case PERF_RECORD_MMAP: |
52 | return curr_handler->process_mmap_event(event, offset, head); | 82 | return curr_handler->process_mmap_event(event); |
53 | case PERF_RECORD_COMM: | 83 | case PERF_RECORD_COMM: |
54 | return curr_handler->process_comm_event(event, offset, head); | 84 | return curr_handler->process_comm_event(event); |
55 | case PERF_RECORD_FORK: | 85 | case PERF_RECORD_FORK: |
56 | return curr_handler->process_fork_event(event, offset, head); | 86 | return curr_handler->process_fork_event(event); |
57 | case PERF_RECORD_EXIT: | 87 | case PERF_RECORD_EXIT: |
58 | return curr_handler->process_exit_event(event, offset, head); | 88 | return curr_handler->process_exit_event(event); |
59 | case PERF_RECORD_LOST: | 89 | case PERF_RECORD_LOST: |
60 | return curr_handler->process_lost_event(event, offset, head); | 90 | return curr_handler->process_lost_event(event); |
61 | case PERF_RECORD_READ: | 91 | case PERF_RECORD_READ: |
62 | return curr_handler->process_read_event(event, offset, head); | 92 | return curr_handler->process_read_event(event); |
63 | case PERF_RECORD_THROTTLE: | 93 | case PERF_RECORD_THROTTLE: |
64 | return curr_handler->process_throttle_event(event, offset, head); | 94 | return curr_handler->process_throttle_event(event); |
65 | case PERF_RECORD_UNTHROTTLE: | 95 | case PERF_RECORD_UNTHROTTLE: |
66 | return curr_handler->process_unthrottle_event(event, offset, head); | 96 | return curr_handler->process_unthrottle_event(event); |
67 | default: | 97 | default: |
68 | curr_handler->total_unknown++; | 98 | curr_handler->total_unknown++; |
69 | return -1; | 99 | return -1; |
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h index ae036ecd7625..3180ff7e3633 100644 --- a/tools/perf/util/data_map.h +++ b/tools/perf/util/data_map.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "event.h" | 4 | #include "event.h" |
5 | #include "header.h" | 5 | #include "header.h" |
6 | 6 | ||
7 | typedef int (*event_type_handler_t)(event_t *, unsigned long, unsigned long); | 7 | typedef int (*event_type_handler_t)(event_t *); |
8 | 8 | ||
9 | struct perf_file_handler { | 9 | struct perf_file_handler { |
10 | event_type_handler_t process_sample_event; | 10 | event_type_handler_t process_sample_event; |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1dae7e3b400d..70b4aa03b472 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include "event.h" | 2 | #include "event.h" |
3 | #include "debug.h" | 3 | #include "debug.h" |
4 | #include "string.h" | 4 | #include "string.h" |
5 | #include "thread.h" | ||
5 | 6 | ||
6 | static pid_t event__synthesize_comm(pid_t pid, int full, | 7 | static pid_t event__synthesize_comm(pid_t pid, int full, |
7 | int (*process)(event_t *event)) | 8 | int (*process)(event_t *event)) |
@@ -175,3 +176,76 @@ void event__synthesize_threads(int (*process)(event_t *event)) | |||
175 | 176 | ||
176 | closedir(proc); | 177 | closedir(proc); |
177 | } | 178 | } |
179 | |||
180 | char *event__cwd; | ||
181 | int event__cwdlen; | ||
182 | |||
183 | struct events_stats event__stats; | ||
184 | |||
185 | int event__process_comm(event_t *self) | ||
186 | { | ||
187 | struct thread *thread = threads__findnew(self->comm.pid); | ||
188 | |||
189 | dump_printf("PERF_RECORD_COMM: %s:%d\n", | ||
190 | self->comm.comm, self->comm.pid); | ||
191 | |||
192 | if (thread == NULL || thread__set_comm(thread, self->comm.comm)) { | ||
193 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | int event__process_lost(event_t *self) | ||
201 | { | ||
202 | dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); | ||
203 | event__stats.lost += self->lost.lost; | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | int event__process_mmap(event_t *self) | ||
208 | { | ||
209 | struct thread *thread = threads__findnew(self->mmap.pid); | ||
210 | struct map *map = map__new(&self->mmap, MAP__FUNCTION, | ||
211 | event__cwd, event__cwdlen); | ||
212 | |||
213 | dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n", | ||
214 | self->mmap.pid, self->mmap.tid, | ||
215 | (void *)(long)self->mmap.start, | ||
216 | (void *)(long)self->mmap.len, | ||
217 | (void *)(long)self->mmap.pgoff, | ||
218 | self->mmap.filename); | ||
219 | |||
220 | if (thread == NULL || map == NULL) | ||
221 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
222 | else | ||
223 | thread__insert_map(thread, map); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | int event__process_task(event_t *self) | ||
229 | { | ||
230 | struct thread *thread = threads__findnew(self->fork.pid); | ||
231 | struct thread *parent = threads__findnew(self->fork.ppid); | ||
232 | |||
233 | dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid, | ||
234 | self->fork.ppid, self->fork.ptid); | ||
235 | /* | ||
236 | * A thread clone will have the same PID for both parent and child. | ||
237 | */ | ||
238 | if (thread == parent) | ||
239 | return 0; | ||
240 | |||
241 | if (self->header.type == PERF_RECORD_EXIT) | ||
242 | return 0; | ||
243 | |||
244 | if (thread == NULL || parent == NULL || | ||
245 | thread__fork(thread, parent) < 0) { | ||
246 | dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); | ||
247 | return -1; | ||
248 | } | ||
249 | |||
250 | return 0; | ||
251 | } | ||
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 3ae3c964c901..13c12c75f970 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -80,6 +80,13 @@ typedef union event_union { | |||
80 | struct sample_event sample; | 80 | struct sample_event sample; |
81 | } event_t; | 81 | } event_t; |
82 | 82 | ||
83 | struct events_stats { | ||
84 | unsigned long total; | ||
85 | unsigned long lost; | ||
86 | }; | ||
87 | |||
88 | void event__print_totals(void); | ||
89 | |||
83 | enum map_type { | 90 | enum map_type { |
84 | MAP__FUNCTION = 0, | 91 | MAP__FUNCTION = 0, |
85 | 92 | ||
@@ -135,4 +142,14 @@ void map__fixup_end(struct map *self); | |||
135 | int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); | 142 | int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); |
136 | void event__synthesize_threads(int (*process)(event_t *event)); | 143 | void event__synthesize_threads(int (*process)(event_t *event)); |
137 | 144 | ||
145 | extern char *event__cwd; | ||
146 | extern int event__cwdlen; | ||
147 | extern struct events_stats event__stats; | ||
148 | extern unsigned long event__total[PERF_RECORD_MAX]; | ||
149 | |||
150 | int event__process_comm(event_t *self); | ||
151 | int event__process_lost(event_t *self); | ||
152 | int event__process_mmap(event_t *self); | ||
153 | int event__process_task(event_t *self); | ||
154 | |||
138 | #endif /* __PERF_RECORD_H */ | 155 | #endif /* __PERF_RECORD_H */ |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 7393a02fd8d4..f26cd9ba00fd 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -10,13 +10,6 @@ struct callchain_param callchain_param = { | |||
10 | .min_percent = 0.5 | 10 | .min_percent = 0.5 |
11 | }; | 11 | }; |
12 | 12 | ||
13 | unsigned long total; | ||
14 | unsigned long total_mmap; | ||
15 | unsigned long total_comm; | ||
16 | unsigned long total_fork; | ||
17 | unsigned long total_unknown; | ||
18 | unsigned long total_lost; | ||
19 | |||
20 | /* | 13 | /* |
21 | * histogram, sorted on item, collects counts | 14 | * histogram, sorted on item, collects counts |
22 | */ | 15 | */ |
diff --git a/tools/perf/util/process_event.c b/tools/perf/util/process_event.c deleted file mode 100644 index a970789581a2..000000000000 --- a/tools/perf/util/process_event.c +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | #include "process_event.h" | ||
2 | |||
3 | char *cwd; | ||
4 | int cwdlen; | ||
5 | |||
6 | int | ||
7 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | ||
8 | { | ||
9 | struct map *map = map__new(&event->mmap, cwd, cwdlen); | ||
10 | struct thread *thread = threads__findnew(event->mmap.pid); | ||
11 | |||
12 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", | ||
13 | (void *)(offset + head), | ||
14 | (void *)(long)(event->header.size), | ||
15 | event->mmap.pid, | ||
16 | event->mmap.tid, | ||
17 | (void *)(long)event->mmap.start, | ||
18 | (void *)(long)event->mmap.len, | ||
19 | (void *)(long)event->mmap.pgoff, | ||
20 | event->mmap.filename); | ||
21 | |||
22 | if (thread == NULL || map == NULL) { | ||
23 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | thread__insert_map(thread, map); | ||
28 | total_mmap++; | ||
29 | |||
30 | return 0; | ||
31 | |||
32 | } | ||
33 | |||
34 | int | ||
35 | process_comm_event(event_t *event, unsigned long offset, unsigned long head) | ||
36 | { | ||
37 | struct thread *thread = threads__findnew(event->comm.pid); | ||
38 | |||
39 | dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n", | ||
40 | (void *)(offset + head), | ||
41 | (void *)(long)(event->header.size), | ||
42 | event->comm.comm, event->comm.pid); | ||
43 | |||
44 | if (thread == NULL || | ||
45 | thread__set_comm_adjust(thread, event->comm.comm)) { | ||
46 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | ||
47 | return -1; | ||
48 | } | ||
49 | total_comm++; | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
diff --git a/tools/perf/util/process_event.h b/tools/perf/util/process_event.h deleted file mode 100644 index 6f68c69736cd..000000000000 --- a/tools/perf/util/process_event.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | #ifndef __PROCESS_EVENT_H | ||
2 | #define __PROCESS_EVENT_H | ||
3 | |||
4 | #include "../builtin.h" | ||
5 | #include "util.h" | ||
6 | |||
7 | #include "color.h" | ||
8 | #include <linux/list.h> | ||
9 | #include "cache.h" | ||
10 | #include <linux/rbtree.h> | ||
11 | #include "symbol.h" | ||
12 | #include "string.h" | ||
13 | |||
14 | #include "../perf.h" | ||
15 | #include "debug.h" | ||
16 | |||
17 | #include "parse-options.h" | ||
18 | #include "parse-events.h" | ||
19 | |||
20 | #include "thread.h" | ||
21 | #include "sort.h" | ||
22 | #include "hist.h" | ||
23 | |||
24 | extern char *cwd; | ||
25 | extern int cwdlen; | ||
26 | extern int process_mmap_event(event_t *, unsigned long, unsigned long); | ||
27 | extern int process_comm_event(event_t *, unsigned long , unsigned long); | ||
28 | |||
29 | #endif /* __PROCESS_H */ | ||
diff --git a/tools/perf/util/process_events.c b/tools/perf/util/process_events.c deleted file mode 100644 index 53778684641c..000000000000 --- a/tools/perf/util/process_events.c +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | #include "process_events.h" | ||
2 | |||
3 | char *cwd; | ||
4 | int cwdlen; | ||
5 | |||
6 | int | ||
7 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | ||
8 | { | ||
9 | struct map *map = map__new(&event->mmap, MAP__FUNCTION, cwd, cwdlen); | ||
10 | struct thread *thread = threads__findnew(event->mmap.pid); | ||
11 | |||
12 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", | ||
13 | (void *)(offset + head), | ||
14 | (void *)(long)(event->header.size), | ||
15 | event->mmap.pid, | ||
16 | event->mmap.tid, | ||
17 | (void *)(long)event->mmap.start, | ||
18 | (void *)(long)event->mmap.len, | ||
19 | (void *)(long)event->mmap.pgoff, | ||
20 | event->mmap.filename); | ||
21 | |||
22 | if (thread == NULL || map == NULL) { | ||
23 | dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | thread__insert_map(thread, map); | ||
28 | total_mmap++; | ||
29 | |||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | int | ||
34 | process_task_event(event_t *event, unsigned long offset, unsigned long head) | ||
35 | { | ||
36 | struct thread *thread = threads__findnew(event->fork.pid); | ||
37 | struct thread *parent = threads__findnew(event->fork.ppid); | ||
38 | |||
39 | dump_printf("%p [%p]: PERF_RECORD_%s: (%d:%d):(%d:%d)\n", | ||
40 | (void *)(offset + head), | ||
41 | (void *)(long)(event->header.size), | ||
42 | event->header.type == PERF_RECORD_FORK ? "FORK" : "EXIT", | ||
43 | event->fork.pid, event->fork.tid, | ||
44 | event->fork.ppid, event->fork.ptid); | ||
45 | |||
46 | /* | ||
47 | * A thread clone will have the same PID for both | ||
48 | * parent and child. | ||
49 | */ | ||
50 | if (thread == parent) | ||
51 | return 0; | ||
52 | |||
53 | if (event->header.type == PERF_RECORD_EXIT) | ||
54 | return 0; | ||
55 | |||
56 | if (!thread || !parent || thread__fork(thread, parent)) { | ||
57 | dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); | ||
58 | return -1; | ||
59 | } | ||
60 | total_fork++; | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
diff --git a/tools/perf/util/process_events.h b/tools/perf/util/process_events.h deleted file mode 100644 index 73d092f83283..000000000000 --- a/tools/perf/util/process_events.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | #ifndef __PROCESS_EVENTS_H | ||
2 | #define __PROCESS_EVENTS_H | ||
3 | |||
4 | #include "../builtin.h" | ||
5 | |||
6 | #include "util.h" | ||
7 | #include "color.h" | ||
8 | #include <linux/list.h> | ||
9 | #include "cache.h" | ||
10 | #include <linux/rbtree.h> | ||
11 | #include "symbol.h" | ||
12 | #include "string.h" | ||
13 | #include "callchain.h" | ||
14 | #include "strlist.h" | ||
15 | #include "values.h" | ||
16 | |||
17 | #include "../perf.h" | ||
18 | #include "debug.h" | ||
19 | #include "header.h" | ||
20 | |||
21 | #include "parse-options.h" | ||
22 | #include "parse-events.h" | ||
23 | |||
24 | #include "data_map.h" | ||
25 | #include "thread.h" | ||
26 | #include "sort.h" | ||
27 | #include "hist.h" | ||
28 | |||
29 | extern char *cwd; | ||
30 | extern int cwdlen; | ||
31 | |||
32 | extern int process_mmap_event(event_t *, unsigned long , unsigned long); | ||
33 | extern int process_task_event(event_t *, unsigned long, unsigned long); | ||
34 | |||
35 | #endif /* __PROCESS_EVENTS_H */ | ||