diff options
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 76 |
1 files changed, 39 insertions, 37 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 67bdb9f14ad6..e06c4f869330 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -70,10 +70,11 @@ | |||
70 | 70 | ||
71 | static volatile int done; | 71 | static volatile int done; |
72 | 72 | ||
73 | #define HEADER_LINE_NR 5 | ||
74 | |||
73 | static void perf_top__update_print_entries(struct perf_top *top) | 75 | static void perf_top__update_print_entries(struct perf_top *top) |
74 | { | 76 | { |
75 | if (top->print_entries > 9) | 77 | top->print_entries = top->winsize.ws_row - HEADER_LINE_NR; |
76 | top->print_entries -= 9; | ||
77 | } | 78 | } |
78 | 79 | ||
79 | static void perf_top__sig_winch(int sig __maybe_unused, | 80 | static void perf_top__sig_winch(int sig __maybe_unused, |
@@ -82,13 +83,6 @@ static void perf_top__sig_winch(int sig __maybe_unused, | |||
82 | struct perf_top *top = arg; | 83 | struct perf_top *top = arg; |
83 | 84 | ||
84 | get_term_dimensions(&top->winsize); | 85 | get_term_dimensions(&top->winsize); |
85 | if (!top->print_entries | ||
86 | || (top->print_entries+4) > top->winsize.ws_row) { | ||
87 | top->print_entries = top->winsize.ws_row; | ||
88 | } else { | ||
89 | top->print_entries += 4; | ||
90 | top->winsize.ws_row = top->print_entries; | ||
91 | } | ||
92 | perf_top__update_print_entries(top); | 86 | perf_top__update_print_entries(top); |
93 | } | 87 | } |
94 | 88 | ||
@@ -251,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
251 | { | 245 | { |
252 | struct hist_entry *he; | 246 | struct hist_entry *he; |
253 | 247 | ||
248 | pthread_mutex_lock(&evsel->hists.lock); | ||
254 | he = __hists__add_entry(&evsel->hists, al, NULL, sample->period, | 249 | he = __hists__add_entry(&evsel->hists, al, NULL, sample->period, |
255 | sample->weight); | 250 | sample->weight); |
251 | pthread_mutex_unlock(&evsel->hists.lock); | ||
252 | |||
256 | if (he == NULL) | 253 | if (he == NULL) |
257 | return NULL; | 254 | return NULL; |
258 | 255 | ||
@@ -290,16 +287,17 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
290 | return; | 287 | return; |
291 | } | 288 | } |
292 | 289 | ||
293 | hists__collapse_resort_threaded(&top->sym_evsel->hists); | 290 | hists__collapse_resort(&top->sym_evsel->hists); |
294 | hists__output_resort_threaded(&top->sym_evsel->hists); | 291 | hists__output_resort(&top->sym_evsel->hists); |
295 | hists__decay_entries_threaded(&top->sym_evsel->hists, | 292 | hists__decay_entries(&top->sym_evsel->hists, |
296 | top->hide_user_symbols, | 293 | top->hide_user_symbols, |
297 | top->hide_kernel_symbols); | 294 | top->hide_kernel_symbols); |
298 | hists__output_recalc_col_len(&top->sym_evsel->hists, | 295 | hists__output_recalc_col_len(&top->sym_evsel->hists, |
299 | top->winsize.ws_row - 3); | 296 | top->print_entries - printed); |
300 | putchar('\n'); | 297 | putchar('\n'); |
301 | hists__fprintf(&top->sym_evsel->hists, false, | 298 | hists__fprintf(&top->sym_evsel->hists, false, |
302 | top->winsize.ws_row - 4 - printed, win_width, stdout); | 299 | top->print_entries - printed, win_width, |
300 | top->min_percent, stdout); | ||
303 | } | 301 | } |
304 | 302 | ||
305 | static void prompt_integer(int *target, const char *msg) | 303 | static void prompt_integer(int *target, const char *msg) |
@@ -477,7 +475,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) | |||
477 | perf_top__sig_winch(SIGWINCH, NULL, top); | 475 | perf_top__sig_winch(SIGWINCH, NULL, top); |
478 | sigaction(SIGWINCH, &act, NULL); | 476 | sigaction(SIGWINCH, &act, NULL); |
479 | } else { | 477 | } else { |
480 | perf_top__sig_winch(SIGWINCH, NULL, top); | ||
481 | signal(SIGWINCH, SIG_DFL); | 478 | signal(SIGWINCH, SIG_DFL); |
482 | } | 479 | } |
483 | break; | 480 | break; |
@@ -556,11 +553,11 @@ static void perf_top__sort_new_samples(void *arg) | |||
556 | if (t->evlist->selected != NULL) | 553 | if (t->evlist->selected != NULL) |
557 | t->sym_evsel = t->evlist->selected; | 554 | t->sym_evsel = t->evlist->selected; |
558 | 555 | ||
559 | hists__collapse_resort_threaded(&t->sym_evsel->hists); | 556 | hists__collapse_resort(&t->sym_evsel->hists); |
560 | hists__output_resort_threaded(&t->sym_evsel->hists); | 557 | hists__output_resort(&t->sym_evsel->hists); |
561 | hists__decay_entries_threaded(&t->sym_evsel->hists, | 558 | hists__decay_entries(&t->sym_evsel->hists, |
562 | t->hide_user_symbols, | 559 | t->hide_user_symbols, |
563 | t->hide_kernel_symbols); | 560 | t->hide_kernel_symbols); |
564 | } | 561 | } |
565 | 562 | ||
566 | static void *display_thread_tui(void *arg) | 563 | static void *display_thread_tui(void *arg) |
@@ -584,7 +581,7 @@ static void *display_thread_tui(void *arg) | |||
584 | list_for_each_entry(pos, &top->evlist->entries, node) | 581 | list_for_each_entry(pos, &top->evlist->entries, node) |
585 | pos->hists.uid_filter_str = top->record_opts.target.uid_str; | 582 | pos->hists.uid_filter_str = top->record_opts.target.uid_str; |
586 | 583 | ||
587 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, | 584 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent, |
588 | &top->session->header.env); | 585 | &top->session->header.env); |
589 | 586 | ||
590 | done = 1; | 587 | done = 1; |
@@ -794,7 +791,7 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
794 | return; | 791 | return; |
795 | } | 792 | } |
796 | 793 | ||
797 | if (top->sort_has_symbols) | 794 | if (sort__has_sym) |
798 | perf_top__record_precise_ip(top, he, evsel->idx, ip); | 795 | perf_top__record_precise_ip(top, he, evsel->idx, ip); |
799 | } | 796 | } |
800 | 797 | ||
@@ -912,9 +909,9 @@ out_err: | |||
912 | return -1; | 909 | return -1; |
913 | } | 910 | } |
914 | 911 | ||
915 | static int perf_top__setup_sample_type(struct perf_top *top) | 912 | static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused) |
916 | { | 913 | { |
917 | if (!top->sort_has_symbols) { | 914 | if (!sort__has_sym) { |
918 | if (symbol_conf.use_callchain) { | 915 | if (symbol_conf.use_callchain) { |
919 | ui__error("Selected -g but \"sym\" not present in --sort/-s."); | 916 | ui__error("Selected -g but \"sym\" not present in --sort/-s."); |
920 | return -EINVAL; | 917 | return -EINVAL; |
@@ -1025,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) | |||
1025 | return record_parse_callchain_opt(opt, arg, unset); | 1022 | return record_parse_callchain_opt(opt, arg, unset); |
1026 | } | 1023 | } |
1027 | 1024 | ||
1025 | static int | ||
1026 | parse_percent_limit(const struct option *opt, const char *arg, | ||
1027 | int unset __maybe_unused) | ||
1028 | { | ||
1029 | struct perf_top *top = opt->value; | ||
1030 | |||
1031 | top->min_percent = strtof(arg, NULL); | ||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1028 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | 1035 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) |
1029 | { | 1036 | { |
1030 | int status; | 1037 | int status; |
@@ -1110,6 +1117,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1110 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", | 1117 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", |
1111 | "Specify disassembler style (e.g. -M intel for intel syntax)"), | 1118 | "Specify disassembler style (e.g. -M intel for intel syntax)"), |
1112 | OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), | 1119 | OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), |
1120 | OPT_CALLBACK(0, "percent-limit", &top, "percent", | ||
1121 | "Don't show entries under that percent", parse_percent_limit), | ||
1113 | OPT_END() | 1122 | OPT_END() |
1114 | }; | 1123 | }; |
1115 | const char * const top_usage[] = { | 1124 | const char * const top_usage[] = { |
@@ -1121,8 +1130,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1121 | if (top.evlist == NULL) | 1130 | if (top.evlist == NULL) |
1122 | return -ENOMEM; | 1131 | return -ENOMEM; |
1123 | 1132 | ||
1124 | symbol_conf.exclude_other = false; | ||
1125 | |||
1126 | argc = parse_options(argc, argv, options, top_usage, 0); | 1133 | argc = parse_options(argc, argv, options, top_usage, 0); |
1127 | if (argc) | 1134 | if (argc) |
1128 | usage_with_options(top_usage, options); | 1135 | usage_with_options(top_usage, options); |
@@ -1133,6 +1140,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1133 | if (setup_sorting() < 0) | 1140 | if (setup_sorting() < 0) |
1134 | usage_with_options(top_usage, options); | 1141 | usage_with_options(top_usage, options); |
1135 | 1142 | ||
1143 | /* display thread wants entries to be collapsed in a different tree */ | ||
1144 | sort__need_collapse = 1; | ||
1145 | |||
1136 | if (top.use_stdio) | 1146 | if (top.use_stdio) |
1137 | use_browser = 0; | 1147 | use_browser = 0; |
1138 | else if (top.use_tui) | 1148 | else if (top.use_tui) |
@@ -1200,15 +1210,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1200 | if (symbol__init() < 0) | 1210 | if (symbol__init() < 0) |
1201 | return -1; | 1211 | return -1; |
1202 | 1212 | ||
1203 | sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout); | 1213 | sort__setup_elide(stdout); |
1204 | sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); | ||
1205 | sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout); | ||
1206 | |||
1207 | /* | ||
1208 | * Avoid annotation data structures overhead when symbols aren't on the | ||
1209 | * sort list. | ||
1210 | */ | ||
1211 | top.sort_has_symbols = sort_sym.list.next != NULL; | ||
1212 | 1214 | ||
1213 | get_term_dimensions(&top.winsize); | 1215 | get_term_dimensions(&top.winsize); |
1214 | if (top.print_entries == 0) { | 1216 | if (top.print_entries == 0) { |