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 | |
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')
-rw-r--r-- | tools/perf/builtin-annotate.c | 29 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 15 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 57 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 29 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 4 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 16 | ||||
-rw-r--r-- | tools/perf/util/ui/browsers/annotate.c | 12 | ||||
-rw-r--r-- | tools/perf/util/ui/browsers/hists.c | 9 |
8 files changed, 106 insertions, 65 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 9072ef44cfcb..f3e44231b10d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -57,7 +57,18 @@ static int hists__add_entry(struct hists *self, struct addr_location *al) | |||
57 | if (he == NULL) | 57 | if (he == NULL) |
58 | return -ENOMEM; | 58 | return -ENOMEM; |
59 | 59 | ||
60 | return hist_entry__inc_addr_samples(he, al->addr); | 60 | if (he->ms.sym != NULL) { |
61 | /* | ||
62 | * All aggregated on the first sym_hist. | ||
63 | */ | ||
64 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
65 | if (notes->histograms == NULL && symbol__alloc_hist(he->ms.sym, 1) < 0) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | return hist_entry__inc_addr_samples(he, 0, al->addr); | ||
69 | } | ||
70 | |||
71 | return 0; | ||
61 | } | 72 | } |
62 | 73 | ||
63 | static int process_sample_event(union perf_event *event, | 74 | static int process_sample_event(union perf_event *event, |
@@ -81,9 +92,9 @@ static int process_sample_event(union perf_event *event, | |||
81 | return 0; | 92 | return 0; |
82 | } | 93 | } |
83 | 94 | ||
84 | static int hist_entry__tty_annotate(struct hist_entry *he) | 95 | static int hist_entry__tty_annotate(struct hist_entry *he, int evidx) |
85 | { | 96 | { |
86 | return symbol__tty_annotate(he->ms.sym, he->ms.map, | 97 | return symbol__tty_annotate(he->ms.sym, he->ms.map, evidx, |
87 | print_line, full_paths); | 98 | print_line, full_paths); |
88 | } | 99 | } |
89 | 100 | ||
@@ -100,7 +111,7 @@ static void hists__find_annotations(struct hists *self) | |||
100 | goto find_next; | 111 | goto find_next; |
101 | 112 | ||
102 | notes = symbol__annotation(he->ms.sym); | 113 | notes = symbol__annotation(he->ms.sym); |
103 | if (notes->histogram == NULL) { | 114 | if (notes->histograms == NULL) { |
104 | find_next: | 115 | find_next: |
105 | if (key == KEY_LEFT) | 116 | if (key == KEY_LEFT) |
106 | nd = rb_prev(nd); | 117 | nd = rb_prev(nd); |
@@ -110,7 +121,8 @@ find_next: | |||
110 | } | 121 | } |
111 | 122 | ||
112 | if (use_browser > 0) { | 123 | if (use_browser > 0) { |
113 | key = hist_entry__tui_annotate(he); | 124 | /* For now all is aggregated on the first */ |
125 | key = hist_entry__tui_annotate(he, 0); | ||
114 | switch (key) { | 126 | switch (key) { |
115 | case KEY_RIGHT: | 127 | case KEY_RIGHT: |
116 | next = rb_next(nd); | 128 | next = rb_next(nd); |
@@ -125,15 +137,16 @@ find_next: | |||
125 | if (next != NULL) | 137 | if (next != NULL) |
126 | nd = next; | 138 | nd = next; |
127 | } else { | 139 | } else { |
128 | hist_entry__tty_annotate(he); | 140 | /* For now all is aggregated on the first */ |
141 | hist_entry__tty_annotate(he, 0); | ||
129 | nd = rb_next(nd); | 142 | nd = rb_next(nd); |
130 | /* | 143 | /* |
131 | * Since we have a hist_entry per IP for the same | 144 | * Since we have a hist_entry per IP for the same |
132 | * symbol, free he->ms.sym->histogram to signal we already | 145 | * symbol, free he->ms.sym->histogram to signal we already |
133 | * processed this symbol. | 146 | * processed this symbol. |
134 | */ | 147 | */ |
135 | free(notes->histogram); | 148 | free(notes->histograms); |
136 | notes->histogram = NULL; | 149 | notes->histograms = NULL; |
137 | } | 150 | } |
138 | } | 151 | } |
139 | } | 152 | } |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 91e4cdba933b..de06bf55efff 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -118,8 +118,17 @@ static int perf_session__add_hist_entry(struct perf_session *session, | |||
118 | * so we don't allocated the extra space needed because the stdio | 118 | * so we don't allocated the extra space needed because the stdio |
119 | * code will not use it. | 119 | * code will not use it. |
120 | */ | 120 | */ |
121 | if (use_browser > 0) | 121 | if (al->sym != NULL && use_browser > 0) { |
122 | err = hist_entry__inc_addr_samples(he, al->addr); | 122 | /* |
123 | * All aggregated on the first sym_hist. | ||
124 | */ | ||
125 | struct annotation *notes = symbol__annotation(he->ms.sym); | ||
126 | if (notes->histograms == NULL && | ||
127 | symbol__alloc_hist(he->ms.sym, 1) < 0) | ||
128 | err = -ENOMEM; | ||
129 | else | ||
130 | err = hist_entry__inc_addr_samples(he, 0, al->addr); | ||
131 | } | ||
123 | 132 | ||
124 | return err; | 133 | return err; |
125 | } | 134 | } |
@@ -349,7 +358,7 @@ static int __cmd_report(void) | |||
349 | } | 358 | } |
350 | 359 | ||
351 | if (use_browser > 0) | 360 | if (use_browser > 0) |
352 | hists__tui_browse_tree(&session->hists_tree, help); | 361 | hists__tui_browse_tree(&session->hists_tree, help, 0); |
353 | else | 362 | else |
354 | hists__tty_browse_tree(&session->hists_tree, help); | 363 | hists__tty_browse_tree(&session->hists_tree, help); |
355 | 364 | ||
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 | } |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6e2fbc205299..0a5069ca6dd7 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -28,9 +28,21 @@ struct source_line { | |||
28 | char *path; | 28 | char *path; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | /** struct annotation - symbols with hits have this attached as in sannotation | ||
32 | * | ||
33 | * @histogram: Array of addr hit histograms per event being monitored | ||
34 | * @src_line: If 'print_lines' is specified, per source code line percentages | ||
35 | * | ||
36 | * src_line is allocated, percentages calculated and all sorted by percentage | ||
37 | * when the annotation is about to be presented, so the percentages are for | ||
38 | * one of the entries in the histogram array, i.e. for the event/counter being | ||
39 | * presented. It is deallocated right after symbol__{tui,tty,etc}_annotate | ||
40 | * returns. | ||
41 | */ | ||
31 | struct annotation { | 42 | struct annotation { |
32 | struct sym_hist *histogram; | ||
33 | struct source_line *src_line; | 43 | struct source_line *src_line; |
44 | struct sym_hist *histograms; | ||
45 | int sizeof_sym_hist; | ||
34 | }; | 46 | }; |
35 | 47 | ||
36 | struct sannotation { | 48 | struct sannotation { |
@@ -38,28 +50,35 @@ struct sannotation { | |||
38 | struct symbol symbol; | 50 | struct symbol symbol; |
39 | }; | 51 | }; |
40 | 52 | ||
53 | static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) | ||
54 | { | ||
55 | return ((void *)notes->histograms) + (notes->sizeof_sym_hist * idx); | ||
56 | } | ||
57 | |||
41 | static inline struct annotation *symbol__annotation(struct symbol *sym) | 58 | static inline struct annotation *symbol__annotation(struct symbol *sym) |
42 | { | 59 | { |
43 | struct sannotation *a = container_of(sym, struct sannotation, symbol); | 60 | struct sannotation *a = container_of(sym, struct sannotation, symbol); |
44 | return &a->annotation; | 61 | return &a->annotation; |
45 | } | 62 | } |
46 | 63 | ||
47 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, u64 addr); | 64 | int symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
65 | int evidx, u64 addr); | ||
66 | int symbol__alloc_hist(struct symbol *sym, int nevents); | ||
48 | 67 | ||
49 | int symbol__annotate(struct symbol *sym, struct map *map, | 68 | int symbol__annotate(struct symbol *sym, struct map *map, |
50 | struct list_head *head, size_t privsize); | 69 | struct list_head *head, size_t privsize); |
51 | 70 | ||
52 | int symbol__tty_annotate(struct symbol *sym, struct map *map, | 71 | int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, |
53 | bool print_lines, bool full_paths); | 72 | bool print_lines, bool full_paths); |
54 | 73 | ||
55 | #ifdef NO_NEWT_SUPPORT | 74 | #ifdef NO_NEWT_SUPPORT |
56 | static inline int symbol__tui_annotate(symbol *sym __used, | 75 | static inline int symbol__tui_annotate(symbol *sym __used, |
57 | struct map *map __used) | 76 | struct map *map __used, int evidx __used) |
58 | { | 77 | { |
59 | return 0; | 78 | return 0; |
60 | } | 79 | } |
61 | #else | 80 | #else |
62 | int symbol__tui_annotate(struct symbol *sym, struct map *map); | 81 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx); |
63 | #endif | 82 | #endif |
64 | 83 | ||
65 | #endif /* __PERF_ANNOTATE_H */ | 84 | #endif /* __PERF_ANNOTATE_H */ |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6d9c92c3d7cb..bac5ab684967 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -950,9 +950,9 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread) | |||
950 | } | 950 | } |
951 | } | 951 | } |
952 | 952 | ||
953 | int hist_entry__inc_addr_samples(struct hist_entry *he, u64 ip) | 953 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) |
954 | { | 954 | { |
955 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, ip); | 955 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); |
956 | } | 956 | } |
957 | 957 | ||
958 | int hist_entry__annotate(struct hist_entry *he, struct list_head *head, | 958 | int hist_entry__annotate(struct hist_entry *he, struct list_head *head, |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 8a201f755534..2c6cdae6a764 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -77,7 +77,7 @@ size_t hists__fprintf_nr_events(struct hists *self, FILE *fp); | |||
77 | size_t hists__fprintf(struct hists *self, struct hists *pair, | 77 | size_t hists__fprintf(struct hists *self, struct hists *pair, |
78 | bool show_displacement, FILE *fp); | 78 | bool show_displacement, FILE *fp); |
79 | 79 | ||
80 | int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip); | 80 | int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr); |
81 | int hist_entry__annotate(struct hist_entry *self, struct list_head *head, | 81 | int hist_entry__annotate(struct hist_entry *self, struct list_head *head, |
82 | size_t privsize); | 82 | size_t privsize); |
83 | 83 | ||
@@ -91,18 +91,20 @@ bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len); | |||
91 | #ifdef NO_NEWT_SUPPORT | 91 | #ifdef NO_NEWT_SUPPORT |
92 | static inline int hists__browse(struct hists *self __used, | 92 | static inline int hists__browse(struct hists *self __used, |
93 | const char *helpline __used, | 93 | const char *helpline __used, |
94 | const char *ev_name __used) | 94 | const char *ev_name __used, int evidx __used) |
95 | { | 95 | { |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline int hists__tui_browse_tree(struct rb_root *self __used, | 99 | static inline int hists__tui_browse_tree(struct rb_root *self __used, |
100 | const char *help __used) | 100 | const char *help __used, |
101 | int evidx __used) | ||
101 | { | 102 | { |
102 | return 0; | 103 | return 0; |
103 | } | 104 | } |
104 | 105 | ||
105 | static inline int hist_entry__tui_annotate(struct hist_entry *self __used) | 106 | static inline int hist_entry__tui_annotate(struct hist_entry *self __used, |
107 | int evidx __used) | ||
106 | { | 108 | { |
107 | return 0; | 109 | return 0; |
108 | } | 110 | } |
@@ -111,13 +113,13 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self __used) | |||
111 | #else | 113 | #else |
112 | #include <newt.h> | 114 | #include <newt.h> |
113 | int hists__browse(struct hists *self, const char *helpline, | 115 | int hists__browse(struct hists *self, const char *helpline, |
114 | const char *ev_name); | 116 | const char *ev_name, int evidx); |
115 | int hist_entry__tui_annotate(struct hist_entry *self); | 117 | int hist_entry__tui_annotate(struct hist_entry *self, int evidx); |
116 | 118 | ||
117 | #define KEY_LEFT NEWT_KEY_LEFT | 119 | #define KEY_LEFT NEWT_KEY_LEFT |
118 | #define KEY_RIGHT NEWT_KEY_RIGHT | 120 | #define KEY_RIGHT NEWT_KEY_RIGHT |
119 | 121 | ||
120 | int hists__tui_browse_tree(struct rb_root *self, const char *help); | 122 | int hists__tui_browse_tree(struct rb_root *self, const char *help, int evidx); |
121 | #endif | 123 | #endif |
122 | 124 | ||
123 | unsigned int hists__sort_list_width(struct hists *self); | 125 | unsigned int hists__sort_list_width(struct hists *self); |
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index daa7138d8015..8d8a16895af7 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
@@ -61,7 +61,7 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
61 | 61 | ||
62 | static double objdump_line__calc_percent(struct objdump_line *self, | 62 | static double objdump_line__calc_percent(struct objdump_line *self, |
63 | struct list_head *head, | 63 | struct list_head *head, |
64 | struct symbol *sym) | 64 | struct symbol *sym, int evidx) |
65 | { | 65 | { |
66 | double percent = 0.0; | 66 | double percent = 0.0; |
67 | 67 | ||
@@ -70,7 +70,7 @@ static double objdump_line__calc_percent(struct objdump_line *self, | |||
70 | unsigned int hits = 0; | 70 | unsigned int hits = 0; |
71 | struct annotation *notes = symbol__annotation(sym); | 71 | struct annotation *notes = symbol__annotation(sym); |
72 | struct source_line *src_line = notes->src_line; | 72 | struct source_line *src_line = notes->src_line; |
73 | struct sym_hist *h = notes->histogram; | 73 | struct sym_hist *h = annotation__histogram(notes, evidx); |
74 | s64 offset = self->offset; | 74 | s64 offset = self->offset; |
75 | struct objdump_line *next = objdump__get_next_ip_line(head, self); | 75 | struct objdump_line *next = objdump__get_next_ip_line(head, self); |
76 | 76 | ||
@@ -183,12 +183,12 @@ out: | |||
183 | return key; | 183 | return key; |
184 | } | 184 | } |
185 | 185 | ||
186 | int hist_entry__tui_annotate(struct hist_entry *he) | 186 | int hist_entry__tui_annotate(struct hist_entry *he, int evidx) |
187 | { | 187 | { |
188 | return symbol__tui_annotate(he->ms.sym, he->ms.map); | 188 | return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx); |
189 | } | 189 | } |
190 | 190 | ||
191 | int symbol__tui_annotate(struct symbol *sym, struct map *map) | 191 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx) |
192 | { | 192 | { |
193 | struct objdump_line *pos, *n; | 193 | struct objdump_line *pos, *n; |
194 | struct objdump_line_rb_node *rbpos; | 194 | struct objdump_line_rb_node *rbpos; |
@@ -223,7 +223,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map) | |||
223 | browser.b.width = line_len; | 223 | browser.b.width = line_len; |
224 | rbpos = objdump_line__rb(pos); | 224 | rbpos = objdump_line__rb(pos); |
225 | rbpos->idx = browser.b.nr_entries++; | 225 | rbpos->idx = browser.b.nr_entries++; |
226 | rbpos->percent = objdump_line__calc_percent(pos, &head, sym); | 226 | rbpos->percent = objdump_line__calc_percent(pos, &head, sym, evidx); |
227 | if (rbpos->percent < 0.01) | 227 | if (rbpos->percent < 0.01) |
228 | continue; | 228 | continue; |
229 | objdump__insert_line(&browser.entries, rbpos); | 229 | objdump__insert_line(&browser.entries, rbpos); |
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index 86428239fa65..294b49538522 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c | |||
@@ -797,7 +797,8 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size, | |||
797 | return printed; | 797 | return printed; |
798 | } | 798 | } |
799 | 799 | ||
800 | int hists__browse(struct hists *self, const char *helpline, const char *ev_name) | 800 | int hists__browse(struct hists *self, const char *helpline, |
801 | const char *ev_name, int evidx) | ||
801 | { | 802 | { |
802 | struct hist_browser *browser = hist_browser__new(self); | 803 | struct hist_browser *browser = hist_browser__new(self); |
803 | struct pstack *fstack; | 804 | struct pstack *fstack; |
@@ -935,7 +936,7 @@ do_annotate: | |||
935 | if (he == NULL) | 936 | if (he == NULL) |
936 | continue; | 937 | continue; |
937 | 938 | ||
938 | hist_entry__tui_annotate(he); | 939 | hist_entry__tui_annotate(he, evidx); |
939 | } else if (choice == browse_map) | 940 | } else if (choice == browse_map) |
940 | map__browse(browser->selection->map); | 941 | map__browse(browser->selection->map); |
941 | else if (choice == zoom_dso) { | 942 | else if (choice == zoom_dso) { |
@@ -984,7 +985,7 @@ out: | |||
984 | return key; | 985 | return key; |
985 | } | 986 | } |
986 | 987 | ||
987 | int hists__tui_browse_tree(struct rb_root *self, const char *help) | 988 | int hists__tui_browse_tree(struct rb_root *self, const char *help, int evidx) |
988 | { | 989 | { |
989 | struct rb_node *first = rb_first(self), *nd = first, *next; | 990 | struct rb_node *first = rb_first(self), *nd = first, *next; |
990 | int key = 0; | 991 | int key = 0; |
@@ -993,7 +994,7 @@ int hists__tui_browse_tree(struct rb_root *self, const char *help) | |||
993 | struct hists *hists = rb_entry(nd, struct hists, rb_node); | 994 | struct hists *hists = rb_entry(nd, struct hists, rb_node); |
994 | const char *ev_name = __event_name(hists->type, hists->config); | 995 | const char *ev_name = __event_name(hists->type, hists->config); |
995 | 996 | ||
996 | key = hists__browse(hists, help, ev_name); | 997 | key = hists__browse(hists, help, ev_name, evidx); |
997 | switch (key) { | 998 | switch (key) { |
998 | case NEWT_KEY_TAB: | 999 | case NEWT_KEY_TAB: |
999 | next = rb_next(nd); | 1000 | next = rb_next(nd); |