diff options
| -rw-r--r-- | tools/perf/builtin-annotate.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-diff.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 24 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 4 | ||||
| -rw-r--r-- | tools/perf/tests/hists_cumulate.c | 2 | ||||
| -rw-r--r-- | tools/perf/tests/hists_filter.c | 2 | ||||
| -rw-r--r-- | tools/perf/tests/hists_output.c | 10 | ||||
| -rw-r--r-- | tools/perf/ui/tui/setup.c | 26 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 17 | ||||
| -rw-r--r-- | tools/perf/util/hist.h | 2 |
10 files changed, 71 insertions, 20 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e7417fe97a97..747f86103599 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann) | |||
| 232 | if (nr_samples > 0) { | 232 | if (nr_samples > 0) { |
| 233 | total_nr_samples += nr_samples; | 233 | total_nr_samples += nr_samples; |
| 234 | hists__collapse_resort(hists, NULL); | 234 | hists__collapse_resort(hists, NULL); |
| 235 | hists__output_resort(hists); | 235 | hists__output_resort(hists, NULL); |
| 236 | 236 | ||
| 237 | if (symbol_conf.event_group && | 237 | if (symbol_conf.event_group && |
| 238 | !perf_evsel__is_group_leader(pos)) | 238 | !perf_evsel__is_group_leader(pos)) |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 1ce425d101a9..303c1e151dcf 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -605,7 +605,7 @@ static void hists__process(struct hists *hists) | |||
| 605 | hists__precompute(hists); | 605 | hists__precompute(hists); |
| 606 | hists__compute_resort(hists); | 606 | hists__compute_resort(hists); |
| 607 | } else { | 607 | } else { |
| 608 | hists__output_resort(hists); | 608 | hists__output_resort(hists, NULL); |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | hists__fprintf(hists, true, 0, 0, 0, stdout); | 611 | hists__fprintf(hists, true, 0, 0, 0, stdout); |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 39367609c707..072ae8ad67fc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -457,6 +457,19 @@ static void report__collapse_hists(struct report *rep) | |||
| 457 | ui_progress__finish(); | 457 | ui_progress__finish(); |
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | static void report__output_resort(struct report *rep) | ||
| 461 | { | ||
| 462 | struct ui_progress prog; | ||
| 463 | struct perf_evsel *pos; | ||
| 464 | |||
| 465 | ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); | ||
| 466 | |||
| 467 | evlist__for_each(rep->session->evlist, pos) | ||
| 468 | hists__output_resort(evsel__hists(pos), &prog); | ||
| 469 | |||
| 470 | ui_progress__finish(); | ||
| 471 | } | ||
| 472 | |||
| 460 | static int __cmd_report(struct report *rep) | 473 | static int __cmd_report(struct report *rep) |
| 461 | { | 474 | { |
| 462 | int ret; | 475 | int ret; |
| @@ -505,13 +518,20 @@ static int __cmd_report(struct report *rep) | |||
| 505 | if (session_done()) | 518 | if (session_done()) |
| 506 | return 0; | 519 | return 0; |
| 507 | 520 | ||
| 521 | /* | ||
| 522 | * recalculate number of entries after collapsing since it | ||
| 523 | * might be changed during the collapse phase. | ||
| 524 | */ | ||
| 525 | rep->nr_entries = 0; | ||
| 526 | evlist__for_each(session->evlist, pos) | ||
| 527 | rep->nr_entries += evsel__hists(pos)->nr_entries; | ||
| 528 | |||
| 508 | if (rep->nr_entries == 0) { | 529 | if (rep->nr_entries == 0) { |
| 509 | ui__error("The %s file has no samples!\n", file->path); | 530 | ui__error("The %s file has no samples!\n", file->path); |
| 510 | return 0; | 531 | return 0; |
| 511 | } | 532 | } |
| 512 | 533 | ||
| 513 | evlist__for_each(session->evlist, pos) | 534 | report__output_resort(rep); |
| 514 | hists__output_resort(evsel__hists(pos)); | ||
| 515 | 535 | ||
| 516 | return report__browse_hists(rep); | 536 | return report__browse_hists(rep); |
| 517 | } | 537 | } |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0aa7747ff139..961cea183a83 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -285,7 +285,7 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | hists__collapse_resort(hists, NULL); | 287 | hists__collapse_resort(hists, NULL); |
| 288 | hists__output_resort(hists); | 288 | hists__output_resort(hists, NULL); |
| 289 | 289 | ||
| 290 | hists__output_recalc_col_len(hists, top->print_entries - printed); | 290 | hists__output_recalc_col_len(hists, top->print_entries - printed); |
| 291 | putchar('\n'); | 291 | putchar('\n'); |
| @@ -554,7 +554,7 @@ static void perf_top__sort_new_samples(void *arg) | |||
| 554 | } | 554 | } |
| 555 | 555 | ||
| 556 | hists__collapse_resort(hists, NULL); | 556 | hists__collapse_resort(hists, NULL); |
| 557 | hists__output_resort(hists); | 557 | hists__output_resort(hists, NULL); |
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | static void *display_thread_tui(void *arg) | 560 | static void *display_thread_tui(void *arg) |
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 614d5c4978ab..4b8226e19a91 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c | |||
| @@ -187,7 +187,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec | |||
| 187 | * function since TEST_ASSERT_VAL() returns in case of failure. | 187 | * function since TEST_ASSERT_VAL() returns in case of failure. |
| 188 | */ | 188 | */ |
| 189 | hists__collapse_resort(hists, NULL); | 189 | hists__collapse_resort(hists, NULL); |
| 190 | hists__output_resort(hists); | 190 | hists__output_resort(hists, NULL); |
| 191 | 191 | ||
| 192 | if (verbose > 2) { | 192 | if (verbose > 2) { |
| 193 | pr_info("use callchain: %d, cumulate callchain: %d\n", | 193 | pr_info("use callchain: %d, cumulate callchain: %d\n", |
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 74f257a81265..59e53db7914c 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c | |||
| @@ -138,7 +138,7 @@ int test__hists_filter(void) | |||
| 138 | struct hists *hists = evsel__hists(evsel); | 138 | struct hists *hists = evsel__hists(evsel); |
| 139 | 139 | ||
| 140 | hists__collapse_resort(hists, NULL); | 140 | hists__collapse_resort(hists, NULL); |
| 141 | hists__output_resort(hists); | 141 | hists__output_resort(hists, NULL); |
| 142 | 142 | ||
| 143 | if (verbose > 2) { | 143 | if (verbose > 2) { |
| 144 | pr_info("Normal histogram\n"); | 144 | pr_info("Normal histogram\n"); |
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index a748f2be1222..f5547610da02 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c | |||
| @@ -152,7 +152,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine) | |||
| 152 | goto out; | 152 | goto out; |
| 153 | 153 | ||
| 154 | hists__collapse_resort(hists, NULL); | 154 | hists__collapse_resort(hists, NULL); |
| 155 | hists__output_resort(hists); | 155 | hists__output_resort(hists, NULL); |
| 156 | 156 | ||
| 157 | if (verbose > 2) { | 157 | if (verbose > 2) { |
| 158 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); | 158 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -252,7 +252,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine) | |||
| 252 | goto out; | 252 | goto out; |
| 253 | 253 | ||
| 254 | hists__collapse_resort(hists, NULL); | 254 | hists__collapse_resort(hists, NULL); |
| 255 | hists__output_resort(hists); | 255 | hists__output_resort(hists, NULL); |
| 256 | 256 | ||
| 257 | if (verbose > 2) { | 257 | if (verbose > 2) { |
| 258 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); | 258 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -306,7 +306,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) | |||
| 306 | goto out; | 306 | goto out; |
| 307 | 307 | ||
| 308 | hists__collapse_resort(hists, NULL); | 308 | hists__collapse_resort(hists, NULL); |
| 309 | hists__output_resort(hists); | 309 | hists__output_resort(hists, NULL); |
| 310 | 310 | ||
| 311 | if (verbose > 2) { | 311 | if (verbose > 2) { |
| 312 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); | 312 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -384,7 +384,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) | |||
| 384 | goto out; | 384 | goto out; |
| 385 | 385 | ||
| 386 | hists__collapse_resort(hists, NULL); | 386 | hists__collapse_resort(hists, NULL); |
| 387 | hists__output_resort(hists); | 387 | hists__output_resort(hists, NULL); |
| 388 | 388 | ||
| 389 | if (verbose > 2) { | 389 | if (verbose > 2) { |
| 390 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); | 390 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
| @@ -487,7 +487,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine) | |||
| 487 | goto out; | 487 | goto out; |
| 488 | 488 | ||
| 489 | hists__collapse_resort(hists, NULL); | 489 | hists__collapse_resort(hists, NULL); |
| 490 | hists__output_resort(hists); | 490 | hists__output_resort(hists, NULL); |
| 491 | 491 | ||
| 492 | if (verbose > 2) { | 492 | if (verbose > 2) { |
| 493 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); | 493 | pr_info("[fields = %s, sort = %s]\n", field_order, sort_order); |
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 2f612562978c..3c38f25b1695 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | #include <signal.h> | 1 | #include <signal.h> |
| 2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
| 3 | #ifdef HAVE_BACKTRACE_SUPPORT | ||
| 4 | #include <execinfo.h> | ||
| 5 | #endif | ||
| 3 | 6 | ||
| 4 | #include "../../util/cache.h" | 7 | #include "../../util/cache.h" |
| 5 | #include "../../util/debug.h" | 8 | #include "../../util/debug.h" |
| @@ -88,6 +91,25 @@ int ui__getch(int delay_secs) | |||
| 88 | return SLkp_getkey(); | 91 | return SLkp_getkey(); |
| 89 | } | 92 | } |
| 90 | 93 | ||
| 94 | #ifdef HAVE_BACKTRACE_SUPPORT | ||
| 95 | static void ui__signal_backtrace(int sig) | ||
| 96 | { | ||
| 97 | void *stackdump[32]; | ||
| 98 | size_t size; | ||
| 99 | |||
| 100 | ui__exit(false); | ||
| 101 | psignal(sig, "perf"); | ||
| 102 | |||
| 103 | printf("-------- backtrace --------\n"); | ||
| 104 | size = backtrace(stackdump, ARRAY_SIZE(stackdump)); | ||
| 105 | backtrace_symbols_fd(stackdump, size, STDOUT_FILENO); | ||
| 106 | |||
| 107 | exit(0); | ||
| 108 | } | ||
| 109 | #else | ||
| 110 | # define ui__signal_backtrace ui__signal | ||
| 111 | #endif | ||
| 112 | |||
| 91 | static void ui__signal(int sig) | 113 | static void ui__signal(int sig) |
| 92 | { | 114 | { |
| 93 | ui__exit(false); | 115 | ui__exit(false); |
| @@ -122,8 +144,8 @@ int ui__init(void) | |||
| 122 | ui_browser__init(); | 144 | ui_browser__init(); |
| 123 | tui_progress__init(); | 145 | tui_progress__init(); |
| 124 | 146 | ||
| 125 | signal(SIGSEGV, ui__signal); | 147 | signal(SIGSEGV, ui__signal_backtrace); |
| 126 | signal(SIGFPE, ui__signal); | 148 | signal(SIGFPE, ui__signal_backtrace); |
| 127 | signal(SIGINT, ui__signal); | 149 | signal(SIGINT, ui__signal); |
| 128 | signal(SIGQUIT, ui__signal); | 150 | signal(SIGQUIT, ui__signal); |
| 129 | signal(SIGTERM, ui__signal); | 151 | signal(SIGTERM, ui__signal); |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6e88b9e395df..0ced178ce306 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "evlist.h" | 6 | #include "evlist.h" |
| 7 | #include "evsel.h" | 7 | #include "evsel.h" |
| 8 | #include "annotate.h" | 8 | #include "annotate.h" |
| 9 | #include "ui/progress.h" | ||
| 9 | #include <math.h> | 10 | #include <math.h> |
| 10 | 11 | ||
| 11 | static bool hists__filter_entry_by_dso(struct hists *hists, | 12 | static bool hists__filter_entry_by_dso(struct hists *hists, |
| @@ -303,7 +304,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template, | |||
| 303 | size_t callchain_size = 0; | 304 | size_t callchain_size = 0; |
| 304 | struct hist_entry *he; | 305 | struct hist_entry *he; |
| 305 | 306 | ||
| 306 | if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) | 307 | if (symbol_conf.use_callchain) |
| 307 | callchain_size = sizeof(struct callchain_root); | 308 | callchain_size = sizeof(struct callchain_root); |
| 308 | 309 | ||
| 309 | he = zalloc(sizeof(*he) + callchain_size); | 310 | he = zalloc(sizeof(*he) + callchain_size); |
| @@ -736,7 +737,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter, | |||
| 736 | iter->he = he; | 737 | iter->he = he; |
| 737 | he_cache[iter->curr++] = he; | 738 | he_cache[iter->curr++] = he; |
| 738 | 739 | ||
| 739 | callchain_append(he->callchain, &callchain_cursor, sample->period); | 740 | hist_entry__append_callchain(he, sample); |
| 740 | 741 | ||
| 741 | /* | 742 | /* |
| 742 | * We need to re-initialize the cursor since callchain_append() | 743 | * We need to re-initialize the cursor since callchain_append() |
| @@ -809,7 +810,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, | |||
| 809 | iter->he = he; | 810 | iter->he = he; |
| 810 | he_cache[iter->curr++] = he; | 811 | he_cache[iter->curr++] = he; |
| 811 | 812 | ||
| 812 | callchain_append(he->callchain, &cursor, sample->period); | 813 | if (symbol_conf.use_callchain) |
| 814 | callchain_append(he->callchain, &cursor, sample->period); | ||
| 813 | return 0; | 815 | return 0; |
| 814 | } | 816 | } |
| 815 | 817 | ||
| @@ -987,6 +989,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused, | |||
| 987 | else | 989 | else |
| 988 | p = &(*p)->rb_right; | 990 | p = &(*p)->rb_right; |
| 989 | } | 991 | } |
| 992 | hists->nr_entries++; | ||
| 990 | 993 | ||
| 991 | rb_link_node(&he->rb_node_in, parent, p); | 994 | rb_link_node(&he->rb_node_in, parent, p); |
| 992 | rb_insert_color(&he->rb_node_in, root); | 995 | rb_insert_color(&he->rb_node_in, root); |
| @@ -1024,7 +1027,10 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) | |||
| 1024 | if (!sort__need_collapse) | 1027 | if (!sort__need_collapse) |
| 1025 | return; | 1028 | return; |
| 1026 | 1029 | ||
| 1030 | hists->nr_entries = 0; | ||
| 1031 | |||
| 1027 | root = hists__get_rotate_entries_in(hists); | 1032 | root = hists__get_rotate_entries_in(hists); |
| 1033 | |||
| 1028 | next = rb_first(root); | 1034 | next = rb_first(root); |
| 1029 | 1035 | ||
| 1030 | while (next) { | 1036 | while (next) { |
| @@ -1119,7 +1125,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, | |||
| 1119 | rb_insert_color(&he->rb_node, entries); | 1125 | rb_insert_color(&he->rb_node, entries); |
| 1120 | } | 1126 | } |
| 1121 | 1127 | ||
| 1122 | void hists__output_resort(struct hists *hists) | 1128 | void hists__output_resort(struct hists *hists, struct ui_progress *prog) |
| 1123 | { | 1129 | { |
| 1124 | struct rb_root *root; | 1130 | struct rb_root *root; |
| 1125 | struct rb_node *next; | 1131 | struct rb_node *next; |
| @@ -1148,6 +1154,9 @@ void hists__output_resort(struct hists *hists) | |||
| 1148 | 1154 | ||
| 1149 | if (!n->filtered) | 1155 | if (!n->filtered) |
| 1150 | hists__calc_col_len(hists, n); | 1156 | hists__calc_col_len(hists, n); |
| 1157 | |||
| 1158 | if (prog) | ||
| 1159 | ui_progress__update(prog, 1); | ||
| 1151 | } | 1160 | } |
| 1152 | } | 1161 | } |
| 1153 | 1162 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index d0ef9a19a744..46bd50344f85 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -121,7 +121,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size, | |||
| 121 | struct hists *hists); | 121 | struct hists *hists); |
| 122 | void hist_entry__free(struct hist_entry *); | 122 | void hist_entry__free(struct hist_entry *); |
| 123 | 123 | ||
| 124 | void hists__output_resort(struct hists *hists); | 124 | void hists__output_resort(struct hists *hists, struct ui_progress *prog); |
| 125 | void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); | 125 | void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); |
| 126 | 126 | ||
| 127 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); | 127 | void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); |
