From 1ab1fa5dfb429c533fbc791e524788cf0cc43775 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 26 Dec 2013 15:11:52 +0900 Subject: perf hists: Add support for showing relative percentage When filtering by thread, dso or symbol on TUI it also update total period so that the output shows different result than no filter - the percentage changed to relative to filtered entries only. Sometimes this is not desired since users might expect same results with filter. So new filtered_* fields to hists->stats to count them separately. They'll be controlled/used by user later. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-2-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f38590d7561b..1ed3e2b86f0b 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -674,8 +674,8 @@ void hists__output_resort(struct hists *hists) next = rb_first(root); hists->entries = RB_ROOT; - hists->nr_entries = 0; - hists->stats.total_period = 0; + hists->nr_entries = hists->nr_non_filtered_entries = 0; + hists->stats.total_period = hists->stats.total_non_filtered_period = 0; hists__reset_col_len(hists); while (next) { @@ -695,11 +695,16 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h return; ++hists->nr_entries; - if (h->ms.unfolded) + ++hists->nr_non_filtered_entries; + if (h->ms.unfolded) { hists->nr_entries += h->nr_rows; + hists->nr_non_filtered_entries += h->nr_rows; + } h->row_offset = 0; hists->stats.total_period += h->stat.period; + hists->stats.total_non_filtered_period += h->stat.period; hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->stat.nr_events; + hists->stats.nr_non_filtered_samples += h->stat.nr_events; hists__calc_col_len(hists, h); } @@ -722,7 +727,9 @@ void hists__filter_by_dso(struct hists *hists) struct rb_node *nd; hists->nr_entries = hists->stats.total_period = 0; + hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { @@ -755,7 +762,9 @@ void hists__filter_by_thread(struct hists *hists) struct rb_node *nd; hists->nr_entries = hists->stats.total_period = 0; + hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { @@ -786,7 +795,9 @@ void hists__filter_by_symbol(struct hists *hists) struct rb_node *nd; hists->nr_entries = hists->stats.total_period = 0; + hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { -- cgit v1.2.3 From f2148330544a697481219b5bc34261f6dd049bfb Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Jan 2014 11:52:48 +0900 Subject: perf report: Add --percentage option The --percentage option is for controlling overhead percentage displayed. It can only receive either of "relative" or "absolute". "relative" means it's relative to filtered entries only so that the sum of shown entries will be always 100%. "absolute" means it retains the original value before and after the filter is applied. $ perf report -s comm # Overhead Command # ........ ............ # 74.19% cc1 7.61% gcc 6.11% as 4.35% sh 4.14% make 1.13% fixdep ... $ perf report -s comm -c cc1,gcc --percentage absolute # Overhead Command # ........ ............ # 74.19% cc1 7.61% gcc $ perf report -s comm -c cc1,gcc --percentage relative # Overhead Command # ........ ............ # 90.69% cc1 9.31% gcc Note that it has zero effect if no filter was applied. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-3-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 1ed3e2b86f0b..3ebd89a28257 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -321,9 +321,11 @@ void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) { if (!h->filtered) { hists__calc_col_len(hists, h); - ++hists->nr_entries; - hists->stats.total_period += h->stat.period; + hists->nr_non_filtered_entries++; + hists->stats.total_non_filtered_period += h->stat.period; } + hists->nr_entries++; + hists->stats.total_period += h->stat.period; } static u8 symbol__parent_filter(const struct symbol *parent) @@ -674,8 +676,9 @@ void hists__output_resort(struct hists *hists) next = rb_first(root); hists->entries = RB_ROOT; - hists->nr_entries = hists->nr_non_filtered_entries = 0; - hists->stats.total_period = hists->stats.total_non_filtered_period = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_period = 0; + hists->stats.total_non_filtered_period = 0; hists__reset_col_len(hists); while (next) { @@ -694,16 +697,11 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h if (h->filtered) return; - ++hists->nr_entries; ++hists->nr_non_filtered_entries; - if (h->ms.unfolded) { - hists->nr_entries += h->nr_rows; + if (h->ms.unfolded) hists->nr_non_filtered_entries += h->nr_rows; - } h->row_offset = 0; - hists->stats.total_period += h->stat.period; hists->stats.total_non_filtered_period += h->stat.period; - hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->stat.nr_events; hists->stats.nr_non_filtered_samples += h->stat.nr_events; hists__calc_col_len(hists, h); @@ -726,9 +724,8 @@ void hists__filter_by_dso(struct hists *hists) { struct rb_node *nd; - hists->nr_entries = hists->stats.total_period = 0; - hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); @@ -761,9 +758,8 @@ void hists__filter_by_thread(struct hists *hists) { struct rb_node *nd; - hists->nr_entries = hists->stats.total_period = 0; - hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); @@ -794,9 +790,8 @@ void hists__filter_by_symbol(struct hists *hists) { struct rb_node *nd; - hists->nr_entries = hists->stats.total_period = 0; - hists->nr_non_filtered_entries = hists->stats.total_non_filtered_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; hists__reset_col_len(hists); @@ -942,3 +937,9 @@ int hists__link(struct hists *leader, struct hists *other) return 0; } + +u64 hists__total_period(struct hists *hists) +{ + return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : + hists->stats.total_period; +} -- cgit v1.2.3 From 33db4568e1f41efe6d0e4695483f968fc1135bf3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Feb 2014 12:06:07 +0900 Subject: perf top: Add --percentage option The --percentage option is for controlling overhead percentage displayed. It can only receive either of "relative" or "absolute". Move the parser callback function into a common location since it's used by multiple commands now. For more information, please see previous commit same thing done to "perf report". Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-4-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3ebd89a28257..3c2dd233b98e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -943,3 +943,16 @@ u64 hists__total_period(struct hists *hists) return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : hists->stats.total_period; } + +int parse_filter_percentage(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused) +{ + if (!strcmp(arg, "relative")) + symbol_conf.filter_relative = true; + else if (!strcmp(arg, "absolute")) + symbol_conf.filter_relative = false; + else + return -1; + + return 0; +} -- cgit v1.2.3 From 0b93da1756df4fe930ee0220a6addce263a6e0ab Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Jan 2014 12:02:15 +0900 Subject: perf tools: Add hist.percentage config option Add hist.percentage option for setting default value of the symbol_conf.filter_relative. It affects the output of various perf commands (like perf report, top and diff) only if filter(s) applied. An user can write .perfconfig file like below to show absolute percentage of filtered entries by default: $ cat ~/.perfconfig [hist] percentage = absolute And it can be changed through command line: $ perf report --percentage relative Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1397145720-8063-6-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3c2dd233b98e..5a892477aa50 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -956,3 +956,11 @@ int parse_filter_percentage(const struct option *opt __maybe_unused, return 0; } + +int perf_hist_config(const char *var, const char *value) +{ + if (!strcmp(var, "hist.percentage")) + return parse_filter_percentage(NULL, value, 0); + + return 0; +} -- cgit v1.2.3 From 6263835a1b1ad137f3c26a1383c0487a9388d06e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 24 Apr 2014 16:21:46 +0900 Subject: perf hists: Rename hists__inc_stats() The existing hists__inc_nr_entries() is a misnomer as it's not only increasing ->nr_entries but also other stats. So rename it to more general hists__inc_stats(). Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-3-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 5a892477aa50..12d6c1bd761d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -317,7 +317,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) return he; } -void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) +void hists__inc_stats(struct hists *hists, struct hist_entry *h) { if (!h->filtered) { hists__calc_col_len(hists, h); @@ -686,7 +686,7 @@ void hists__output_resort(struct hists *hists) next = rb_next(&n->rb_node_in); __hists__insert_output_entry(&hists->entries, n, min_callchain_hits); - hists__inc_nr_entries(hists, n); + hists__inc_stats(hists, n); } } @@ -853,7 +853,7 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists, he->hists = hists; rb_link_node(&he->rb_node_in, parent, p); rb_insert_color(&he->rb_node_in, root); - hists__inc_nr_entries(hists, he); + hists__inc_stats(hists, he); he->dummy = true; } out: -- cgit v1.2.3 From ae993efc9c6bd109b027d2799a442892067e9230 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 24 Apr 2014 16:25:19 +0900 Subject: perf hists: Move column length calculation out of hists__inc_stats() It's not the part of logic of hists__inc_stats() so it'd be better to move it out of the function. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-4-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 12d6c1bd761d..f5b388e50265 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -320,7 +320,6 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) void hists__inc_stats(struct hists *hists, struct hist_entry *h) { if (!h->filtered) { - hists__calc_col_len(hists, h); hists->nr_non_filtered_entries++; hists->stats.total_non_filtered_period += h->stat.period; } @@ -687,6 +686,9 @@ void hists__output_resort(struct hists *hists) __hists__insert_output_entry(&hists->entries, n, min_callchain_hits); hists__inc_stats(hists, n); + + if (!n->filtered) + hists__calc_col_len(hists, n); } } -- cgit v1.2.3 From 9283ba9bd77a6940ecad8721429131d773c704b8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 24 Apr 2014 16:37:26 +0900 Subject: perf hists: Add a couple of hists stat helper functions Add hists__{reset,inc}_[filter_]stats() functions to cleanup accesses to hist stats (for output). Note that number of samples in the stat is not handled here since it belongs to the input stage. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-5-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 59 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f5b388e50265..b675857883a2 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -317,16 +317,6 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) return he; } -void hists__inc_stats(struct hists *hists, struct hist_entry *h) -{ - if (!h->filtered) { - hists->nr_non_filtered_entries++; - hists->stats.total_non_filtered_period += h->stat.period; - } - hists->nr_entries++; - hists->stats.total_period += h->stat.period; -} - static u8 symbol__parent_filter(const struct symbol *parent) { if (symbol_conf.exclude_other && parent == NULL) @@ -632,6 +622,35 @@ out: return ret; } +static void hists__reset_filter_stats(struct hists *hists) +{ + hists->nr_non_filtered_entries = 0; + hists->stats.total_non_filtered_period = 0; +} + +void hists__reset_stats(struct hists *hists) +{ + hists->nr_entries = 0; + hists->stats.total_period = 0; + + hists__reset_filter_stats(hists); +} + +static void hists__inc_filter_stats(struct hists *hists, struct hist_entry *h) +{ + hists->nr_non_filtered_entries++; + hists->stats.total_non_filtered_period += h->stat.period; +} + +void hists__inc_stats(struct hists *hists, struct hist_entry *h) +{ + if (!h->filtered) + hists__inc_filter_stats(hists, h); + + hists->nr_entries++; + hists->stats.total_period += h->stat.period; +} + static void __hists__insert_output_entry(struct rb_root *entries, struct hist_entry *he, u64 min_callchain_hits) @@ -675,9 +694,7 @@ void hists__output_resort(struct hists *hists) next = rb_first(root); hists->entries = RB_ROOT; - hists->nr_non_filtered_entries = 0; - hists->stats.total_period = 0; - hists->stats.total_non_filtered_period = 0; + hists__reset_stats(hists); hists__reset_col_len(hists); while (next) { @@ -699,13 +716,13 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h if (h->filtered) return; - ++hists->nr_non_filtered_entries; if (h->ms.unfolded) hists->nr_non_filtered_entries += h->nr_rows; h->row_offset = 0; - hists->stats.total_non_filtered_period += h->stat.period; + hists->stats.nr_non_filtered_samples += h->stat.nr_events; + hists__inc_filter_stats(hists, h); hists__calc_col_len(hists, h); } @@ -726,9 +743,9 @@ void hists__filter_by_dso(struct hists *hists) { struct rb_node *nd; - hists->nr_non_filtered_entries = 0; - hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; + + hists__reset_filter_stats(hists); hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { @@ -760,9 +777,9 @@ void hists__filter_by_thread(struct hists *hists) { struct rb_node *nd; - hists->nr_non_filtered_entries = 0; - hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; + + hists__reset_filter_stats(hists); hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { @@ -792,9 +809,9 @@ void hists__filter_by_symbol(struct hists *hists) { struct rb_node *nd; - hists->nr_non_filtered_entries = 0; - hists->stats.total_non_filtered_period = 0; hists->stats.nr_non_filtered_samples = 0; + + hists__reset_filter_stats(hists); hists__reset_col_len(hists); for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { -- cgit v1.2.3 From 87e90f43285f4096e9ba5fc18b05c2e04caf3fab Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 24 Apr 2014 16:44:16 +0900 Subject: perf hists: Collapse expanded callchains after filter is applied When a filter is applied a hist entry checks whether its callchain was folded and account it to the output stat. But this is rather hacky and only TUI-specific. Simply fold the callchains for the entry looks like a simpler and more generic solution IMHO. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-6-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index b675857883a2..8d5cfcc3bc63 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -716,8 +716,8 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h if (h->filtered) return; - if (h->ms.unfolded) - hists->nr_non_filtered_entries += h->nr_rows; + /* force fold unfiltered entry for simplicity */ + h->ms.unfolded = false; h->row_offset = 0; hists->stats.nr_non_filtered_samples += h->stat.nr_events; -- cgit v1.2.3 From 820bc81f4cdaac09a8f25040d3a20d86f3da292b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 22 Apr 2014 11:44:21 +0900 Subject: perf tools: Account entry stats when it's added to the output tree Currently, accounting each sample is done in multiple places - once when adding them to the input tree, other when adding them to the output tree. It's not only confusing but also can cause a subtle problem since concurrent processing like in perf top might see the updated stats before adding entries into the output tree - like seeing more (blank) lines at the end and/or slight inaccurate percentage. To fix this, only account the entries when it's moved into the output tree so that they cannot be seen prematurely. There're some exceptional cases here and there - they should be addressed separately with comments. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-7-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 1 - 1 file changed, 1 deletion(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 8d5cfcc3bc63..6d0d2d75db68 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -382,7 +382,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists, if (!he) return NULL; - hists->nr_entries++; rb_link_node(&he->rb_node_in, parent, p); rb_insert_color(&he->rb_node_in, hists->entries_in); out: -- cgit v1.2.3 From 3186b6815d49b5e0defbd884223da3778edb59fc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 22 Apr 2014 13:44:23 +0900 Subject: perf hists: Add missing update on filtered stats in hists__decay_entries() When a filter is used for perf top, its hists->nr_non_filtered_entries was not updated after it removed an entry in hists__decay_entries(). Also hists->stats.total_non_filtered_period was missed too. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1398327843-31845-8-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6d0d2d75db68..7f0236cea4fe 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -225,14 +225,18 @@ static void he_stat__decay(struct he_stat *he_stat) static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) { u64 prev_period = he->stat.period; + u64 diff; if (prev_period == 0) return true; he_stat__decay(&he->stat); + diff = prev_period - he->stat.period; + + hists->stats.total_period -= diff; if (!he->filtered) - hists->stats.total_period -= prev_period - he->stat.period; + hists->stats.total_non_filtered_period -= diff; return he->stat.period == 0; } @@ -259,8 +263,11 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel) if (sort__need_collapse) rb_erase(&n->rb_node_in, &hists->entries_collapsed); - hist_entry__free(n); --hists->nr_entries; + if (!n->filtered) + --hists->nr_non_filtered_entries; + + hist_entry__free(n); } } } -- cgit v1.2.3 From 093f0ef34c50ff5cca41c1e18e258ff688e915b6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 3 Mar 2014 12:07:47 +0900 Subject: perf tools: Use hpp formats to sort hist entries It wrapped sort entries to hpp functions, so using the hpp sort list to sort entries. Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/r/1400480762-22852-4-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 7f0236cea4fe..38373c986e97 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -432,11 +432,11 @@ struct hist_entry *__hists__add_entry(struct hists *hists, int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) { - struct sort_entry *se; + struct perf_hpp_fmt *fmt; int64_t cmp = 0; - list_for_each_entry(se, &hist_entry__sort_list, list) { - cmp = se->se_cmp(left, right); + perf_hpp__for_each_sort_list(fmt) { + cmp = fmt->cmp(left, right); if (cmp) break; } @@ -447,15 +447,11 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) { - struct sort_entry *se; + struct perf_hpp_fmt *fmt; int64_t cmp = 0; - list_for_each_entry(se, &hist_entry__sort_list, list) { - int64_t (*f)(struct hist_entry *, struct hist_entry *); - - f = se->se_collapse ?: se->se_cmp; - - cmp = f(left, right); + perf_hpp__for_each_sort_list(fmt) { + cmp = fmt->collapse(left, right); if (cmp) break; } -- cgit v1.2.3 From 043ca389a3181565b5c19d43a55eae111977d13d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 3 Mar 2014 14:18:00 +0900 Subject: perf tools: Use hpp formats to sort final output Convert output sorting function to use ->sort hpp functions. Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/r/1400480762-22852-6-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 62 +++++++------------------------------------------- 1 file changed, 8 insertions(+), 54 deletions(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 38373c986e97..c99ae4dd973e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -564,64 +564,18 @@ void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) } } -/* - * reverse the map, sort on period. - */ - -static int period_cmp(u64 period_a, u64 period_b) +static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b) { - if (period_a > period_b) - return 1; - if (period_a < period_b) - return -1; - return 0; -} - -static int hist_entry__sort_on_period(struct hist_entry *a, - struct hist_entry *b) -{ - int ret; - int i, nr_members; - struct perf_evsel *evsel; - struct hist_entry *pair; - u64 *periods_a, *periods_b; - - ret = period_cmp(a->stat.period, b->stat.period); - if (ret || !symbol_conf.event_group) - return ret; - - evsel = hists_to_evsel(a->hists); - nr_members = evsel->nr_members; - if (nr_members <= 1) - return ret; - - periods_a = zalloc(sizeof(periods_a) * nr_members); - periods_b = zalloc(sizeof(periods_b) * nr_members); - - if (!periods_a || !periods_b) - goto out; - - list_for_each_entry(pair, &a->pairs.head, pairs.node) { - evsel = hists_to_evsel(pair->hists); - periods_a[perf_evsel__group_idx(evsel)] = pair->stat.period; - } - - list_for_each_entry(pair, &b->pairs.head, pairs.node) { - evsel = hists_to_evsel(pair->hists); - periods_b[perf_evsel__group_idx(evsel)] = pair->stat.period; - } + struct perf_hpp_fmt *fmt; + int64_t cmp = 0; - for (i = 1; i < nr_members; i++) { - ret = period_cmp(periods_a[i], periods_b[i]); - if (ret) + perf_hpp__for_each_format(fmt) { + cmp = fmt->sort(a, b); + if (cmp) break; } -out: - free(periods_a); - free(periods_b); - - return ret; + return cmp; } static void hists__reset_filter_stats(struct hists *hists) @@ -669,7 +623,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, parent = *p; iter = rb_entry(parent, struct hist_entry, rb_node); - if (hist_entry__sort_on_period(he, iter) > 0) + if (hist_entry__sort(he, iter) > 0) p = &(*p)->rb_left; else p = &(*p)->rb_right; -- cgit v1.2.3 From 26d8b338271a17a8a9b78000ebaec8b4645f5476 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 3 Mar 2014 16:16:20 +0900 Subject: perf tools: Consolidate output field handling to hpp format routines Until now the hpp and sort functions do similar jobs different ways. Since the sort functions converted/wrapped to hpp formats it can do the job in a uniform way. The perf_hpp__sort_list has a list of hpp formats to sort entries and the perf_hpp__list has a list of hpp formats to print output result. To have a backward compatibility, it automatically adds 'overhead' field in front of sort list. And then all of fields in sort list added to the output list (if it's not already there). Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Link: http://lkml.kernel.org/n/tip-7g3h86woz2sckg3h1lj42ygj@git.kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index c99ae4dd973e..ae13c2dbd27a 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -569,7 +569,7 @@ static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b) struct perf_hpp_fmt *fmt; int64_t cmp = 0; - perf_hpp__for_each_format(fmt) { + perf_hpp__for_each_sort_list(fmt) { cmp = fmt->sort(a, b); if (cmp) break; -- cgit v1.2.3 From e67d49a72df9aa50841ad400f7a99405e4980ee4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 18 Mar 2014 13:00:59 +0900 Subject: perf tools: Skip elided sort entries When it converted sort entries to hpp formats, it missed se->elide handling, so add it for compatibility. Signed-off-by: Namhyung Kim Link: http://lkml.kernel.org/r/1400480762-22852-16-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/hist.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools/perf/util/hist.c') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index ae13c2dbd27a..b262b44b7a65 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -436,6 +436,9 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) int64_t cmp = 0; perf_hpp__for_each_sort_list(fmt) { + if (perf_hpp__should_skip(fmt)) + continue; + cmp = fmt->cmp(left, right); if (cmp) break; @@ -451,6 +454,9 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) int64_t cmp = 0; perf_hpp__for_each_sort_list(fmt) { + if (perf_hpp__should_skip(fmt)) + continue; + cmp = fmt->collapse(left, right); if (cmp) break; @@ -570,6 +576,9 @@ static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b) int64_t cmp = 0; perf_hpp__for_each_sort_list(fmt) { + if (perf_hpp__should_skip(fmt)) + continue; + cmp = fmt->sort(a, b); if (cmp) break; -- cgit v1.2.3