diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-04 10:43:24 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-05 09:28:48 -0500 |
commit | 2f525d0148ef2734c8a172201e5e1e9167a8a5fd (patch) | |
tree | 6bd0efbdeb640fa52616b20f03aed7176eb6c297 /tools/perf/util/annotate.c | |
parent | 78f7defedbb4da73b9a07635c357c1afcaa55c8f (diff) |
perf annotate: Support multiple histograms in annotation
The perf annotate tool continues aggregating everything on just one
histograms, but to support the top model add support for one histogram
perf evsel in the evlist.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 9b25575b980c..7488fe99502c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -15,44 +15,40 @@ | |||
15 | #include "debug.h" | 15 | #include "debug.h" |
16 | #include "annotate.h" | 16 | #include "annotate.h" |
17 | 17 | ||
18 | static int symbol__alloc_hist(struct symbol *sym) | 18 | int symbol__alloc_hist(struct symbol *sym, int nevents) |
19 | { | 19 | { |
20 | struct annotation *notes = symbol__annotation(sym); | 20 | struct annotation *notes = symbol__annotation(sym); |
21 | const int size = (sizeof(*notes->histogram) + | ||
22 | (sym->end - sym->start) * sizeof(u64)); | ||
23 | 21 | ||
24 | notes->histogram = zalloc(size); | 22 | notes->sizeof_sym_hist = (sizeof(*notes->histograms) + |
25 | return notes->histogram == NULL ? -1 : 0; | 23 | (sym->end - sym->start) * sizeof(u64)); |
24 | notes->histograms = calloc(nevents, notes->sizeof_sym_hist); | ||
25 | return notes->histograms == NULL ? -1 : 0; | ||
26 | } | 26 | } |
27 | 27 | ||
28 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, u64 addr) | 28 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
29 | int evidx, u64 addr) | ||
29 | { | 30 | { |
30 | unsigned int sym_size, offset; | 31 | unsigned offset; |
31 | struct annotation *notes; | 32 | struct annotation *notes; |
32 | struct sym_hist *h; | 33 | struct sym_hist *h; |
33 | 34 | ||
34 | if (!sym || !map) | ||
35 | return 0; | ||
36 | |||
37 | notes = symbol__annotation(sym); | 35 | notes = symbol__annotation(sym); |
38 | if (notes->histogram == NULL && symbol__alloc_hist(sym) < 0) | 36 | if (notes->histograms == NULL) |
39 | return -ENOMEM; | 37 | return -ENOMEM; |
40 | 38 | ||
41 | sym_size = sym->end - sym->start; | ||
42 | offset = addr - sym->start; | ||
43 | |||
44 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); | 39 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); |
45 | 40 | ||
46 | if (offset >= sym_size) | 41 | if (addr >= sym->end) |
47 | return 0; | 42 | return 0; |
48 | 43 | ||
49 | h = notes->histogram; | 44 | offset = addr - sym->start; |
45 | h = annotation__histogram(notes, evidx); | ||
50 | h->sum++; | 46 | h->sum++; |
51 | h->addr[offset]++; | 47 | h->addr[offset]++; |
52 | 48 | ||
53 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 | 49 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 |
54 | "] => %" PRIu64 "\n", sym->start, sym->name, | 50 | ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, |
55 | addr, addr - sym->start, h->addr[offset]); | 51 | addr, addr - sym->start, evidx, h->addr[offset]); |
56 | return 0; | 52 | return 0; |
57 | } | 53 | } |
58 | 54 | ||
@@ -90,8 +86,8 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
90 | } | 86 | } |
91 | 87 | ||
92 | static void objdump_line__print(struct objdump_line *oline, | 88 | static void objdump_line__print(struct objdump_line *oline, |
93 | struct list_head *head, | 89 | struct list_head *head, struct symbol *sym, |
94 | struct symbol *sym, u64 len) | 90 | int evidx, u64 len) |
95 | { | 91 | { |
96 | static const char *prev_line; | 92 | static const char *prev_line; |
97 | static const char *prev_color; | 93 | static const char *prev_color; |
@@ -103,7 +99,7 @@ static void objdump_line__print(struct objdump_line *oline, | |||
103 | const char *color; | 99 | const char *color; |
104 | struct annotation *notes = symbol__annotation(sym); | 100 | struct annotation *notes = symbol__annotation(sym); |
105 | struct source_line *src_line = notes->src_line; | 101 | struct source_line *src_line = notes->src_line; |
106 | struct sym_hist *h = notes->histogram; | 102 | struct sym_hist *h = annotation__histogram(notes, evidx); |
107 | s64 offset = oline->offset; | 103 | s64 offset = oline->offset; |
108 | struct objdump_line *next = objdump__get_next_ip_line(head, oline); | 104 | struct objdump_line *next = objdump__get_next_ip_line(head, oline); |
109 | 105 | ||
@@ -328,7 +324,7 @@ static void symbol__free_source_line(struct symbol *sym, int len) | |||
328 | 324 | ||
329 | /* Get the filename:line for the colored entries */ | 325 | /* Get the filename:line for the colored entries */ |
330 | static int symbol__get_source_line(struct symbol *sym, struct map *map, | 326 | static int symbol__get_source_line(struct symbol *sym, struct map *map, |
331 | struct rb_root *root, int len, | 327 | int evidx, struct rb_root *root, int len, |
332 | const char *filename) | 328 | const char *filename) |
333 | { | 329 | { |
334 | u64 start; | 330 | u64 start; |
@@ -336,7 +332,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
336 | char cmd[PATH_MAX * 2]; | 332 | char cmd[PATH_MAX * 2]; |
337 | struct source_line *src_line; | 333 | struct source_line *src_line; |
338 | struct annotation *notes = symbol__annotation(sym); | 334 | struct annotation *notes = symbol__annotation(sym); |
339 | struct sym_hist *h = notes->histogram; | 335 | struct sym_hist *h = annotation__histogram(notes, evidx); |
340 | 336 | ||
341 | if (!h->sum) | 337 | if (!h->sum) |
342 | return 0; | 338 | return 0; |
@@ -409,10 +405,10 @@ static void print_summary(struct rb_root *root, const char *filename) | |||
409 | } | 405 | } |
410 | } | 406 | } |
411 | 407 | ||
412 | static void symbol__annotate_hits(struct symbol *sym) | 408 | static void symbol__annotate_hits(struct symbol *sym, int evidx) |
413 | { | 409 | { |
414 | struct annotation *notes = symbol__annotation(sym); | 410 | struct annotation *notes = symbol__annotation(sym); |
415 | struct sym_hist *h = notes->histogram; | 411 | struct sym_hist *h = annotation__histogram(notes, evidx); |
416 | u64 len = sym->end - sym->start, offset; | 412 | u64 len = sym->end - sym->start, offset; |
417 | 413 | ||
418 | for (offset = 0; offset < len; ++offset) | 414 | for (offset = 0; offset < len; ++offset) |
@@ -422,8 +418,8 @@ static void symbol__annotate_hits(struct symbol *sym) | |||
422 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 418 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); |
423 | } | 419 | } |
424 | 420 | ||
425 | int symbol__tty_annotate(struct symbol *sym, struct map *map, bool print_lines, | 421 | int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, |
426 | bool full_paths) | 422 | bool print_lines, bool full_paths) |
427 | { | 423 | { |
428 | struct dso *dso = map->dso; | 424 | struct dso *dso = map->dso; |
429 | const char *filename = dso->long_name, *d_filename; | 425 | const char *filename = dso->long_name, *d_filename; |
@@ -443,7 +439,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, bool print_lines, | |||
443 | len = sym->end - sym->start; | 439 | len = sym->end - sym->start; |
444 | 440 | ||
445 | if (print_lines) { | 441 | if (print_lines) { |
446 | symbol__get_source_line(sym, map, &source_line, len, filename); | 442 | symbol__get_source_line(sym, map, evidx, &source_line, |
443 | len, filename); | ||
447 | print_summary(&source_line, filename); | 444 | print_summary(&source_line, filename); |
448 | } | 445 | } |
449 | 446 | ||
@@ -452,10 +449,10 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, bool print_lines, | |||
452 | printf("------------------------------------------------\n"); | 449 | printf("------------------------------------------------\n"); |
453 | 450 | ||
454 | if (verbose) | 451 | if (verbose) |
455 | symbol__annotate_hits(sym); | 452 | symbol__annotate_hits(sym, evidx); |
456 | 453 | ||
457 | list_for_each_entry_safe(pos, n, &head, node) { | 454 | list_for_each_entry_safe(pos, n, &head, node) { |
458 | objdump_line__print(pos, &head, sym, len); | 455 | objdump_line__print(pos, &head, sym, evidx, len); |
459 | list_del(&pos->node); | 456 | list_del(&pos->node); |
460 | objdump_line__free(pos); | 457 | objdump_line__free(pos); |
461 | } | 458 | } |