aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-11-25 17:10:20 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-07-12 12:54:16 -0400
commit5f3f8d3b1207cba3664d57a33de43f5ee11c8a06 (patch)
treea53c53dacba12cf133b342724497a15bef0f7136
parentef358e6dcaba76d1c00dba5fc6cd4cde1d1a2f13 (diff)
perf diff: Add generic order option for compute sorting
Adding option 'o' to allow sorting based on the input file number. By default (without -o option) the output is sorted on baseline. Also removing '+' sorting support from -c option, because it's not needed anymore. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/n/tip-l7dvhgt0azm7yiqg3fbn4dxw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/Documentation/perf-diff.txt6
-rw-r--r--tools/perf/builtin-diff.c95
2 files changed, 70 insertions, 31 deletions
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 2d134f3f1c9d..fdfceee0ffd0 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -75,8 +75,6 @@ OPTIONS
75-c:: 75-c::
76--compute:: 76--compute::
77 Differential computation selection - delta,ratio,wdiff (default is delta). 77 Differential computation selection - delta,ratio,wdiff (default is delta).
78 If '+' is specified as a first character, the output is sorted based
79 on the computation results.
80 See COMPARISON METHODS section for more info. 78 See COMPARISON METHODS section for more info.
81 79
82-p:: 80-p::
@@ -87,6 +85,10 @@ OPTIONS
87--formula:: 85--formula::
88 Show formula for given computation. 86 Show formula for given computation.
89 87
88-o::
89--order::
90 Specify compute sorting column number.
91
90COMPARISON 92COMPARISON
91---------- 93----------
92The comparison is governed by the baseline file. The baseline perf.data 94The comparison is governed by the baseline file. The baseline perf.data
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index f2fbf69ad984..93de3ac177c5 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -64,7 +64,7 @@ static bool force;
64static bool show_period; 64static bool show_period;
65static bool show_formula; 65static bool show_formula;
66static bool show_baseline_only; 66static bool show_baseline_only;
67static bool sort_compute; 67static unsigned int sort_compute;
68 68
69static s64 compute_wdiff_w1; 69static s64 compute_wdiff_w1;
70static s64 compute_wdiff_w2; 70static s64 compute_wdiff_w2;
@@ -188,13 +188,6 @@ static int setup_compute(const struct option *opt, const char *str,
188 return 0; 188 return 0;
189 } 189 }
190 190
191 if (*str == '+') {
192 sort_compute = true;
193 cstr = (char *) ++str;
194 if (!*str)
195 return 0;
196 }
197
198 option = strchr(str, ':'); 191 option = strchr(str, ':');
199 if (option) { 192 if (option) {
200 unsigned len = option++ - str; 193 unsigned len = option++ - str;
@@ -378,6 +371,29 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
378 } 371 }
379} 372}
380 373
374static struct hist_entry*
375get_pair_data(struct hist_entry *he, struct data__file *d)
376{
377 if (hist_entry__has_pairs(he)) {
378 struct hist_entry *pair;
379
380 list_for_each_entry(pair, &he->pairs.head, pairs.node)
381 if (pair->hists == d->hists)
382 return pair;
383 }
384
385 return NULL;
386}
387
388static struct hist_entry*
389get_pair_fmt(struct hist_entry *he, struct diff_hpp_fmt *dfmt)
390{
391 void *ptr = dfmt - dfmt->idx;
392 struct data__file *d = container_of(ptr, struct data__file, fmt);
393
394 return get_pair_data(he, d);
395}
396
381static void hists__baseline_only(struct hists *hists) 397static void hists__baseline_only(struct hists *hists)
382{ 398{
383 struct rb_root *root; 399 struct rb_root *root;
@@ -412,10 +428,12 @@ static void hists__precompute(struct hists *hists)
412 428
413 next = rb_first(root); 429 next = rb_first(root);
414 while (next != NULL) { 430 while (next != NULL) {
415 struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in); 431 struct hist_entry *he, *pair;
416 struct hist_entry *pair = hist_entry__next_pair(he);
417 432
433 he = rb_entry(next, struct hist_entry, rb_node_in);
418 next = rb_next(&he->rb_node_in); 434 next = rb_next(&he->rb_node_in);
435
436 pair = get_pair_data(he, &data__files[sort_compute]);
419 if (!pair) 437 if (!pair)
420 continue; 438 continue;
421 439
@@ -446,7 +464,7 @@ static int64_t cmp_doubles(double l, double r)
446} 464}
447 465
448static int64_t 466static int64_t
449hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right, 467__hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
450 int c) 468 int c)
451{ 469{
452 switch (c) { 470 switch (c) {
@@ -478,6 +496,36 @@ hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
478 return 0; 496 return 0;
479} 497}
480 498
499static int64_t
500hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
501 int c)
502{
503 bool pairs_left = hist_entry__has_pairs(left);
504 bool pairs_right = hist_entry__has_pairs(right);
505 struct hist_entry *p_right, *p_left;
506
507 if (!pairs_left && !pairs_right)
508 return 0;
509
510 if (!pairs_left || !pairs_right)
511 return pairs_left ? -1 : 1;
512
513 p_left = get_pair_data(left, &data__files[sort_compute]);
514 p_right = get_pair_data(right, &data__files[sort_compute]);
515
516 if (!p_left && !p_right)
517 return 0;
518
519 if (!p_left || !p_right)
520 return p_left ? -1 : 1;
521
522 /*
523 * We have 2 entries of same kind, let's
524 * make the data comparison.
525 */
526 return __hist_entry__cmp_compute(p_left, p_right, c);
527}
528
481static void insert_hist_entry_by_compute(struct rb_root *root, 529static void insert_hist_entry_by_compute(struct rb_root *root,
482 struct hist_entry *he, 530 struct hist_entry *he,
483 int c) 531 int c)
@@ -680,6 +728,7 @@ static const struct option options[] = {
680 "columns '.' is reserved."), 728 "columns '.' is reserved."),
681 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 729 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
682 "Look for files with symbols relative to this directory"), 730 "Look for files with symbols relative to this directory"),
731 OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
683 OPT_END() 732 OPT_END()
684}; 733};
685 734
@@ -791,28 +840,11 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry *pair,
791 }; 840 };
792} 841}
793 842
794static struct hist_entry *get_pair(struct hist_entry *he,
795 struct diff_hpp_fmt *dfmt)
796{
797 void *ptr = dfmt - dfmt->idx;
798 struct data__file *d = container_of(ptr, struct data__file, fmt);
799
800 if (hist_entry__has_pairs(he)) {
801 struct hist_entry *pair;
802
803 list_for_each_entry(pair, &he->pairs.head, pairs.node)
804 if (pair->hists == d->hists)
805 return pair;
806 }
807
808 return NULL;
809}
810
811static void 843static void
812__hpp__entry_global(struct hist_entry *he, struct diff_hpp_fmt *dfmt, 844__hpp__entry_global(struct hist_entry *he, struct diff_hpp_fmt *dfmt,
813 char *buf, size_t size) 845 char *buf, size_t size)
814{ 846{
815 struct hist_entry *pair = get_pair(he, dfmt); 847 struct hist_entry *pair = get_pair_fmt(he, dfmt);
816 int idx = dfmt->idx; 848 int idx = dfmt->idx;
817 849
818 /* baseline is special */ 850 /* baseline is special */
@@ -972,6 +1004,11 @@ static int data_init(int argc, const char **argv)
972 defaults[1] = "perf.data.guest"; 1004 defaults[1] = "perf.data.guest";
973 } 1005 }
974 1006
1007 if (sort_compute >= (unsigned int) data__files_cnt) {
1008 pr_err("Order option out of limit.\n");
1009 return -EINVAL;
1010 }
1011
975 data__files = zalloc(sizeof(*data__files) * data__files_cnt); 1012 data__files = zalloc(sizeof(*data__files) * data__files_cnt);
976 if (!data__files) 1013 if (!data__files)
977 return -ENOMEM; 1014 return -ENOMEM;