summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r--tools/perf/builtin-diff.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 204fffe22532..8bff543acaab 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -60,7 +60,6 @@ static int data__files_cnt;
60#define data__for_each_file(i, d) data__for_each_file_start(i, d, 0) 60#define data__for_each_file(i, d) data__for_each_file_start(i, d, 0)
61#define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1) 61#define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1)
62 62
63static char diff__default_sort_order[] = "dso,symbol";
64static bool force; 63static bool force;
65static bool show_period; 64static bool show_period;
66static bool show_formula; 65static bool show_formula;
@@ -220,7 +219,8 @@ static int setup_compute(const struct option *opt, const char *str,
220 219
221static double period_percent(struct hist_entry *he, u64 period) 220static double period_percent(struct hist_entry *he, u64 period)
222{ 221{
223 u64 total = he->hists->stats.total_period; 222 u64 total = hists__total_period(he->hists);
223
224 return (period * 100.0) / total; 224 return (period * 100.0) / total;
225} 225}
226 226
@@ -259,11 +259,18 @@ static s64 compute_wdiff(struct hist_entry *he, struct hist_entry *pair)
259static int formula_delta(struct hist_entry *he, struct hist_entry *pair, 259static int formula_delta(struct hist_entry *he, struct hist_entry *pair,
260 char *buf, size_t size) 260 char *buf, size_t size)
261{ 261{
262 u64 he_total = he->hists->stats.total_period;
263 u64 pair_total = pair->hists->stats.total_period;
264
265 if (symbol_conf.filter_relative) {
266 he_total = he->hists->stats.total_non_filtered_period;
267 pair_total = pair->hists->stats.total_non_filtered_period;
268 }
262 return scnprintf(buf, size, 269 return scnprintf(buf, size,
263 "(%" PRIu64 " * 100 / %" PRIu64 ") - " 270 "(%" PRIu64 " * 100 / %" PRIu64 ") - "
264 "(%" PRIu64 " * 100 / %" PRIu64 ")", 271 "(%" PRIu64 " * 100 / %" PRIu64 ")",
265 pair->stat.period, pair->hists->stats.total_period, 272 pair->stat.period, pair_total,
266 he->stat.period, he->hists->stats.total_period); 273 he->stat.period, he_total);
267} 274}
268 275
269static int formula_ratio(struct hist_entry *he, struct hist_entry *pair, 276static int formula_ratio(struct hist_entry *he, struct hist_entry *pair,
@@ -327,16 +334,22 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
327 return -1; 334 return -1;
328 } 335 }
329 336
330 if (al.filtered)
331 return 0;
332
333 if (hists__add_entry(&evsel->hists, &al, sample->period, 337 if (hists__add_entry(&evsel->hists, &al, sample->period,
334 sample->weight, sample->transaction)) { 338 sample->weight, sample->transaction)) {
335 pr_warning("problem incrementing symbol period, skipping event\n"); 339 pr_warning("problem incrementing symbol period, skipping event\n");
336 return -1; 340 return -1;
337 } 341 }
338 342
343 /*
344 * The total_period is updated here before going to the output
345 * tree since normally only the baseline hists will call
346 * hists__output_resort() and precompute needs the total
347 * period in order to sort entries by percentage delta.
348 */
339 evsel->hists.stats.total_period += sample->period; 349 evsel->hists.stats.total_period += sample->period;
350 if (!al.filtered)
351 evsel->hists.stats.total_non_filtered_period += sample->period;
352
340 return 0; 353 return 0;
341} 354}
342 355
@@ -564,8 +577,7 @@ static void hists__compute_resort(struct hists *hists)
564 hists->entries = RB_ROOT; 577 hists->entries = RB_ROOT;
565 next = rb_first(root); 578 next = rb_first(root);
566 579
567 hists->nr_entries = 0; 580 hists__reset_stats(hists);
568 hists->stats.total_period = 0;
569 hists__reset_col_len(hists); 581 hists__reset_col_len(hists);
570 582
571 while (next != NULL) { 583 while (next != NULL) {
@@ -575,7 +587,10 @@ static void hists__compute_resort(struct hists *hists)
575 next = rb_next(&he->rb_node_in); 587 next = rb_next(&he->rb_node_in);
576 588
577 insert_hist_entry_by_compute(&hists->entries, he, compute); 589 insert_hist_entry_by_compute(&hists->entries, he, compute);
578 hists__inc_nr_entries(hists, he); 590 hists__inc_stats(hists, he);
591
592 if (!he->filtered)
593 hists__calc_col_len(hists, he);
579 } 594 }
580} 595}
581 596
@@ -725,20 +740,24 @@ static const struct option options[] = {
725 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 740 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
726 "only consider these symbols"), 741 "only consider these symbols"),
727 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 742 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
728 "sort by key(s): pid, comm, dso, symbol, parent"), 743 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
744 " Please refer the man page for the complete list."),
729 OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", 745 OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
730 "separator for columns, no spaces will be added between " 746 "separator for columns, no spaces will be added between "
731 "columns '.' is reserved."), 747 "columns '.' is reserved."),
732 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 748 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
733 "Look for files with symbols relative to this directory"), 749 "Look for files with symbols relative to this directory"),
734 OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."), 750 OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
751 OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
752 "How to display percentage of filtered entries", parse_filter_percentage),
735 OPT_END() 753 OPT_END()
736}; 754};
737 755
738static double baseline_percent(struct hist_entry *he) 756static double baseline_percent(struct hist_entry *he)
739{ 757{
740 struct hists *hists = he->hists; 758 u64 total = hists__total_period(he->hists);
741 return 100.0 * he->stat.period / hists->stats.total_period; 759
760 return 100.0 * he->stat.period / total;
742} 761}
743 762
744static int hpp__color_baseline(struct perf_hpp_fmt *fmt, 763static int hpp__color_baseline(struct perf_hpp_fmt *fmt,
@@ -1120,7 +1139,8 @@ static int data_init(int argc, const char **argv)
1120 1139
1121int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) 1140int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
1122{ 1141{
1123 sort_order = diff__default_sort_order; 1142 perf_config(perf_default_config, NULL);
1143
1124 argc = parse_options(argc, argv, options, diff_usage, 0); 1144 argc = parse_options(argc, argv, options, diff_usage, 0);
1125 1145
1126 if (symbol__init() < 0) 1146 if (symbol__init() < 0)
@@ -1131,6 +1151,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
1131 1151
1132 ui_init(); 1152 ui_init();
1133 1153
1154 sort__mode = SORT_MODE__DIFF;
1155
1134 if (setup_sorting() < 0) 1156 if (setup_sorting() < 0)
1135 usage_with_options(diff_usage, options); 1157 usage_with_options(diff_usage, options);
1136 1158