aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c76
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
71static volatile int done; 71static volatile int done;
72 72
73#define HEADER_LINE_NR 5
74
73static void perf_top__update_print_entries(struct perf_top *top) 75static 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
79static void perf_top__sig_winch(int sig __maybe_unused, 80static 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
305static void prompt_integer(int *target, const char *msg) 303static 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
566static void *display_thread_tui(void *arg) 563static 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
915static int perf_top__setup_sample_type(struct perf_top *top) 912static 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
1025static int
1026parse_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
1028int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) 1035int 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) {