diff options
author | Namhyung Kim <namhyung@kernel.org> | 2012-11-09 11:21:02 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-03-15 12:06:07 -0400 |
commit | c7e7b6101361025fbea03833c6aee18e3d7bed34 (patch) | |
tree | 166aa05b910104e9bed6cf53fd1fa26fdd31352b | |
parent | d8d7cd93e6b5f42bd2ae77680b5dc27415ba7492 (diff) |
perf annotate browser: Support event group view on TUI
Dynamically allocate browser_disasm_line according to a number of group
members. This way we can handle multiple events in a general manner.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/878v5tl2vc.fsf@sejong.aot.lge.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 93 |
1 files changed, 75 insertions, 18 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 8b16926dd56e..f56247a03a22 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -17,6 +17,10 @@ struct browser_disasm_line { | |||
17 | u32 idx; | 17 | u32 idx; |
18 | int idx_asm; | 18 | int idx_asm; |
19 | int jump_sources; | 19 | int jump_sources; |
20 | /* | ||
21 | * actual length of this array is saved on the nr_events field | ||
22 | * of the struct annotate_browser | ||
23 | */ | ||
20 | double percent[1]; | 24 | double percent[1]; |
21 | }; | 25 | }; |
22 | 26 | ||
@@ -34,8 +38,9 @@ struct annotate_browser { | |||
34 | struct ui_browser b; | 38 | struct ui_browser b; |
35 | struct rb_root entries; | 39 | struct rb_root entries; |
36 | struct rb_node *curr_hot; | 40 | struct rb_node *curr_hot; |
37 | struct disasm_line *selection; | 41 | struct disasm_line *selection; |
38 | struct disasm_line **offsets; | 42 | struct disasm_line **offsets; |
43 | int nr_events; | ||
39 | u64 start; | 44 | u64 start; |
40 | int nr_asm_entries; | 45 | int nr_asm_entries; |
41 | int nr_entries; | 46 | int nr_entries; |
@@ -95,14 +100,24 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
95 | (!current_entry || (browser->use_navkeypressed && | 100 | (!current_entry || (browser->use_navkeypressed && |
96 | !browser->navkeypressed))); | 101 | !browser->navkeypressed))); |
97 | int width = browser->width, printed; | 102 | int width = browser->width, printed; |
103 | int i, pcnt_width = 7 * ab->nr_events; | ||
104 | double percent_max = 0.0; | ||
98 | char bf[256]; | 105 | char bf[256]; |
99 | 106 | ||
100 | if (dl->offset != -1 && bdl->percent[0] != 0.0) { | 107 | for (i = 0; i < ab->nr_events; i++) { |
101 | ui_browser__set_percent_color(browser, bdl->percent[0], current_entry); | 108 | if (bdl->percent[i] > percent_max) |
102 | slsmg_printf("%6.2f ", bdl->percent[0]); | 109 | percent_max = bdl->percent[i]; |
110 | } | ||
111 | |||
112 | if (dl->offset != -1 && percent_max != 0.0) { | ||
113 | for (i = 0; i < ab->nr_events; i++) { | ||
114 | ui_browser__set_percent_color(browser, bdl->percent[i], | ||
115 | current_entry); | ||
116 | slsmg_printf("%6.2f ", bdl->percent[i]); | ||
117 | } | ||
103 | } else { | 118 | } else { |
104 | ui_browser__set_percent_color(browser, 0, current_entry); | 119 | ui_browser__set_percent_color(browser, 0, current_entry); |
105 | slsmg_write_nstring(" ", 7); | 120 | slsmg_write_nstring(" ", pcnt_width); |
106 | } | 121 | } |
107 | 122 | ||
108 | SLsmg_write_char(' '); | 123 | SLsmg_write_char(' '); |
@@ -112,12 +127,12 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
112 | width += 1; | 127 | width += 1; |
113 | 128 | ||
114 | if (!*dl->line) | 129 | if (!*dl->line) |
115 | slsmg_write_nstring(" ", width - 7); | 130 | slsmg_write_nstring(" ", width - pcnt_width); |
116 | else if (dl->offset == -1) { | 131 | else if (dl->offset == -1) { |
117 | printed = scnprintf(bf, sizeof(bf), "%*s ", | 132 | printed = scnprintf(bf, sizeof(bf), "%*s ", |
118 | ab->addr_width, " "); | 133 | ab->addr_width, " "); |
119 | slsmg_write_nstring(bf, printed); | 134 | slsmg_write_nstring(bf, printed); |
120 | slsmg_write_nstring(dl->line, width - printed - 6); | 135 | slsmg_write_nstring(dl->line, width - printed - pcnt_width + 1); |
121 | } else { | 136 | } else { |
122 | u64 addr = dl->offset; | 137 | u64 addr = dl->offset; |
123 | int color = -1; | 138 | int color = -1; |
@@ -176,7 +191,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
176 | } | 191 | } |
177 | 192 | ||
178 | disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); | 193 | disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); |
179 | slsmg_write_nstring(bf, width - 10 - printed); | 194 | slsmg_write_nstring(bf, width - pcnt_width - 3 - printed); |
180 | } | 195 | } |
181 | 196 | ||
182 | if (current_entry) | 197 | if (current_entry) |
@@ -201,6 +216,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
201 | unsigned int from, to; | 216 | unsigned int from, to; |
202 | struct map_symbol *ms = ab->b.priv; | 217 | struct map_symbol *ms = ab->b.priv; |
203 | struct symbol *sym = ms->sym; | 218 | struct symbol *sym = ms->sym; |
219 | u8 pcnt_width = 7; | ||
204 | 220 | ||
205 | /* PLT symbols contain external offsets */ | 221 | /* PLT symbols contain external offsets */ |
206 | if (strstr(sym->name, "@plt")) | 222 | if (strstr(sym->name, "@plt")) |
@@ -224,23 +240,44 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
224 | to = (u64)btarget->idx; | 240 | to = (u64)btarget->idx; |
225 | } | 241 | } |
226 | 242 | ||
243 | pcnt_width *= ab->nr_events; | ||
244 | |||
227 | ui_browser__set_color(browser, HE_COLORSET_CODE); | 245 | ui_browser__set_color(browser, HE_COLORSET_CODE); |
228 | __ui_browser__line_arrow(browser, 9 + ab->addr_width, from, to); | 246 | __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width, |
247 | from, to); | ||
229 | } | 248 | } |
230 | 249 | ||
231 | static unsigned int annotate_browser__refresh(struct ui_browser *browser) | 250 | static unsigned int annotate_browser__refresh(struct ui_browser *browser) |
232 | { | 251 | { |
252 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | ||
233 | int ret = ui_browser__list_head_refresh(browser); | 253 | int ret = ui_browser__list_head_refresh(browser); |
254 | int pcnt_width; | ||
255 | |||
256 | pcnt_width = 7 * ab->nr_events; | ||
234 | 257 | ||
235 | if (annotate_browser__opts.jump_arrows) | 258 | if (annotate_browser__opts.jump_arrows) |
236 | annotate_browser__draw_current_jump(browser); | 259 | annotate_browser__draw_current_jump(browser); |
237 | 260 | ||
238 | ui_browser__set_color(browser, HE_COLORSET_NORMAL); | 261 | ui_browser__set_color(browser, HE_COLORSET_NORMAL); |
239 | __ui_browser__vline(browser, 7, 0, browser->height - 1); | 262 | __ui_browser__vline(browser, pcnt_width, 0, browser->height - 1); |
240 | return ret; | 263 | return ret; |
241 | } | 264 | } |
242 | 265 | ||
243 | static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl) | 266 | static int disasm__cmp(struct browser_disasm_line *a, |
267 | struct browser_disasm_line *b, int nr_pcnt) | ||
268 | { | ||
269 | int i; | ||
270 | |||
271 | for (i = 0; i < nr_pcnt; i++) { | ||
272 | if (a->percent[i] == b->percent[i]) | ||
273 | continue; | ||
274 | return a->percent[i] < b->percent[i]; | ||
275 | } | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl, | ||
280 | int nr_events) | ||
244 | { | 281 | { |
245 | struct rb_node **p = &root->rb_node; | 282 | struct rb_node **p = &root->rb_node; |
246 | struct rb_node *parent = NULL; | 283 | struct rb_node *parent = NULL; |
@@ -249,7 +286,8 @@ static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_l | |||
249 | while (*p != NULL) { | 286 | while (*p != NULL) { |
250 | parent = *p; | 287 | parent = *p; |
251 | l = rb_entry(parent, struct browser_disasm_line, rb_node); | 288 | l = rb_entry(parent, struct browser_disasm_line, rb_node); |
252 | if (bdl->percent[0] < l->percent[0]) | 289 | |
290 | if (disasm__cmp(bdl, l, nr_events)) | ||
253 | p = &(*p)->rb_left; | 291 | p = &(*p)->rb_left; |
254 | else | 292 | else |
255 | p = &(*p)->rb_right; | 293 | p = &(*p)->rb_right; |
@@ -313,6 +351,8 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, | |||
313 | list_for_each_entry(pos, ¬es->src->source, node) { | 351 | list_for_each_entry(pos, ¬es->src->source, node) { |
314 | struct browser_disasm_line *bpos = disasm_line__browser(pos); | 352 | struct browser_disasm_line *bpos = disasm_line__browser(pos); |
315 | const char *path = NULL; | 353 | const char *path = NULL; |
354 | double max_percent = 0.0; | ||
355 | int i; | ||
316 | 356 | ||
317 | if (pos->offset == -1) { | 357 | if (pos->offset == -1) { |
318 | RB_CLEAR_NODE(&bpos->rb_node); | 358 | RB_CLEAR_NODE(&bpos->rb_node); |
@@ -320,15 +360,24 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, | |||
320 | } | 360 | } |
321 | 361 | ||
322 | next = disasm__get_next_ip_line(¬es->src->source, pos); | 362 | next = disasm__get_next_ip_line(¬es->src->source, pos); |
323 | bpos->percent[0] = disasm__calc_percent(notes, evsel->idx, | ||
324 | pos->offset, next ? next->offset : len, | ||
325 | &path); | ||
326 | 363 | ||
327 | if (bpos->percent[0] < 0.01) { | 364 | for (i = 0; i < browser->nr_events; i++) { |
365 | bpos->percent[i] = disasm__calc_percent(notes, | ||
366 | evsel->idx + i, | ||
367 | pos->offset, | ||
368 | next ? next->offset : len, | ||
369 | &path); | ||
370 | |||
371 | if (max_percent < bpos->percent[i]) | ||
372 | max_percent = bpos->percent[i]; | ||
373 | } | ||
374 | |||
375 | if (max_percent < 0.01) { | ||
328 | RB_CLEAR_NODE(&bpos->rb_node); | 376 | RB_CLEAR_NODE(&bpos->rb_node); |
329 | continue; | 377 | continue; |
330 | } | 378 | } |
331 | disasm_rb_tree__insert(&browser->entries, bpos); | 379 | disasm_rb_tree__insert(&browser->entries, bpos, |
380 | browser->nr_events); | ||
332 | } | 381 | } |
333 | pthread_mutex_unlock(¬es->lock); | 382 | pthread_mutex_unlock(¬es->lock); |
334 | 383 | ||
@@ -829,6 +878,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
829 | }, | 878 | }, |
830 | }; | 879 | }; |
831 | int ret = -1; | 880 | int ret = -1; |
881 | int nr_pcnt = 1; | ||
882 | size_t sizeof_bdl = sizeof(struct browser_disasm_line); | ||
832 | 883 | ||
833 | if (sym == NULL) | 884 | if (sym == NULL) |
834 | return -1; | 885 | return -1; |
@@ -844,7 +895,12 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
844 | return -1; | 895 | return -1; |
845 | } | 896 | } |
846 | 897 | ||
847 | if (symbol__annotate(sym, map, sizeof(struct browser_disasm_line)) < 0) { | 898 | if (perf_evsel__is_group_event(evsel)) { |
899 | nr_pcnt = evsel->nr_members; | ||
900 | sizeof_bdl += sizeof(double) * (nr_pcnt - 1); | ||
901 | } | ||
902 | |||
903 | if (symbol__annotate(sym, map, sizeof_bdl) < 0) { | ||
848 | ui__error("%s", ui_helpline__last_msg); | 904 | ui__error("%s", ui_helpline__last_msg); |
849 | goto out_free_offsets; | 905 | goto out_free_offsets; |
850 | } | 906 | } |
@@ -882,6 +938,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
882 | browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size); | 938 | browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size); |
883 | browser.max_addr_width = hex_width(sym->end); | 939 | browser.max_addr_width = hex_width(sym->end); |
884 | browser.jumps_width = width_jumps(browser.max_jump_sources); | 940 | browser.jumps_width = width_jumps(browser.max_jump_sources); |
941 | browser.nr_events = nr_pcnt; | ||
885 | browser.b.nr_entries = browser.nr_entries; | 942 | browser.b.nr_entries = browser.nr_entries; |
886 | browser.b.entries = ¬es->src->source, | 943 | browser.b.entries = ¬es->src->source, |
887 | browser.b.width += 18; /* Percentage */ | 944 | browser.b.width += 18; /* Percentage */ |