diff options
Diffstat (limited to 'tools/perf/ui')
-rw-r--r-- | tools/perf/ui/browser.c | 39 | ||||
-rw-r--r-- | tools/perf/ui/browser.h | 3 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 153 | ||||
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 2 |
4 files changed, 146 insertions, 51 deletions
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 3ccf6e14f89b..6680fa5cb9dd 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c | |||
@@ -150,7 +150,7 @@ unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser) | |||
150 | while (nd != NULL) { | 150 | while (nd != NULL) { |
151 | ui_browser__gotorc(browser, row, 0); | 151 | ui_browser__gotorc(browser, row, 0); |
152 | browser->write(browser, nd, row); | 152 | browser->write(browser, nd, row); |
153 | if (++row == browser->height) | 153 | if (++row == browser->rows) |
154 | break; | 154 | break; |
155 | nd = rb_next(nd); | 155 | nd = rb_next(nd); |
156 | } | 156 | } |
@@ -166,7 +166,7 @@ bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row) | |||
166 | void ui_browser__refresh_dimensions(struct ui_browser *browser) | 166 | void ui_browser__refresh_dimensions(struct ui_browser *browser) |
167 | { | 167 | { |
168 | browser->width = SLtt_Screen_Cols - 1; | 168 | browser->width = SLtt_Screen_Cols - 1; |
169 | browser->height = SLtt_Screen_Rows - 2; | 169 | browser->height = browser->rows = SLtt_Screen_Rows - 2; |
170 | browser->y = 1; | 170 | browser->y = 1; |
171 | browser->x = 0; | 171 | browser->x = 0; |
172 | } | 172 | } |
@@ -250,7 +250,10 @@ int ui_browser__show(struct ui_browser *browser, const char *title, | |||
250 | int err; | 250 | int err; |
251 | va_list ap; | 251 | va_list ap; |
252 | 252 | ||
253 | ui_browser__refresh_dimensions(browser); | 253 | if (browser->refresh_dimensions == NULL) |
254 | browser->refresh_dimensions = ui_browser__refresh_dimensions; | ||
255 | |||
256 | browser->refresh_dimensions(browser); | ||
254 | 257 | ||
255 | pthread_mutex_lock(&ui__lock); | 258 | pthread_mutex_lock(&ui__lock); |
256 | __ui_browser__show_title(browser, title); | 259 | __ui_browser__show_title(browser, title); |
@@ -279,7 +282,7 @@ static void ui_browser__scrollbar_set(struct ui_browser *browser) | |||
279 | { | 282 | { |
280 | int height = browser->height, h = 0, pct = 0, | 283 | int height = browser->height, h = 0, pct = 0, |
281 | col = browser->width, | 284 | col = browser->width, |
282 | row = browser->y - 1; | 285 | row = 0; |
283 | 286 | ||
284 | if (browser->nr_entries > 1) { | 287 | if (browser->nr_entries > 1) { |
285 | pct = ((browser->index * (browser->height - 1)) / | 288 | pct = ((browser->index * (browser->height - 1)) / |
@@ -367,7 +370,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs) | |||
367 | 370 | ||
368 | if (key == K_RESIZE) { | 371 | if (key == K_RESIZE) { |
369 | ui__refresh_dimensions(false); | 372 | ui__refresh_dimensions(false); |
370 | ui_browser__refresh_dimensions(browser); | 373 | browser->refresh_dimensions(browser); |
371 | __ui_browser__show_title(browser, browser->title); | 374 | __ui_browser__show_title(browser, browser->title); |
372 | ui_helpline__puts(browser->helpline); | 375 | ui_helpline__puts(browser->helpline); |
373 | continue; | 376 | continue; |
@@ -389,7 +392,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs) | |||
389 | if (browser->index == browser->nr_entries - 1) | 392 | if (browser->index == browser->nr_entries - 1) |
390 | break; | 393 | break; |
391 | ++browser->index; | 394 | ++browser->index; |
392 | if (browser->index == browser->top_idx + browser->height) { | 395 | if (browser->index == browser->top_idx + browser->rows) { |
393 | ++browser->top_idx; | 396 | ++browser->top_idx; |
394 | browser->seek(browser, +1, SEEK_CUR); | 397 | browser->seek(browser, +1, SEEK_CUR); |
395 | } | 398 | } |
@@ -405,10 +408,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs) | |||
405 | break; | 408 | break; |
406 | case K_PGDN: | 409 | case K_PGDN: |
407 | case ' ': | 410 | case ' ': |
408 | if (browser->top_idx + browser->height > browser->nr_entries - 1) | 411 | if (browser->top_idx + browser->rows > browser->nr_entries - 1) |
409 | break; | 412 | break; |
410 | 413 | ||
411 | offset = browser->height; | 414 | offset = browser->rows; |
412 | if (browser->index + offset > browser->nr_entries - 1) | 415 | if (browser->index + offset > browser->nr_entries - 1) |
413 | offset = browser->nr_entries - 1 - browser->index; | 416 | offset = browser->nr_entries - 1 - browser->index; |
414 | browser->index += offset; | 417 | browser->index += offset; |
@@ -419,10 +422,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs) | |||
419 | if (browser->top_idx == 0) | 422 | if (browser->top_idx == 0) |
420 | break; | 423 | break; |
421 | 424 | ||
422 | if (browser->top_idx < browser->height) | 425 | if (browser->top_idx < browser->rows) |
423 | offset = browser->top_idx; | 426 | offset = browser->top_idx; |
424 | else | 427 | else |
425 | offset = browser->height; | 428 | offset = browser->rows; |
426 | 429 | ||
427 | browser->index -= offset; | 430 | browser->index -= offset; |
428 | browser->top_idx -= offset; | 431 | browser->top_idx -= offset; |
@@ -432,7 +435,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs) | |||
432 | ui_browser__reset_index(browser); | 435 | ui_browser__reset_index(browser); |
433 | break; | 436 | break; |
434 | case K_END: | 437 | case K_END: |
435 | offset = browser->height - 1; | 438 | offset = browser->rows - 1; |
436 | if (offset >= browser->nr_entries) | 439 | if (offset >= browser->nr_entries) |
437 | offset = browser->nr_entries - 1; | 440 | offset = browser->nr_entries - 1; |
438 | 441 | ||
@@ -462,7 +465,7 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser) | |||
462 | if (!browser->filter || !browser->filter(browser, pos)) { | 465 | if (!browser->filter || !browser->filter(browser, pos)) { |
463 | ui_browser__gotorc(browser, row, 0); | 466 | ui_browser__gotorc(browser, row, 0); |
464 | browser->write(browser, pos, row); | 467 | browser->write(browser, pos, row); |
465 | if (++row == browser->height) | 468 | if (++row == browser->rows) |
466 | break; | 469 | break; |
467 | } | 470 | } |
468 | } | 471 | } |
@@ -587,7 +590,7 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser) | |||
587 | if (!browser->filter || !browser->filter(browser, *pos)) { | 590 | if (!browser->filter || !browser->filter(browser, *pos)) { |
588 | ui_browser__gotorc(browser, row, 0); | 591 | ui_browser__gotorc(browser, row, 0); |
589 | browser->write(browser, pos, row); | 592 | browser->write(browser, pos, row); |
590 | if (++row == browser->height) | 593 | if (++row == browser->rows) |
591 | break; | 594 | break; |
592 | } | 595 | } |
593 | 596 | ||
@@ -623,7 +626,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser, | |||
623 | 626 | ||
624 | SLsmg_set_char_set(1); | 627 | SLsmg_set_char_set(1); |
625 | 628 | ||
626 | if (start < browser->top_idx + browser->height) { | 629 | if (start < browser->top_idx + browser->rows) { |
627 | row = start - browser->top_idx; | 630 | row = start - browser->top_idx; |
628 | ui_browser__gotorc(browser, row, column); | 631 | ui_browser__gotorc(browser, row, column); |
629 | SLsmg_write_char(SLSMG_LLCORN_CHAR); | 632 | SLsmg_write_char(SLSMG_LLCORN_CHAR); |
@@ -633,7 +636,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser, | |||
633 | if (row-- == 0) | 636 | if (row-- == 0) |
634 | goto out; | 637 | goto out; |
635 | } else | 638 | } else |
636 | row = browser->height - 1; | 639 | row = browser->rows - 1; |
637 | 640 | ||
638 | if (end > browser->top_idx) | 641 | if (end > browser->top_idx) |
639 | end_row = end - browser->top_idx; | 642 | end_row = end - browser->top_idx; |
@@ -675,8 +678,8 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser, | |||
675 | } else | 678 | } else |
676 | row = 0; | 679 | row = 0; |
677 | 680 | ||
678 | if (end >= browser->top_idx + browser->height) | 681 | if (end >= browser->top_idx + browser->rows) |
679 | end_row = browser->height - 1; | 682 | end_row = browser->rows - 1; |
680 | else | 683 | else |
681 | end_row = end - browser->top_idx; | 684 | end_row = end - browser->top_idx; |
682 | 685 | ||
@@ -684,7 +687,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser, | |||
684 | SLsmg_draw_vline(end_row - row + 1); | 687 | SLsmg_draw_vline(end_row - row + 1); |
685 | 688 | ||
686 | ui_browser__gotorc(browser, end_row, column); | 689 | ui_browser__gotorc(browser, end_row, column); |
687 | if (end < browser->top_idx + browser->height) { | 690 | if (end < browser->top_idx + browser->rows) { |
688 | SLsmg_write_char(SLSMG_LLCORN_CHAR); | 691 | SLsmg_write_char(SLSMG_LLCORN_CHAR); |
689 | ui_browser__gotorc(browser, end_row, column + 1); | 692 | ui_browser__gotorc(browser, end_row, column + 1); |
690 | SLsmg_write_char(SLSMG_HLINE_CHAR); | 693 | SLsmg_write_char(SLSMG_HLINE_CHAR); |
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index 03d4d6295f10..92ae72113965 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h | |||
@@ -14,11 +14,12 @@ | |||
14 | struct ui_browser { | 14 | struct ui_browser { |
15 | u64 index, top_idx; | 15 | u64 index, top_idx; |
16 | void *top, *entries; | 16 | void *top, *entries; |
17 | u16 y, x, width, height; | 17 | u16 y, x, width, height, rows; |
18 | int current_color; | 18 | int current_color; |
19 | void *priv; | 19 | void *priv; |
20 | const char *title; | 20 | const char *title; |
21 | char *helpline; | 21 | char *helpline; |
22 | void (*refresh_dimensions)(struct ui_browser *browser); | ||
22 | unsigned int (*refresh)(struct ui_browser *browser); | 23 | unsigned int (*refresh)(struct ui_browser *browser); |
23 | void (*write)(struct ui_browser *browser, void *entry, int row); | 24 | void (*write)(struct ui_browser *browser, void *entry, int row); |
24 | void (*seek)(struct ui_browser *browser, off_t offset, int whence); | 25 | void (*seek)(struct ui_browser *browser, off_t offset, int whence); |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 04a229aa5c0f..a94b11fc5e00 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -26,6 +26,7 @@ struct hist_browser { | |||
26 | struct map_symbol *selection; | 26 | struct map_symbol *selection; |
27 | int print_seq; | 27 | int print_seq; |
28 | bool show_dso; | 28 | bool show_dso; |
29 | bool show_headers; | ||
29 | float min_pcnt; | 30 | float min_pcnt; |
30 | u64 nr_non_filtered_entries; | 31 | u64 nr_non_filtered_entries; |
31 | u64 nr_callchain_rows; | 32 | u64 nr_callchain_rows; |
@@ -33,8 +34,7 @@ struct hist_browser { | |||
33 | 34 | ||
34 | extern void hist_browser__init_hpp(void); | 35 | extern void hist_browser__init_hpp(void); |
35 | 36 | ||
36 | static int hists__browser_title(struct hists *hists, char *bf, size_t size, | 37 | static int hists__browser_title(struct hists *hists, char *bf, size_t size); |
37 | const char *ev_name); | ||
38 | static void hist_browser__update_nr_entries(struct hist_browser *hb); | 38 | static void hist_browser__update_nr_entries(struct hist_browser *hb); |
39 | 39 | ||
40 | static struct rb_node *hists__filter_entries(struct rb_node *nd, | 40 | static struct rb_node *hists__filter_entries(struct rb_node *nd, |
@@ -57,11 +57,42 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb) | |||
57 | return nr_entries + hb->nr_callchain_rows; | 57 | return nr_entries + hb->nr_callchain_rows; |
58 | } | 58 | } |
59 | 59 | ||
60 | static void hist_browser__refresh_dimensions(struct hist_browser *browser) | 60 | static void hist_browser__update_rows(struct hist_browser *hb) |
61 | { | 61 | { |
62 | struct ui_browser *browser = &hb->b; | ||
63 | u16 header_offset = hb->show_headers ? 1 : 0, index_row; | ||
64 | |||
65 | browser->rows = browser->height - header_offset; | ||
66 | /* | ||
67 | * Verify if we were at the last line and that line isn't | ||
68 | * visibe because we now show the header line(s). | ||
69 | */ | ||
70 | index_row = browser->index - browser->top_idx; | ||
71 | if (index_row >= browser->rows) | ||
72 | browser->index -= index_row - browser->rows + 1; | ||
73 | } | ||
74 | |||
75 | static void hist_browser__refresh_dimensions(struct ui_browser *browser) | ||
76 | { | ||
77 | struct hist_browser *hb = container_of(browser, struct hist_browser, b); | ||
78 | |||
62 | /* 3 == +/- toggle symbol before actual hist_entry rendering */ | 79 | /* 3 == +/- toggle symbol before actual hist_entry rendering */ |
63 | browser->b.width = 3 + (hists__sort_list_width(browser->hists) + | 80 | browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]")); |
64 | sizeof("[k]")); | 81 | /* |
82 | * FIXME: Just keeping existing behaviour, but this really should be | ||
83 | * before updating browser->width, as it will invalidate the | ||
84 | * calculation above. Fix this and the fallout in another | ||
85 | * changeset. | ||
86 | */ | ||
87 | ui_browser__refresh_dimensions(browser); | ||
88 | hist_browser__update_rows(hb); | ||
89 | } | ||
90 | |||
91 | static void hist_browser__gotorc(struct hist_browser *browser, int row, int column) | ||
92 | { | ||
93 | u16 header_offset = browser->show_headers ? 1 : 0; | ||
94 | |||
95 | ui_browser__gotorc(&browser->b, row + header_offset, column); | ||
65 | } | 96 | } |
66 | 97 | ||
67 | static void hist_browser__reset(struct hist_browser *browser) | 98 | static void hist_browser__reset(struct hist_browser *browser) |
@@ -74,7 +105,7 @@ static void hist_browser__reset(struct hist_browser *browser) | |||
74 | 105 | ||
75 | hist_browser__update_nr_entries(browser); | 106 | hist_browser__update_nr_entries(browser); |
76 | browser->b.nr_entries = hist_browser__nr_entries(browser); | 107 | browser->b.nr_entries = hist_browser__nr_entries(browser); |
77 | hist_browser__refresh_dimensions(browser); | 108 | hist_browser__refresh_dimensions(&browser->b); |
78 | ui_browser__reset_index(&browser->b); | 109 | ui_browser__reset_index(&browser->b); |
79 | } | 110 | } |
80 | 111 | ||
@@ -346,7 +377,7 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser) | |||
346 | "Or reduce the sampling frequency."); | 377 | "Or reduce the sampling frequency."); |
347 | } | 378 | } |
348 | 379 | ||
349 | static int hist_browser__run(struct hist_browser *browser, const char *ev_name, | 380 | static int hist_browser__run(struct hist_browser *browser, |
350 | struct hist_browser_timer *hbt) | 381 | struct hist_browser_timer *hbt) |
351 | { | 382 | { |
352 | int key; | 383 | int key; |
@@ -356,8 +387,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, | |||
356 | browser->b.entries = &browser->hists->entries; | 387 | browser->b.entries = &browser->hists->entries; |
357 | browser->b.nr_entries = hist_browser__nr_entries(browser); | 388 | browser->b.nr_entries = hist_browser__nr_entries(browser); |
358 | 389 | ||
359 | hist_browser__refresh_dimensions(browser); | 390 | hists__browser_title(browser->hists, title, sizeof(title)); |
360 | hists__browser_title(browser->hists, title, sizeof(title), ev_name); | ||
361 | 391 | ||
362 | if (ui_browser__show(&browser->b, title, | 392 | if (ui_browser__show(&browser->b, title, |
363 | "Press '?' for help on key bindings") < 0) | 393 | "Press '?' for help on key bindings") < 0) |
@@ -384,7 +414,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, | |||
384 | ui_browser__warn_lost_events(&browser->b); | 414 | ui_browser__warn_lost_events(&browser->b); |
385 | } | 415 | } |
386 | 416 | ||
387 | hists__browser_title(browser->hists, title, sizeof(title), ev_name); | 417 | hists__browser_title(browser->hists, title, sizeof(title)); |
388 | ui_browser__show_title(&browser->b, title); | 418 | ui_browser__show_title(&browser->b, title); |
389 | continue; | 419 | continue; |
390 | } | 420 | } |
@@ -393,10 +423,10 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, | |||
393 | struct hist_entry *h = rb_entry(browser->b.top, | 423 | struct hist_entry *h = rb_entry(browser->b.top, |
394 | struct hist_entry, rb_node); | 424 | struct hist_entry, rb_node); |
395 | ui_helpline__pop(); | 425 | ui_helpline__pop(); |
396 | ui_helpline__fpush("%d: nr_ent=(%d,%d), height=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", | 426 | ui_helpline__fpush("%d: nr_ent=(%d,%d), rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", |
397 | seq++, browser->b.nr_entries, | 427 | seq++, browser->b.nr_entries, |
398 | browser->hists->nr_entries, | 428 | browser->hists->nr_entries, |
399 | browser->b.height, | 429 | browser->b.rows, |
400 | browser->b.index, | 430 | browser->b.index, |
401 | browser->b.top_idx, | 431 | browser->b.top_idx, |
402 | h->row_offset, h->nr_rows); | 432 | h->row_offset, h->nr_rows); |
@@ -410,6 +440,10 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, | |||
410 | /* Expand the whole world. */ | 440 | /* Expand the whole world. */ |
411 | hist_browser__set_folding(browser, true); | 441 | hist_browser__set_folding(browser, true); |
412 | break; | 442 | break; |
443 | case 'H': | ||
444 | browser->show_headers = !browser->show_headers; | ||
445 | hist_browser__update_rows(browser); | ||
446 | break; | ||
413 | case K_ENTER: | 447 | case K_ENTER: |
414 | if (hist_browser__toggle_fold(browser)) | 448 | if (hist_browser__toggle_fold(browser)) |
415 | break; | 449 | break; |
@@ -509,13 +543,13 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse | |||
509 | } | 543 | } |
510 | 544 | ||
511 | ui_browser__set_color(&browser->b, color); | 545 | ui_browser__set_color(&browser->b, color); |
512 | ui_browser__gotorc(&browser->b, row, 0); | 546 | hist_browser__gotorc(browser, row, 0); |
513 | slsmg_write_nstring(" ", offset + extra_offset); | 547 | slsmg_write_nstring(" ", offset + extra_offset); |
514 | slsmg_printf("%c ", folded_sign); | 548 | slsmg_printf("%c ", folded_sign); |
515 | slsmg_write_nstring(str, width); | 549 | slsmg_write_nstring(str, width); |
516 | free(alloc_str); | 550 | free(alloc_str); |
517 | 551 | ||
518 | if (++row == browser->b.height) | 552 | if (++row == browser->b.rows) |
519 | goto out; | 553 | goto out; |
520 | do_next: | 554 | do_next: |
521 | if (folded_sign == '+') | 555 | if (folded_sign == '+') |
@@ -528,7 +562,7 @@ do_next: | |||
528 | new_level, row, row_offset, | 562 | new_level, row, row_offset, |
529 | is_current_entry); | 563 | is_current_entry); |
530 | } | 564 | } |
531 | if (row == browser->b.height) | 565 | if (row == browser->b.rows) |
532 | goto out; | 566 | goto out; |
533 | node = next; | 567 | node = next; |
534 | } | 568 | } |
@@ -568,13 +602,13 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser, | |||
568 | 602 | ||
569 | s = callchain_list__sym_name(chain, bf, sizeof(bf), | 603 | s = callchain_list__sym_name(chain, bf, sizeof(bf), |
570 | browser->show_dso); | 604 | browser->show_dso); |
571 | ui_browser__gotorc(&browser->b, row, 0); | 605 | hist_browser__gotorc(browser, row, 0); |
572 | ui_browser__set_color(&browser->b, color); | 606 | ui_browser__set_color(&browser->b, color); |
573 | slsmg_write_nstring(" ", offset); | 607 | slsmg_write_nstring(" ", offset); |
574 | slsmg_printf("%c ", folded_sign); | 608 | slsmg_printf("%c ", folded_sign); |
575 | slsmg_write_nstring(s, width - 2); | 609 | slsmg_write_nstring(s, width - 2); |
576 | 610 | ||
577 | if (++row == browser->b.height) | 611 | if (++row == browser->b.rows) |
578 | goto out; | 612 | goto out; |
579 | } | 613 | } |
580 | 614 | ||
@@ -603,7 +637,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser, | |||
603 | row += hist_browser__show_callchain_node(browser, node, level, | 637 | row += hist_browser__show_callchain_node(browser, node, level, |
604 | row, row_offset, | 638 | row, row_offset, |
605 | is_current_entry); | 639 | is_current_entry); |
606 | if (row == browser->b.height) | 640 | if (row == browser->b.rows) |
607 | break; | 641 | break; |
608 | } | 642 | } |
609 | 643 | ||
@@ -733,7 +767,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
733 | .ptr = &arg, | 767 | .ptr = &arg, |
734 | }; | 768 | }; |
735 | 769 | ||
736 | ui_browser__gotorc(&browser->b, row, 0); | 770 | hist_browser__gotorc(browser, row, 0); |
737 | 771 | ||
738 | perf_hpp__for_each_format(fmt) { | 772 | perf_hpp__for_each_format(fmt) { |
739 | if (perf_hpp__should_skip(fmt)) | 773 | if (perf_hpp__should_skip(fmt)) |
@@ -777,7 +811,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
777 | } else | 811 | } else |
778 | --row_offset; | 812 | --row_offset; |
779 | 813 | ||
780 | if (folded_sign == '-' && row != browser->b.height) { | 814 | if (folded_sign == '-' && row != browser->b.rows) { |
781 | printed += hist_browser__show_callchain(browser, &entry->sorted_chain, | 815 | printed += hist_browser__show_callchain(browser, &entry->sorted_chain, |
782 | 1, row, &row_offset, | 816 | 1, row, &row_offset, |
783 | ¤t_entry); | 817 | ¤t_entry); |
@@ -788,6 +822,56 @@ static int hist_browser__show_entry(struct hist_browser *browser, | |||
788 | return printed; | 822 | return printed; |
789 | } | 823 | } |
790 | 824 | ||
825 | static int advance_hpp_check(struct perf_hpp *hpp, int inc) | ||
826 | { | ||
827 | advance_hpp(hpp, inc); | ||
828 | return hpp->size <= 0; | ||
829 | } | ||
830 | |||
831 | static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists) | ||
832 | { | ||
833 | struct perf_hpp dummy_hpp = { | ||
834 | .buf = buf, | ||
835 | .size = size, | ||
836 | }; | ||
837 | struct perf_hpp_fmt *fmt; | ||
838 | size_t ret = 0; | ||
839 | |||
840 | if (symbol_conf.use_callchain) { | ||
841 | ret = scnprintf(buf, size, " "); | ||
842 | if (advance_hpp_check(&dummy_hpp, ret)) | ||
843 | return ret; | ||
844 | } | ||
845 | |||
846 | perf_hpp__for_each_format(fmt) { | ||
847 | if (perf_hpp__should_skip(fmt)) | ||
848 | continue; | ||
849 | |||
850 | /* We need to add the length of the columns header. */ | ||
851 | perf_hpp__reset_width(fmt, hists); | ||
852 | |||
853 | ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); | ||
854 | if (advance_hpp_check(&dummy_hpp, ret)) | ||
855 | break; | ||
856 | |||
857 | ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, " "); | ||
858 | if (advance_hpp_check(&dummy_hpp, ret)) | ||
859 | break; | ||
860 | } | ||
861 | |||
862 | return ret; | ||
863 | } | ||
864 | |||
865 | static void hist_browser__show_headers(struct hist_browser *browser) | ||
866 | { | ||
867 | char headers[1024]; | ||
868 | |||
869 | hists__scnprintf_headers(headers, sizeof(headers), browser->hists); | ||
870 | ui_browser__gotorc(&browser->b, 0, 0); | ||
871 | ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); | ||
872 | slsmg_write_nstring(headers, browser->b.width + 1); | ||
873 | } | ||
874 | |||
791 | static void ui_browser__hists_init_top(struct ui_browser *browser) | 875 | static void ui_browser__hists_init_top(struct ui_browser *browser) |
792 | { | 876 | { |
793 | if (browser->top == NULL) { | 877 | if (browser->top == NULL) { |
@@ -801,9 +885,15 @@ static void ui_browser__hists_init_top(struct ui_browser *browser) | |||
801 | static unsigned int hist_browser__refresh(struct ui_browser *browser) | 885 | static unsigned int hist_browser__refresh(struct ui_browser *browser) |
802 | { | 886 | { |
803 | unsigned row = 0; | 887 | unsigned row = 0; |
888 | u16 header_offset = 0; | ||
804 | struct rb_node *nd; | 889 | struct rb_node *nd; |
805 | struct hist_browser *hb = container_of(browser, struct hist_browser, b); | 890 | struct hist_browser *hb = container_of(browser, struct hist_browser, b); |
806 | 891 | ||
892 | if (hb->show_headers) { | ||
893 | hist_browser__show_headers(hb); | ||
894 | header_offset = 1; | ||
895 | } | ||
896 | |||
807 | ui_browser__hists_init_top(browser); | 897 | ui_browser__hists_init_top(browser); |
808 | 898 | ||
809 | for (nd = browser->top; nd; nd = rb_next(nd)) { | 899 | for (nd = browser->top; nd; nd = rb_next(nd)) { |
@@ -818,11 +908,11 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) | |||
818 | continue; | 908 | continue; |
819 | 909 | ||
820 | row += hist_browser__show_entry(hb, h, row); | 910 | row += hist_browser__show_entry(hb, h, row); |
821 | if (row == browser->height) | 911 | if (row == browser->rows) |
822 | break; | 912 | break; |
823 | } | 913 | } |
824 | 914 | ||
825 | return row; | 915 | return row + header_offset; |
826 | } | 916 | } |
827 | 917 | ||
828 | static struct rb_node *hists__filter_entries(struct rb_node *nd, | 918 | static struct rb_node *hists__filter_entries(struct rb_node *nd, |
@@ -1191,8 +1281,10 @@ static struct hist_browser *hist_browser__new(struct hists *hists) | |||
1191 | if (browser) { | 1281 | if (browser) { |
1192 | browser->hists = hists; | 1282 | browser->hists = hists; |
1193 | browser->b.refresh = hist_browser__refresh; | 1283 | browser->b.refresh = hist_browser__refresh; |
1284 | browser->b.refresh_dimensions = hist_browser__refresh_dimensions; | ||
1194 | browser->b.seek = ui_browser__hists_seek; | 1285 | browser->b.seek = ui_browser__hists_seek; |
1195 | browser->b.use_navkeypressed = true; | 1286 | browser->b.use_navkeypressed = true; |
1287 | browser->show_headers = symbol_conf.show_hist_headers; | ||
1196 | } | 1288 | } |
1197 | 1289 | ||
1198 | return browser; | 1290 | return browser; |
@@ -1213,8 +1305,7 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser | |||
1213 | return browser->he_selection->thread; | 1305 | return browser->he_selection->thread; |
1214 | } | 1306 | } |
1215 | 1307 | ||
1216 | static int hists__browser_title(struct hists *hists, char *bf, size_t size, | 1308 | static int hists__browser_title(struct hists *hists, char *bf, size_t size) |
1217 | const char *ev_name) | ||
1218 | { | 1309 | { |
1219 | char unit; | 1310 | char unit; |
1220 | int printed; | 1311 | int printed; |
@@ -1223,6 +1314,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size, | |||
1223 | unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; | 1314 | unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
1224 | u64 nr_events = hists->stats.total_period; | 1315 | u64 nr_events = hists->stats.total_period; |
1225 | struct perf_evsel *evsel = hists_to_evsel(hists); | 1316 | struct perf_evsel *evsel = hists_to_evsel(hists); |
1317 | const char *ev_name = perf_evsel__name(evsel); | ||
1226 | char buf[512]; | 1318 | char buf[512]; |
1227 | size_t buflen = sizeof(buf); | 1319 | size_t buflen = sizeof(buf); |
1228 | 1320 | ||
@@ -1390,7 +1482,7 @@ static void hist_browser__update_nr_entries(struct hist_browser *hb) | |||
1390 | } | 1482 | } |
1391 | 1483 | ||
1392 | static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | 1484 | static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, |
1393 | const char *helpline, const char *ev_name, | 1485 | const char *helpline, |
1394 | bool left_exits, | 1486 | bool left_exits, |
1395 | struct hist_browser_timer *hbt, | 1487 | struct hist_browser_timer *hbt, |
1396 | float min_pcnt, | 1488 | float min_pcnt, |
@@ -1422,6 +1514,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
1422 | "d Zoom into current DSO\n" \ | 1514 | "d Zoom into current DSO\n" \ |
1423 | "E Expand all callchains\n" \ | 1515 | "E Expand all callchains\n" \ |
1424 | "F Toggle percentage of filtered entries\n" \ | 1516 | "F Toggle percentage of filtered entries\n" \ |
1517 | "H Display column headers\n" \ | ||
1425 | 1518 | ||
1426 | /* help messages are sorted by lexical order of the hotkey */ | 1519 | /* help messages are sorted by lexical order of the hotkey */ |
1427 | const char report_help[] = HIST_BROWSER_HELP_COMMON | 1520 | const char report_help[] = HIST_BROWSER_HELP_COMMON |
@@ -1465,7 +1558,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
1465 | 1558 | ||
1466 | nr_options = 0; | 1559 | nr_options = 0; |
1467 | 1560 | ||
1468 | key = hist_browser__run(browser, ev_name, hbt); | 1561 | key = hist_browser__run(browser, hbt); |
1469 | 1562 | ||
1470 | if (browser->he_selection != NULL) { | 1563 | if (browser->he_selection != NULL) { |
1471 | thread = hist_browser__selected_thread(browser); | 1564 | thread = hist_browser__selected_thread(browser); |
@@ -1843,7 +1936,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, | |||
1843 | { | 1936 | { |
1844 | struct perf_evlist *evlist = menu->b.priv; | 1937 | struct perf_evlist *evlist = menu->b.priv; |
1845 | struct perf_evsel *pos; | 1938 | struct perf_evsel *pos; |
1846 | const char *ev_name, *title = "Available samples"; | 1939 | const char *title = "Available samples"; |
1847 | int delay_secs = hbt ? hbt->refresh : 0; | 1940 | int delay_secs = hbt ? hbt->refresh : 0; |
1848 | int key; | 1941 | int key; |
1849 | 1942 | ||
@@ -1876,9 +1969,8 @@ browse_hists: | |||
1876 | */ | 1969 | */ |
1877 | if (hbt) | 1970 | if (hbt) |
1878 | hbt->timer(hbt->arg); | 1971 | hbt->timer(hbt->arg); |
1879 | ev_name = perf_evsel__name(pos); | ||
1880 | key = perf_evsel__hists_browse(pos, nr_events, help, | 1972 | key = perf_evsel__hists_browse(pos, nr_events, help, |
1881 | ev_name, true, hbt, | 1973 | true, hbt, |
1882 | menu->min_pcnt, | 1974 | menu->min_pcnt, |
1883 | menu->env); | 1975 | menu->env); |
1884 | ui_browser__show_title(&menu->b, title); | 1976 | ui_browser__show_title(&menu->b, title); |
@@ -1982,10 +2074,9 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, | |||
1982 | single_entry: | 2074 | single_entry: |
1983 | if (nr_entries == 1) { | 2075 | if (nr_entries == 1) { |
1984 | struct perf_evsel *first = perf_evlist__first(evlist); | 2076 | struct perf_evsel *first = perf_evlist__first(evlist); |
1985 | const char *ev_name = perf_evsel__name(first); | ||
1986 | 2077 | ||
1987 | return perf_evsel__hists_browse(first, nr_entries, help, | 2078 | return perf_evsel__hists_browse(first, nr_entries, help, |
1988 | ev_name, false, hbt, min_pcnt, | 2079 | false, hbt, min_pcnt, |
1989 | env); | 2080 | env); |
1990 | } | 2081 | } |
1991 | 2082 | ||
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 90122abd3721..40af0acb4fe9 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -479,7 +479,7 @@ print_entries: | |||
479 | 479 | ||
480 | if (h->ms.map == NULL && verbose > 1) { | 480 | if (h->ms.map == NULL && verbose > 1) { |
481 | __map_groups__fprintf_maps(h->thread->mg, | 481 | __map_groups__fprintf_maps(h->thread->mg, |
482 | MAP__FUNCTION, verbose, fp); | 482 | MAP__FUNCTION, fp); |
483 | fprintf(fp, "%.10s end\n", graph_dotted_line); | 483 | fprintf(fp, "%.10s end\n", graph_dotted_line); |
484 | } | 484 | } |
485 | } | 485 | } |