diff options
author | Jiri Olsa <jolsa@redhat.com> | 2013-02-04 07:32:55 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-02-06 16:09:27 -0500 |
commit | 0c5268bf2218144469dde3228f14898fadbbcdcd (patch) | |
tree | 311e06f63a91f927a424d3f045586717873ee2c1 /tools/perf | |
parent | d7e7a451c13e784f497c054f1bd083d77be87498 (diff) |
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 <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
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/r/1359981185-16819-2-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/ui/hist.c | 53 |
1 files changed, 26 insertions, 27 deletions
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 @@ | |||
9 | 9 | ||
10 | typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...); | 10 | typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...); |
11 | 11 | ||
12 | static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, | 12 | static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, |
13 | u64 (*get_field)(struct hist_entry *), | 13 | u64 (*get_field)(struct hist_entry *), |
14 | const char *fmt, hpp_snprint_fn print_fn) | 14 | const char *fmt, hpp_snprint_fn print_fn, |
15 | bool fmt_percent) | ||
15 | { | 16 | { |
16 | int ret; | 17 | int ret; |
17 | double percent = 0.0; | ||
18 | struct hists *hists = he->hists; | 18 | struct hists *hists = he->hists; |
19 | 19 | ||
20 | if (hists->stats.total_period) | 20 | if (fmt_percent) { |
21 | percent = 100.0 * get_field(he) / hists->stats.total_period; | 21 | double percent = 0.0; |
22 | |||
23 | if (hists->stats.total_period) | ||
24 | percent = 100.0 * get_field(he) / | ||
25 | hists->stats.total_period; | ||
22 | 26 | ||
23 | ret = print_fn(hpp->buf, hpp->size, fmt, percent); | 27 | ret = print_fn(hpp->buf, hpp->size, fmt, percent); |
28 | } else | ||
29 | ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); | ||
24 | 30 | ||
25 | if (symbol_conf.event_group) { | 31 | if (symbol_conf.event_group) { |
26 | int prev_idx, idx_delta; | 32 | int prev_idx, idx_delta; |
@@ -49,11 +55,15 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, | |||
49 | * have no sample | 55 | * have no sample |
50 | */ | 56 | */ |
51 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 57 | ret += print_fn(hpp->buf + ret, hpp->size - ret, |
52 | fmt, 0.0); | 58 | fmt, 0); |
53 | } | 59 | } |
54 | 60 | ||
55 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 61 | if (fmt_percent) |
56 | fmt, 100.0 * period / total); | 62 | ret += print_fn(hpp->buf + ret, hpp->size - ret, |
63 | fmt, 100.0 * period / total); | ||
64 | else | ||
65 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | ||
66 | fmt, period); | ||
57 | 67 | ||
58 | prev_idx = perf_evsel__group_idx(evsel); | 68 | prev_idx = perf_evsel__group_idx(evsel); |
59 | } | 69 | } |
@@ -65,23 +75,12 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, | |||
65 | * zero-fill group members at last which have no sample | 75 | * zero-fill group members at last which have no sample |
66 | */ | 76 | */ |
67 | ret += print_fn(hpp->buf + ret, hpp->size - ret, | 77 | ret += print_fn(hpp->buf + ret, hpp->size - ret, |
68 | fmt, 0.0); | 78 | fmt, 0); |
69 | } | 79 | } |
70 | } | 80 | } |
71 | return ret; | 81 | return ret; |
72 | } | 82 | } |
73 | 83 | ||
74 | static int __hpp__raw_fmt(struct perf_hpp *hpp, struct hist_entry *he, | ||
75 | u64 (*get_field)(struct hist_entry *), | ||
76 | const char *fmt, hpp_snprint_fn print_fn) | ||
77 | { | ||
78 | int ret; | ||
79 | |||
80 | ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | |||
85 | #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ | 84 | #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ |
86 | static int hpp__header_##_type(struct perf_hpp *hpp) \ | 85 | static int hpp__header_##_type(struct perf_hpp *hpp) \ |
87 | { \ | 86 | { \ |
@@ -116,16 +115,16 @@ static u64 he_get_##_field(struct hist_entry *he) \ | |||
116 | \ | 115 | \ |
117 | static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ | 116 | static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ |
118 | { \ | 117 | { \ |
119 | return __hpp__percent_fmt(hpp, he, he_get_##_field, " %6.2f%%", \ | 118 | return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ |
120 | (hpp_snprint_fn)percent_color_snprintf); \ | 119 | (hpp_snprint_fn)percent_color_snprintf, true); \ |
121 | } | 120 | } |
122 | 121 | ||
123 | #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ | 122 | #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ |
124 | static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ | 123 | static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ |
125 | { \ | 124 | { \ |
126 | const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ | 125 | const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ |
127 | return __hpp__percent_fmt(hpp, he, he_get_##_field, fmt, \ | 126 | return __hpp__fmt(hpp, he, he_get_##_field, fmt, \ |
128 | scnprintf); \ | 127 | scnprintf, true); \ |
129 | } | 128 | } |
130 | 129 | ||
131 | #define __HPP_ENTRY_RAW_FN(_type, _field) \ | 130 | #define __HPP_ENTRY_RAW_FN(_type, _field) \ |
@@ -137,7 +136,7 @@ static u64 he_get_raw_##_field(struct hist_entry *he) \ | |||
137 | static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ | 136 | static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ |
138 | { \ | 137 | { \ |
139 | const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ | 138 | const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ |
140 | return __hpp__raw_fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf); \ | 139 | return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf, false); \ |
141 | } | 140 | } |
142 | 141 | ||
143 | #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ | 142 | #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ |