From 1240005e0d3a7e03c2fd05603fb01676e5a004f7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 13 Oct 2012 00:06:16 +0200 Subject: perf hists: Introduce perf_hpp__list for period related columns Adding perf_hpp__list list to register and contain all period related columns the command is interested in. This way we get rid of static array holding all possible columns and enable commands to register their own columns. It'll be handy for diff command in future to process and display data for multiple files. Signed-off-by: Jiri Olsa Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Namhyung Kim Link: http://lkml.kernel.org/n/tip-kiykge4igrcl7etmpmveto1h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 96 ++++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 44 deletions(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index aa84130024d5..0a5281fe41d6 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -386,60 +386,71 @@ static int hpp__entry_formula(struct perf_hpp *hpp, struct hist_entry *he) return scnprintf(hpp->buf, hpp->size, fmt, buf); } -#define HPP__COLOR_PRINT_FNS(_name) \ - .header = hpp__header_ ## _name, \ - .width = hpp__width_ ## _name, \ - .color = hpp__color_ ## _name, \ - .entry = hpp__entry_ ## _name +#define HPP__COLOR_PRINT_FNS(_name) \ + { \ + .header = hpp__header_ ## _name, \ + .width = hpp__width_ ## _name, \ + .color = hpp__color_ ## _name, \ + .entry = hpp__entry_ ## _name \ + } -#define HPP__PRINT_FNS(_name) \ - .header = hpp__header_ ## _name, \ - .width = hpp__width_ ## _name, \ - .entry = hpp__entry_ ## _name +#define HPP__PRINT_FNS(_name) \ + { \ + .header = hpp__header_ ## _name, \ + .width = hpp__width_ ## _name, \ + .entry = hpp__entry_ ## _name \ + } struct perf_hpp_fmt perf_hpp__format[] = { - { .cond = false, HPP__COLOR_PRINT_FNS(baseline) }, - { .cond = true, HPP__COLOR_PRINT_FNS(overhead) }, - { .cond = false, HPP__COLOR_PRINT_FNS(overhead_sys) }, - { .cond = false, HPP__COLOR_PRINT_FNS(overhead_us) }, - { .cond = false, HPP__COLOR_PRINT_FNS(overhead_guest_sys) }, - { .cond = false, HPP__COLOR_PRINT_FNS(overhead_guest_us) }, - { .cond = false, HPP__PRINT_FNS(samples) }, - { .cond = false, HPP__PRINT_FNS(period) }, - { .cond = false, HPP__PRINT_FNS(period_baseline) }, - { .cond = false, HPP__PRINT_FNS(delta) }, - { .cond = false, HPP__PRINT_FNS(ratio) }, - { .cond = false, HPP__PRINT_FNS(wdiff) }, - { .cond = false, HPP__PRINT_FNS(displ) }, - { .cond = false, HPP__PRINT_FNS(formula) } + HPP__COLOR_PRINT_FNS(baseline), + HPP__COLOR_PRINT_FNS(overhead), + HPP__COLOR_PRINT_FNS(overhead_sys), + HPP__COLOR_PRINT_FNS(overhead_us), + HPP__COLOR_PRINT_FNS(overhead_guest_sys), + HPP__COLOR_PRINT_FNS(overhead_guest_us), + HPP__PRINT_FNS(samples), + HPP__PRINT_FNS(period), + HPP__PRINT_FNS(period_baseline), + HPP__PRINT_FNS(delta), + HPP__PRINT_FNS(ratio), + HPP__PRINT_FNS(wdiff), + HPP__PRINT_FNS(displ), + HPP__PRINT_FNS(formula) }; +LIST_HEAD(perf_hpp__list); + #undef HPP__COLOR_PRINT_FNS #undef HPP__PRINT_FNS void perf_hpp__init(void) { if (symbol_conf.show_cpu_utilization) { - perf_hpp__format[PERF_HPP__OVERHEAD_SYS].cond = true; - perf_hpp__format[PERF_HPP__OVERHEAD_US].cond = true; + perf_hpp__column_enable(PERF_HPP__OVERHEAD_SYS); + perf_hpp__column_enable(PERF_HPP__OVERHEAD_US); if (perf_guest) { - perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_SYS].cond = true; - perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].cond = true; + perf_hpp__column_enable(PERF_HPP__OVERHEAD_GUEST_SYS); + perf_hpp__column_enable(PERF_HPP__OVERHEAD_GUEST_US); } } if (symbol_conf.show_nr_samples) - perf_hpp__format[PERF_HPP__SAMPLES].cond = true; + perf_hpp__column_enable(PERF_HPP__SAMPLES); if (symbol_conf.show_total_period) - perf_hpp__format[PERF_HPP__PERIOD].cond = true; + perf_hpp__column_enable(PERF_HPP__PERIOD); } -void perf_hpp__column_enable(unsigned col, bool enable) +void perf_hpp__column_register(struct perf_hpp_fmt *format) +{ + list_add_tail(&format->list, &perf_hpp__list); +} + +void perf_hpp__column_enable(unsigned col) { BUG_ON(col >= PERF_HPP__MAX_INDEX); - perf_hpp__format[col].cond = enable; + perf_hpp__column_register(&perf_hpp__format[col]); } static inline void advance_hpp(struct perf_hpp *hpp, int inc) @@ -452,27 +463,25 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he, bool color) { const char *sep = symbol_conf.field_sep; + struct perf_hpp_fmt *fmt; char *start = hpp->buf; - int i, ret; + int ret; bool first = true; if (symbol_conf.exclude_other && !he->parent) return 0; - for (i = 0; i < PERF_HPP__MAX_INDEX; i++) { - if (!perf_hpp__format[i].cond) - continue; - + perf_hpp__for_each_format(fmt) { if (!sep || !first) { ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: " "); advance_hpp(hpp, ret); first = false; } - if (color && perf_hpp__format[i].color) - ret = perf_hpp__format[i].color(hpp, he); + if (color && fmt->color) + ret = fmt->color(hpp, he); else - ret = perf_hpp__format[i].entry(hpp, he); + ret = fmt->entry(hpp, he); advance_hpp(hpp, ret); } @@ -504,16 +513,15 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size, */ unsigned int hists__sort_list_width(struct hists *hists) { + struct perf_hpp_fmt *fmt; struct sort_entry *se; - int i, ret = 0; + int i = 0, ret = 0; - for (i = 0; i < PERF_HPP__MAX_INDEX; i++) { - if (!perf_hpp__format[i].cond) - continue; + perf_hpp__for_each_format(fmt) { if (i) ret += 2; - ret += perf_hpp__format[i].width(NULL); + ret += fmt->width(NULL); } list_for_each_entry(se, &hist_entry__sort_list, list) -- cgit v1.2.3 From c0d246b85fc7d42688d7a5d999ea671777caf65b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 20 Oct 2012 22:14:10 +0200 Subject: perf hists: Fix period symbol_conf.field_sep display Currently we don't properly display hist data with symbol_conf.field_sep separator. We need to display either space or separator. Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Namhyung Kim Link: http://lkml.kernel.org/n/tip-cyggwys0bz5kqdowwvfd8h72@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 0a5281fe41d6..6e639b506829 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -472,11 +472,15 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he, return 0; perf_hpp__for_each_format(fmt) { + /* + * If there's no field_sep, we still need + * to display initial ' '. + */ if (!sep || !first) { ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: " "); advance_hpp(hpp, ret); + } else first = false; - } if (color && fmt->color) ret = fmt->color(hpp, he); -- cgit v1.2.3 From 05472daa4d8ab88a071bfcaa3bb47473e4071848 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Nov 2012 14:52:40 +0100 Subject: perf diff: Change compute methods to work with pair directly Changing compute methods to operate over hist entry and its pair directly. This makes the code more obvious and readable, instead of all time checking for pair being != NULL. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1354110769-2998-6-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 38 +++++++++++++++++--------------------- tools/perf/ui/hist.c | 40 +++++++++++++++++++++++++--------------- tools/perf/util/hist.h | 7 ++++--- 3 files changed, 46 insertions(+), 39 deletions(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 9fbbc01c5ad7..342085a18076 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -146,47 +146,40 @@ static int setup_compute(const struct option *opt, const char *str, return -EINVAL; } -static double get_period_percent(struct hist_entry *he, u64 period) +double perf_diff__period_percent(struct hist_entry *he, u64 period) { u64 total = he->hists->stats.total_period; return (period * 100.0) / total; } -double perf_diff__compute_delta(struct hist_entry *he) +double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry *pair) { - struct hist_entry *pair = hist_entry__next_pair(he); - double new_percent = get_period_percent(he, he->stat.period); - double old_percent = pair ? get_period_percent(pair, pair->stat.period) : 0.0; + double new_percent = perf_diff__period_percent(he, he->stat.period); + double old_percent = perf_diff__period_percent(pair, pair->stat.period); he->diff.period_ratio_delta = new_percent - old_percent; he->diff.computed = true; return he->diff.period_ratio_delta; } -double perf_diff__compute_ratio(struct hist_entry *he) +double perf_diff__compute_ratio(struct hist_entry *he, struct hist_entry *pair) { - struct hist_entry *pair = hist_entry__next_pair(he); double new_period = he->stat.period; - double old_period = pair ? pair->stat.period : 0; + double old_period = pair->stat.period; he->diff.computed = true; - he->diff.period_ratio = pair ? (new_period / old_period) : 0; + he->diff.period_ratio = new_period / old_period; return he->diff.period_ratio; } -s64 perf_diff__compute_wdiff(struct hist_entry *he) +s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair) { - struct hist_entry *pair = hist_entry__next_pair(he); u64 new_period = he->stat.period; - u64 old_period = pair ? pair->stat.period : 0; + u64 old_period = pair->stat.period; he->diff.computed = true; - - if (!pair) - he->diff.wdiff = 0; - else - he->diff.wdiff = new_period * compute_wdiff_w2 - - old_period * compute_wdiff_w1; + he->diff.wdiff = new_period * compute_wdiff_w2 - + old_period * compute_wdiff_w1; return he->diff.wdiff; } @@ -385,18 +378,21 @@ static void hists__precompute(struct hists *hists) while (next != NULL) { struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); + struct hist_entry *pair = hist_entry__next_pair(he); next = rb_next(&he->rb_node); + if (!pair) + continue; switch (compute) { case COMPUTE_DELTA: - perf_diff__compute_delta(he); + perf_diff__compute_delta(he, pair); break; case COMPUTE_RATIO: - perf_diff__compute_ratio(he); + perf_diff__compute_ratio(he, pair); break; case COMPUTE_WEIGHTED_DIFF: - perf_diff__compute_wdiff(he); + perf_diff__compute_wdiff(he, pair); break; default: BUG_ON(1); diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 6e639b506829..108e5ed67621 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -268,14 +268,18 @@ static int hpp__width_delta(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he) { + struct hist_entry *pair = hist_entry__next_pair(he); const char *fmt = symbol_conf.field_sep ? "%s" : "%7.7s"; char buf[32] = " "; - double diff; + double diff = 0.0; - if (he->diff.computed) - diff = he->diff.period_ratio_delta; - else - diff = perf_diff__compute_delta(he); + if (pair) { + if (he->diff.computed) + diff = he->diff.period_ratio_delta; + else + diff = perf_diff__compute_delta(he, pair); + } else + diff = perf_diff__period_percent(he, he->stat.period); if (fabs(diff) >= 0.01) scnprintf(buf, sizeof(buf), "%+4.2F%%", diff); @@ -297,14 +301,17 @@ static int hpp__width_ratio(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_ratio(struct perf_hpp *hpp, struct hist_entry *he) { + struct hist_entry *pair = hist_entry__next_pair(he); const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; char buf[32] = " "; - double ratio; + double ratio = 0.0; - if (he->diff.computed) - ratio = he->diff.period_ratio; - else - ratio = perf_diff__compute_ratio(he); + if (pair) { + if (he->diff.computed) + ratio = he->diff.period_ratio; + else + ratio = perf_diff__compute_ratio(he, pair); + } if (ratio > 0.0) scnprintf(buf, sizeof(buf), "%+14.6F", ratio); @@ -326,14 +333,17 @@ static int hpp__width_wdiff(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_wdiff(struct perf_hpp *hpp, struct hist_entry *he) { + struct hist_entry *pair = hist_entry__next_pair(he); const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; char buf[32] = " "; - s64 wdiff; + s64 wdiff = 0; - if (he->diff.computed) - wdiff = he->diff.wdiff; - else - wdiff = perf_diff__compute_wdiff(he); + if (pair) { + if (he->diff.computed) + wdiff = he->diff.wdiff; + else + wdiff = perf_diff__compute_wdiff(he, pair); + } if (wdiff != 0) scnprintf(buf, sizeof(buf), "%14ld", wdiff); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a935a60d521c..235503aac08c 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -226,8 +226,9 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, unsigned int hists__sort_list_width(struct hists *self); -double perf_diff__compute_delta(struct hist_entry *he); -double perf_diff__compute_ratio(struct hist_entry *he); -s64 perf_diff__compute_wdiff(struct hist_entry *he); +double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry *pair); +double perf_diff__compute_ratio(struct hist_entry *he, struct hist_entry *pair); +s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair); int perf_diff__formula(char *buf, size_t size, struct hist_entry *he); +double perf_diff__period_percent(struct hist_entry *he, u64 period); #endif /* __PERF_HIST_H */ -- cgit v1.2.3 From f4c8bae1920c459b7b9c12363d11e8a588862e42 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 28 Nov 2012 14:52:41 +0100 Subject: perf diff: Change formula methods to work with pair directly Changing formula methods to operate over hist entry and its pair directly. This makes the code more obvious and readable, instead of all time checking for pair being != NULL. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1354110769-2998-7-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 35 +++++++++++++---------------------- tools/perf/ui/hist.c | 5 ++++- tools/perf/util/hist.h | 3 ++- 3 files changed, 19 insertions(+), 24 deletions(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 342085a18076..d869029fb75e 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -184,13 +184,9 @@ s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair) return he->diff.wdiff; } -static int formula_delta(struct hist_entry *he, char *buf, size_t size) +static int formula_delta(struct hist_entry *he, struct hist_entry *pair, + char *buf, size_t size) { - struct hist_entry *pair = hist_entry__next_pair(he); - - if (!pair) - return -1; - return scnprintf(buf, size, "(%" PRIu64 " * 100 / %" PRIu64 ") - " "(%" PRIu64 " * 100 / %" PRIu64 ")", @@ -198,41 +194,36 @@ static int formula_delta(struct hist_entry *he, char *buf, size_t size) pair->stat.period, pair->hists->stats.total_period); } -static int formula_ratio(struct hist_entry *he, char *buf, size_t size) +static int formula_ratio(struct hist_entry *he, struct hist_entry *pair, + char *buf, size_t size) { - struct hist_entry *pair = hist_entry__next_pair(he); double new_period = he->stat.period; - double old_period = pair ? pair->stat.period : 0; - - if (!pair) - return -1; + double old_period = pair->stat.period; return scnprintf(buf, size, "%.0F / %.0F", new_period, old_period); } -static int formula_wdiff(struct hist_entry *he, char *buf, size_t size) +static int formula_wdiff(struct hist_entry *he, struct hist_entry *pair, + char *buf, size_t size) { - struct hist_entry *pair = hist_entry__next_pair(he); u64 new_period = he->stat.period; - u64 old_period = pair ? pair->stat.period : 0; - - if (!pair) - return -1; + u64 old_period = pair->stat.period; return scnprintf(buf, size, "(%" PRIu64 " * " "%" PRId64 ") - (%" PRIu64 " * " "%" PRId64 ")", new_period, compute_wdiff_w2, old_period, compute_wdiff_w1); } -int perf_diff__formula(char *buf, size_t size, struct hist_entry *he) +int perf_diff__formula(struct hist_entry *he, struct hist_entry *pair, + char *buf, size_t size) { switch (compute) { case COMPUTE_DELTA: - return formula_delta(he, buf, size); + return formula_delta(he, pair, buf, size); case COMPUTE_RATIO: - return formula_ratio(he, buf, size); + return formula_ratio(he, pair, buf, size); case COMPUTE_WEIGHTED_DIFF: - return formula_wdiff(he, buf, size); + return formula_wdiff(he, pair, buf, size); default: BUG_ON(1); } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 108e5ed67621..1785bab7adfd 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -389,10 +389,13 @@ static int hpp__width_formula(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_formula(struct perf_hpp *hpp, struct hist_entry *he) { + struct hist_entry *pair = hist_entry__next_pair(he); const char *fmt = symbol_conf.field_sep ? "%s" : "%-70s"; char buf[96] = " "; - perf_diff__formula(buf, sizeof(buf), he); + if (pair) + perf_diff__formula(he, pair, buf, sizeof(buf)); + return scnprintf(hpp->buf, hpp->size, fmt, buf); } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 235503aac08c..c1b2fade8e70 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -229,6 +229,7 @@ unsigned int hists__sort_list_width(struct hists *self); double perf_diff__compute_delta(struct hist_entry *he, struct hist_entry *pair); double perf_diff__compute_ratio(struct hist_entry *he, struct hist_entry *pair); s64 perf_diff__compute_wdiff(struct hist_entry *he, struct hist_entry *pair); -int perf_diff__formula(char *buf, size_t size, struct hist_entry *he); +int perf_diff__formula(struct hist_entry *he, struct hist_entry *pair, + char *buf, size_t size); double perf_diff__period_percent(struct hist_entry *he, u64 period); #endif /* __PERF_HIST_H */ -- cgit v1.2.3 From db6d0bb86164497f6c9ef46020cf1881953f4b08 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 6 Dec 2012 14:22:28 +0100 Subject: perf diff: Remove displacement output option It seems not very useful, because it's possible and event more convenient to lookup related symbol by name. Also the output value for both 'baseline' and 'new' data is quite apparent from diff output. And above all it complicates hist code factoring ;) Ditching out PERF_HPP__DISPL column with related output functions. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Ingo Molnar Cc: Namhyung Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/20121206132228.GB1080@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 4 ---- tools/perf/builtin-diff.c | 29 +++++++---------------------- tools/perf/ui/hist.c | 25 ------------------------- tools/perf/util/hist.h | 1 - 4 files changed, 7 insertions(+), 52 deletions(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 194f37d635df..5b3123d5721f 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -22,10 +22,6 @@ specified perf.data files. OPTIONS ------- --M:: ---displacement:: - Show position displacement relative to baseline. - -D:: --dump-raw-trace:: Dump raw trace in ASCII. diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index d869029fb75e..b2e7d39f099b 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -23,7 +23,6 @@ static char const *input_old = "perf.data.old", *input_new = "perf.data"; static char diff__default_sort_order[] = "dso,symbol"; static bool force; -static bool show_displacement; static bool show_period; static bool show_formula; static bool show_baseline_only; @@ -296,9 +295,8 @@ static void insert_hist_entry_by_name(struct rb_root *root, rb_insert_color(&he->rb_node, root); } -static void hists__name_resort(struct hists *self, bool sort) +static void hists__name_resort(struct hists *self) { - unsigned long position = 1; struct rb_root tmp = RB_ROOT; struct rb_node *next = rb_first(&self->entries); @@ -306,16 +304,12 @@ static void hists__name_resort(struct hists *self, bool sort) struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - n->position = position++; - if (sort) { - rb_erase(&n->rb_node, &self->entries); - insert_hist_entry_by_name(&tmp, n); - } + rb_erase(&n->rb_node, &self->entries); + insert_hist_entry_by_name(&tmp, n); } - if (sort) - self->entries = tmp; + self->entries = tmp; } static struct perf_evsel *evsel_match(struct perf_evsel *evsel, @@ -339,12 +333,8 @@ static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name) hists__output_resort(hists); - /* - * The hists__name_resort only sets possition - * if name is false. - */ - if (name || ((!name) && show_displacement)) - hists__name_resort(hists, name); + if (name) + hists__name_resort(hists); } } @@ -549,8 +539,6 @@ static const char * const diff_usage[] = { static const struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), - OPT_BOOLEAN('M', "displacement", &show_displacement, - "Show position displacement relative to baseline"), OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, "Show only items with match in baseline"), OPT_CALLBACK('c', "compute", &compute, @@ -585,7 +573,7 @@ static const struct option options[] = { static void ui_init(void) { /* - * Display baseline/delta/ratio/displacement/ + * Display baseline/delta/ratio * formula/periods columns. */ perf_hpp__column_enable(PERF_HPP__BASELINE); @@ -604,9 +592,6 @@ static void ui_init(void) BUG_ON(1); }; - if (show_displacement) - perf_hpp__column_enable(PERF_HPP__DISPL); - if (show_formula) perf_hpp__column_enable(PERF_HPP__FORMULA); diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 1785bab7adfd..1889c12ca81f 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -351,30 +351,6 @@ static int hpp__entry_wdiff(struct perf_hpp *hpp, struct hist_entry *he) return scnprintf(hpp->buf, hpp->size, fmt, buf); } -static int hpp__header_displ(struct perf_hpp *hpp) -{ - return scnprintf(hpp->buf, hpp->size, "Displ."); -} - -static int hpp__width_displ(struct perf_hpp *hpp __maybe_unused) -{ - return 6; -} - -static int hpp__entry_displ(struct perf_hpp *hpp, - struct hist_entry *he) -{ - struct hist_entry *pair = hist_entry__next_pair(he); - long displacement = pair ? pair->position - he->position : 0; - const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s"; - char buf[32] = " "; - - if (displacement) - scnprintf(buf, sizeof(buf), "%+4ld", displacement); - - return scnprintf(hpp->buf, hpp->size, fmt, buf); -} - static int hpp__header_formula(struct perf_hpp *hpp) { const char *fmt = symbol_conf.field_sep ? "%s" : "%70s"; @@ -427,7 +403,6 @@ struct perf_hpp_fmt perf_hpp__format[] = { HPP__PRINT_FNS(delta), HPP__PRINT_FNS(ratio), HPP__PRINT_FNS(wdiff), - HPP__PRINT_FNS(displ), HPP__PRINT_FNS(formula) }; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index c1b2fade8e70..5b3b0075be64 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -154,7 +154,6 @@ enum { PERF_HPP__DELTA, PERF_HPP__RATIO, PERF_HPP__WEIGHTED_DIFF, - PERF_HPP__DISPL, PERF_HPP__FORMULA, PERF_HPP__MAX_INDEX -- cgit v1.2.3 From 4fb71074a570aab9ba8a30b7a756a3c637a14c03 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 22 Jan 2013 18:09:34 +0900 Subject: perf ui/hist: Consolidate hpp helpers Most of hpp helper functions do same jobs for different fields thus consolidate them to appropriate functions/macros. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1358845787-1350-7-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 238 ++++++++++++++++++--------------------------------- 1 file changed, 84 insertions(+), 154 deletions(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 1889c12ca81f..849c40028e7b 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -3,151 +3,107 @@ #include "../util/hist.h" #include "../util/util.h" #include "../util/sort.h" - +#include "../util/evsel.h" /* hist period print (hpp) functions */ -static int hpp__header_overhead(struct perf_hpp *hpp) -{ - return scnprintf(hpp->buf, hpp->size, "Overhead"); -} - -static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused) -{ - return 8; -} - -static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period / hists->stats.total_period; - - return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); -} - -static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period / hists->stats.total_period; - const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%"; - - return scnprintf(hpp->buf, hpp->size, fmt, percent); -} - -static int hpp__header_overhead_sys(struct perf_hpp *hpp) -{ - const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; - - return scnprintf(hpp->buf, hpp->size, fmt, "sys"); -} - -static int hpp__width_overhead_sys(struct perf_hpp *hpp __maybe_unused) -{ - return 7; -} - -static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_sys / hists->stats.total_period; - return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent); -} +typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...); -static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he) +static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, + u64 (*get_field)(struct hist_entry *), + const char *fmt, hpp_snprint_fn print_fn) { + int ret; + double percent = 0.0; struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_sys / hists->stats.total_period; - const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%"; - - return scnprintf(hpp->buf, hpp->size, fmt, percent); -} - -static int hpp__header_overhead_us(struct perf_hpp *hpp) -{ - const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; - return scnprintf(hpp->buf, hpp->size, fmt, "user"); -} + if (hists->stats.total_period) + percent = 100.0 * get_field(he) / hists->stats.total_period; -static int hpp__width_overhead_us(struct perf_hpp *hpp __maybe_unused) -{ - return 7; + ret = print_fn(hpp->buf, hpp->size, fmt, percent); + return ret; } -static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he) +static int __hpp__raw_fmt(struct perf_hpp *hpp, struct hist_entry *he, + u64 (*get_field)(struct hist_entry *), + const char *fmt, hpp_snprint_fn print_fn) { - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_us / hists->stats.total_period; + int ret; - return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent); + ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); + return ret; } -static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_us / hists->stats.total_period; - const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%"; - return scnprintf(hpp->buf, hpp->size, fmt, percent); +#define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ +static int hpp__header_##_type(struct perf_hpp *hpp) \ +{ \ + int len = _min_width; \ + \ + return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ } -static int hpp__header_overhead_guest_sys(struct perf_hpp *hpp) -{ - return scnprintf(hpp->buf, hpp->size, "guest sys"); +#define __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ +static int hpp__width_##_type(struct perf_hpp *hpp __maybe_unused) \ +{ \ + int len = _min_width; \ + \ + return len; \ } -static int hpp__width_overhead_guest_sys(struct perf_hpp *hpp __maybe_unused) -{ - return 9; +#define __HPP_COLOR_PERCENT_FN(_type, _field) \ +static u64 he_get_##_field(struct hist_entry *he) \ +{ \ + return he->stat._field; \ +} \ + \ +static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ +{ \ + return __hpp__percent_fmt(hpp, he, he_get_##_field, " %6.2f%%", \ + (hpp_snprint_fn)percent_color_snprintf); \ } -static int hpp__color_overhead_guest_sys(struct perf_hpp *hpp, - struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_guest_sys / hists->stats.total_period; - - return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent); +#define __HPP_ENTRY_PERCENT_FN(_type, _field) \ +static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ +{ \ + const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ + return __hpp__percent_fmt(hpp, he, he_get_##_field, fmt, \ + scnprintf); \ } -static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp, - struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_guest_sys / hists->stats.total_period; - const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% "; - - return scnprintf(hpp->buf, hpp->size, fmt, percent); +#define __HPP_ENTRY_RAW_FN(_type, _field) \ +static u64 he_get_raw_##_field(struct hist_entry *he) \ +{ \ + return he->stat._field; \ +} \ + \ +static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ +{ \ + const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ + return __hpp__raw_fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf); \ } -static int hpp__header_overhead_guest_us(struct perf_hpp *hpp) -{ - return scnprintf(hpp->buf, hpp->size, "guest usr"); -} +#define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ +__HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ +__HPP_WIDTH_FN(_type, _min_width, _unit_width) \ +__HPP_COLOR_PERCENT_FN(_type, _field) \ +__HPP_ENTRY_PERCENT_FN(_type, _field) -static int hpp__width_overhead_guest_us(struct perf_hpp *hpp __maybe_unused) -{ - return 9; -} +#define HPP_RAW_FNS(_type, _str, _field, _min_width, _unit_width) \ +__HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ +__HPP_WIDTH_FN(_type, _min_width, _unit_width) \ +__HPP_ENTRY_RAW_FN(_type, _field) -static int hpp__color_overhead_guest_us(struct perf_hpp *hpp, - struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_guest_us / hists->stats.total_period; - return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent); -} +HPP_PERCENT_FNS(overhead, "Overhead", period, 8, 8) +HPP_PERCENT_FNS(overhead_sys, "sys", period_sys, 8, 8) +HPP_PERCENT_FNS(overhead_us, "usr", period_us, 8, 8) +HPP_PERCENT_FNS(overhead_guest_sys, "guest sys", period_guest_sys, 9, 8) +HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us, 9, 8) -static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp, - struct hist_entry *he) -{ - struct hists *hists = he->hists; - double percent = 100.0 * he->stat.period_guest_us / hists->stats.total_period; - const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% "; +HPP_RAW_FNS(samples, "Samples", nr_events, 12, 12) +HPP_RAW_FNS(period, "Period", period, 12, 12) - return scnprintf(hpp->buf, hpp->size, fmt, percent); -} static int hpp__header_baseline(struct perf_hpp *hpp) { @@ -179,7 +135,7 @@ static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he) { double percent = baseline_percent(he); - if (hist_entry__has_pairs(he)) + if (hist_entry__has_pairs(he) || symbol_conf.field_sep) return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); else return scnprintf(hpp->buf, hpp->size, " "); @@ -196,44 +152,6 @@ static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he) return scnprintf(hpp->buf, hpp->size, " "); } -static int hpp__header_samples(struct perf_hpp *hpp) -{ - const char *fmt = symbol_conf.field_sep ? "%s" : "%11s"; - - return scnprintf(hpp->buf, hpp->size, fmt, "Samples"); -} - -static int hpp__width_samples(struct perf_hpp *hpp __maybe_unused) -{ - return 11; -} - -static int hpp__entry_samples(struct perf_hpp *hpp, struct hist_entry *he) -{ - const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%11" PRIu64; - - return scnprintf(hpp->buf, hpp->size, fmt, he->stat.nr_events); -} - -static int hpp__header_period(struct perf_hpp *hpp) -{ - const char *fmt = symbol_conf.field_sep ? "%s" : "%12s"; - - return scnprintf(hpp->buf, hpp->size, fmt, "Period"); -} - -static int hpp__width_period(struct perf_hpp *hpp __maybe_unused) -{ - return 12; -} - -static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he) -{ - const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64; - - return scnprintf(hpp->buf, hpp->size, fmt, he->stat.period); -} - static int hpp__header_period_baseline(struct perf_hpp *hpp) { const char *fmt = symbol_conf.field_sep ? "%s" : "%12s"; @@ -254,6 +172,7 @@ static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *h return scnprintf(hpp->buf, hpp->size, fmt, period); } + static int hpp__header_delta(struct perf_hpp *hpp) { const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; @@ -408,9 +327,20 @@ struct perf_hpp_fmt perf_hpp__format[] = { LIST_HEAD(perf_hpp__list); + #undef HPP__COLOR_PRINT_FNS #undef HPP__PRINT_FNS +#undef HPP_PERCENT_FNS +#undef HPP_RAW_FNS + +#undef __HPP_HEADER_FN +#undef __HPP_WIDTH_FN +#undef __HPP_COLOR_PERCENT_FN +#undef __HPP_ENTRY_PERCENT_FN +#undef __HPP_ENTRY_RAW_FN + + void perf_hpp__init(void) { if (symbol_conf.show_cpu_utilization) { -- cgit v1.2.3 From 5b9e2146ec4f8c6d436f9f7043a0409a4296a705 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 22 Jan 2013 18:09:37 +0900 Subject: perf ui/hist: Add support for event group view Show group member's overhead also when showing the leader's if event group is enabled. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1358845787-1350-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 62 +++++++++++++++++++++++++++++++++++++++++++++- tools/perf/ui/stdio/hist.c | 2 ++ 2 files changed, 63 insertions(+), 1 deletion(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 849c40028e7b..a47ce98c2cb1 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -21,6 +21,53 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, percent = 100.0 * get_field(he) / hists->stats.total_period; ret = print_fn(hpp->buf, hpp->size, fmt, percent); + + if (symbol_conf.event_group) { + int prev_idx, idx_delta; + struct perf_evsel *evsel = hists_to_evsel(hists); + struct hist_entry *pair; + int nr_members = evsel->nr_members; + + if (nr_members <= 1) + return ret; + + prev_idx = perf_evsel__group_idx(evsel); + + list_for_each_entry(pair, &he->pairs.head, pairs.node) { + u64 period = get_field(pair); + u64 total = pair->hists->stats.total_period; + + if (!total) + continue; + + evsel = hists_to_evsel(pair->hists); + idx_delta = perf_evsel__group_idx(evsel) - prev_idx - 1; + + while (idx_delta--) { + /* + * zero-fill group members in the middle which + * have no sample + */ + ret += print_fn(hpp->buf + ret, hpp->size - ret, + fmt, 0.0); + } + + ret += print_fn(hpp->buf + ret, hpp->size - ret, + fmt, 100.0 * period / total); + + prev_idx = perf_evsel__group_idx(evsel); + } + + idx_delta = nr_members - prev_idx - 1; + + while (idx_delta--) { + /* + * zero-fill group members at last which have no sample + */ + ret += print_fn(hpp->buf + ret, hpp->size - ret, + fmt, 0.0); + } + } return ret; } @@ -40,6 +87,11 @@ static int hpp__header_##_type(struct perf_hpp *hpp) \ { \ int len = _min_width; \ \ + if (symbol_conf.event_group) { \ + struct perf_evsel *evsel = hpp->ptr; \ + \ + len = max(len, evsel->nr_members * _unit_width); \ + } \ return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ } @@ -48,6 +100,11 @@ static int hpp__width_##_type(struct perf_hpp *hpp __maybe_unused) \ { \ int len = _min_width; \ \ + if (symbol_conf.event_group) { \ + struct perf_evsel *evsel = hpp->ptr; \ + \ + len = max(len, evsel->nr_members * _unit_width); \ + } \ return len; \ } @@ -438,12 +495,15 @@ unsigned int hists__sort_list_width(struct hists *hists) struct perf_hpp_fmt *fmt; struct sort_entry *se; int i = 0, ret = 0; + struct perf_hpp dummy_hpp = { + .ptr = hists_to_evsel(hists), + }; perf_hpp__for_each_format(fmt) { if (i) ret += 2; - ret += fmt->width(NULL); + ret += fmt->width(&dummy_hpp); } list_for_each_entry(se, &hist_entry__sort_list, list) diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index f9798298e3e0..ff1f60cf442e 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -3,6 +3,7 @@ #include "../../util/util.h" #include "../../util/hist.h" #include "../../util/sort.h" +#include "../../util/evsel.h" static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) @@ -347,6 +348,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, struct perf_hpp dummy_hpp = { .buf = bf, .size = sizeof(bf), + .ptr = hists_to_evsel(hists), }; bool first = true; -- cgit v1.2.3 From 0c5268bf2218144469dde3228f14898fadbbcdcd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 4 Feb 2013 13:32:55 +0100 Subject: perf hists browser: Add support to display whole group data for raw columns Currently we don't display group members' values for raw columns like 'Samples' and 'Period' when in group report mode. Uniting '__hpp__percent_fmt' and '__hpp__raw_fmt' function under new function __hpp__fmt. It's basically '__hpp__percent_fmt' code with new 'fmt_percent' bool parameter added saying whether raw number or percentage should be printed. This way raw columns print out all the group members when in group report mode, like: $ perf record -e '{cycles,cache-misses}' ls ... $ perf report --group --show-total-period --stdio ... # Overhead Period Command Shared Object Symbol # ................ ........................ ....... ................. ................................. # 23.63% 11.24% 3331335 317 ls [kernel.kallsyms] [k] __lock_acquire 12.72% 0.00% 1793100 0 ls [kernel.kallsyms] [k] native_sched_clock 9.72% 0.00% 1369920 0 ls libc-2.14.90.so [.] _nl_find_locale 0.03% 0.07% 4476 2 ls [kernel.kallsyms] [k] intel_pmu_enable_all 0.00% 11.73% 0 331 ls ld-2.14.90.so [.] _dl_cache_libcmp 0.00% 11.06% 0 312 ls [kernel.kallsyms] [k] vma_interval_tree_insert Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1359981185-16819-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 53 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'tools/perf/ui/hist.c') diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index a47ce98c2cb1..d671e63aa351 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -9,18 +9,24 @@ typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...); -static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, - u64 (*get_field)(struct hist_entry *), - const char *fmt, hpp_snprint_fn print_fn) +static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, + u64 (*get_field)(struct hist_entry *), + const char *fmt, hpp_snprint_fn print_fn, + bool fmt_percent) { int ret; - double percent = 0.0; struct hists *hists = he->hists; - if (hists->stats.total_period) - percent = 100.0 * get_field(he) / hists->stats.total_period; + if (fmt_percent) { + double percent = 0.0; + + if (hists->stats.total_period) + percent = 100.0 * get_field(he) / + hists->stats.total_period; - ret = print_fn(hpp->buf, hpp->size, fmt, percent); + ret = print_fn(hpp->buf, hpp->size, fmt, percent); + } else + ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); if (symbol_conf.event_group) { int prev_idx, idx_delta; @@ -49,11 +55,15 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, * have no sample */ ret += print_fn(hpp->buf + ret, hpp->size - ret, - fmt, 0.0); + fmt, 0); } - ret += print_fn(hpp->buf + ret, hpp->size - ret, - fmt, 100.0 * period / total); + if (fmt_percent) + ret += print_fn(hpp->buf + ret, hpp->size - ret, + fmt, 100.0 * period / total); + else + ret += print_fn(hpp->buf + ret, hpp->size - ret, + fmt, period); prev_idx = perf_evsel__group_idx(evsel); } @@ -65,23 +75,12 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, * zero-fill group members at last which have no sample */ ret += print_fn(hpp->buf + ret, hpp->size - ret, - fmt, 0.0); + fmt, 0); } } return ret; } -static int __hpp__raw_fmt(struct perf_hpp *hpp, struct hist_entry *he, - u64 (*get_field)(struct hist_entry *), - const char *fmt, hpp_snprint_fn print_fn) -{ - int ret; - - ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); - return ret; -} - - #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ static int hpp__header_##_type(struct perf_hpp *hpp) \ { \ @@ -116,16 +115,16 @@ static u64 he_get_##_field(struct hist_entry *he) \ \ static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ { \ - return __hpp__percent_fmt(hpp, he, he_get_##_field, " %6.2f%%", \ - (hpp_snprint_fn)percent_color_snprintf); \ + return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ + (hpp_snprint_fn)percent_color_snprintf, true); \ } #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ { \ const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ - return __hpp__percent_fmt(hpp, he, he_get_##_field, fmt, \ - scnprintf); \ + return __hpp__fmt(hpp, he, he_get_##_field, fmt, \ + scnprintf, true); \ } #define __HPP_ENTRY_RAW_FN(_type, _field) \ @@ -137,7 +136,7 @@ static u64 he_get_raw_##_field(struct hist_entry *he) \ static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ { \ const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ - return __hpp__raw_fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf); \ + return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf, false); \ } #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ -- cgit v1.2.3