aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-top.c92
1 files changed, 67 insertions, 25 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 89b7f68a1799..a368978d5177 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -78,6 +78,14 @@ static int dump_symtab = 0;
78 78
79static bool hide_kernel_symbols = false; 79static bool hide_kernel_symbols = false;
80static bool hide_user_symbols = false; 80static bool hide_user_symbols = false;
81static struct winsize winsize;
82static const char *graph_line =
83 "_____________________________________________________________________"
84 "_____________________________________________________________________";
85static const char *graph_dotted_line =
86 "---------------------------------------------------------------------"
87 "---------------------------------------------------------------------"
88 "---------------------------------------------------------------------";
81 89
82/* 90/*
83 * Source 91 * Source
@@ -107,6 +115,7 @@ struct sym_entry {
107 unsigned long snap_count; 115 unsigned long snap_count;
108 double weight; 116 double weight;
109 int skip; 117 int skip;
118 u16 name_len;
110 u8 origin; 119 u8 origin;
111 struct map *map; 120 struct map *map;
112 struct source_line *source; 121 struct source_line *source;
@@ -119,34 +128,40 @@ struct sym_entry {
119 * Source functions 128 * Source functions
120 */ 129 */
121 130
122/* most GUI terminals set LINES (although some don't export it) */ 131static void get_term_dimensions(struct winsize *ws)
123static int term_rows(void)
124{ 132{
125 char *lines_string = getenv("LINES"); 133 char *s = getenv("LINES");
126 int n_lines; 134
127 135 if (s != NULL) {
128 if (lines_string && (n_lines = atoi(lines_string)) > 0) 136 ws->ws_row = atoi(s);
129 return n_lines; 137 s = getenv("COLUMNS");
130#ifdef TIOCGWINSZ 138 if (s != NULL) {
131 else { 139 ws->ws_col = atoi(s);
132 struct winsize ws; 140 if (ws->ws_row && ws->ws_col)
133 if (!ioctl(1, TIOCGWINSZ, &ws) && ws.ws_row) 141 return;
134 return ws.ws_row; 142 }
135 } 143 }
144#ifdef TIOCGWINSZ
145 if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
146 ws->ws_row && ws->ws_col)
147 return;
136#endif 148#endif
137 return 25; 149 ws->ws_row = 25;
150 ws->ws_col = 80;
138} 151}
139 152
140static void update_print_entries(void) 153static void update_print_entries(struct winsize *ws)
141{ 154{
142 print_entries = term_rows(); 155 print_entries = ws->ws_row;
156
143 if (print_entries > 9) 157 if (print_entries > 9)
144 print_entries -= 9; 158 print_entries -= 9;
145} 159}
146 160
147static void sig_winch_handler(int sig __used) 161static void sig_winch_handler(int sig __used)
148{ 162{
149 update_print_entries(); 163 get_term_dimensions(&winsize);
164 update_print_entries(&winsize);
150} 165}
151 166
152static void parse_source(struct sym_entry *syme) 167static void parse_source(struct sym_entry *syme)
@@ -423,6 +438,8 @@ static void print_sym_table(void)
423 struct sym_entry *syme, *n; 438 struct sym_entry *syme, *n;
424 struct rb_root tmp = RB_ROOT; 439 struct rb_root tmp = RB_ROOT;
425 struct rb_node *nd; 440 struct rb_node *nd;
441 int sym_width = 0, dso_width;
442 const int win_width = winsize.ws_col - 1;
426 443
427 samples = userspace_samples = 0; 444 samples = userspace_samples = 0;
428 445
@@ -434,6 +451,7 @@ static void print_sym_table(void)
434 list_for_each_entry_safe_from(syme, n, &active_symbols, node) { 451 list_for_each_entry_safe_from(syme, n, &active_symbols, node) {
435 syme->snap_count = syme->count[snap]; 452 syme->snap_count = syme->count[snap];
436 if (syme->snap_count != 0) { 453 if (syme->snap_count != 0) {
454
437 if ((hide_user_symbols && 455 if ((hide_user_symbols &&
438 syme->origin == PERF_RECORD_MISC_USER) || 456 syme->origin == PERF_RECORD_MISC_USER) ||
439 (hide_kernel_symbols && 457 (hide_kernel_symbols &&
@@ -453,8 +471,7 @@ static void print_sym_table(void)
453 471
454 puts(CONSOLE_CLEAR); 472 puts(CONSOLE_CLEAR);
455 473
456 printf( 474 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
457"------------------------------------------------------------------------------\n");
458 printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% [", 475 printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% [",
459 samples_per_sec, 476 samples_per_sec,
460 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec))); 477 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)));
@@ -492,26 +509,44 @@ static void print_sym_table(void)
492 printf(", %d CPUs)\n", nr_cpus); 509 printf(", %d CPUs)\n", nr_cpus);
493 } 510 }
494 511
495 printf("------------------------------------------------------------------------------\n\n"); 512 printf("%-*.*s\n\n", win_width, win_width, graph_dotted_line);
496 513
497 if (sym_filter_entry) { 514 if (sym_filter_entry) {
498 show_details(sym_filter_entry); 515 show_details(sym_filter_entry);
499 return; 516 return;
500 } 517 }
501 518
519 /*
520 * Find the longest symbol name that will be displayed
521 */
522 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
523 syme = rb_entry(nd, struct sym_entry, rb_node);
524 if (++printed > print_entries ||
525 (int)syme->snap_count < count_filter)
526 continue;
527
528 if (syme->name_len > sym_width)
529 sym_width = syme->name_len;
530 }
531
532 printed = 0;
533
502 if (nr_counters == 1) 534 if (nr_counters == 1)
503 printf(" samples pcnt"); 535 printf(" samples pcnt");
504 else 536 else
505 printf(" weight samples pcnt"); 537 printf(" weight samples pcnt");
506 538
539 dso_width = winsize.ws_col - sym_width - 29;
540
507 if (verbose) 541 if (verbose)
508 printf(" RIP "); 542 printf(" RIP ");
509 printf(" function DSO\n"); 543 printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
510 printf(" %s _______ _____", 544 printf(" %s _______ _____",
511 nr_counters == 1 ? " " : "______"); 545 nr_counters == 1 ? " " : "______");
512 if (verbose) 546 if (verbose)
513 printf(" ________________"); 547 printf(" ________________");
514 printf(" ________________________________ ________________\n\n"); 548 printf(" %-*.*s %-*.*s\n\n", sym_width, sym_width, graph_line,
549 dso_width, dso_width, graph_line);
515 550
516 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { 551 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
517 struct symbol *sym; 552 struct symbol *sym;
@@ -534,8 +569,11 @@ static void print_sym_table(void)
534 percent_color_fprintf(stdout, "%4.1f%%", pcnt); 569 percent_color_fprintf(stdout, "%4.1f%%", pcnt);
535 if (verbose) 570 if (verbose)
536 printf(" %016llx", sym->start); 571 printf(" %016llx", sym->start);
537 printf(" %-32s", sym->name); 572 printf(" %-*.*s", sym_width, sym_width, sym->name);
538 printf(" %s", syme->map->dso->short_name); 573 printf(" %-*.*s", dso_width, dso_width,
574 dso_width >= syme->map->dso->long_name_len ?
575 syme->map->dso->long_name :
576 syme->map->dso->short_name);
539 printf("\n"); 577 printf("\n");
540 } 578 }
541} 579}
@@ -718,7 +756,7 @@ static void handle_keypress(int c)
718 case 'e': 756 case 'e':
719 prompt_integer(&print_entries, "Enter display entries (lines)"); 757 prompt_integer(&print_entries, "Enter display entries (lines)");
720 if (print_entries == 0) { 758 if (print_entries == 0) {
721 update_print_entries(); 759 sig_winch_handler(SIGWINCH);
722 signal(SIGWINCH, sig_winch_handler); 760 signal(SIGWINCH, sig_winch_handler);
723 } else 761 } else
724 signal(SIGWINCH, SIG_DFL); 762 signal(SIGWINCH, SIG_DFL);
@@ -862,6 +900,9 @@ static int symbol_filter(struct map *map, struct symbol *sym)
862 } 900 }
863 } 901 }
864 902
903 if (!syme->skip)
904 syme->name_len = strlen(sym->name);
905
865 return 0; 906 return 0;
866} 907}
867 908
@@ -1301,8 +1342,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1301 if (target_pid != -1 || profile_cpu != -1) 1342 if (target_pid != -1 || profile_cpu != -1)
1302 nr_cpus = 1; 1343 nr_cpus = 1;
1303 1344
1345 get_term_dimensions(&winsize);
1304 if (print_entries == 0) { 1346 if (print_entries == 0) {
1305 update_print_entries(); 1347 update_print_entries(&winsize);
1306 signal(SIGWINCH, sig_winch_handler); 1348 signal(SIGWINCH, sig_winch_handler);
1307 } 1349 }
1308 1350