diff options
Diffstat (limited to 'tools/perf/ui/hist.c')
-rw-r--r-- | tools/perf/ui/hist.c | 238 |
1 files changed, 84 insertions, 154 deletions
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 @@ | |||
3 | #include "../util/hist.h" | 3 | #include "../util/hist.h" |
4 | #include "../util/util.h" | 4 | #include "../util/util.h" |
5 | #include "../util/sort.h" | 5 | #include "../util/sort.h" |
6 | 6 | #include "../util/evsel.h" | |
7 | 7 | ||
8 | /* hist period print (hpp) functions */ | 8 | /* hist period print (hpp) functions */ |
9 | static int hpp__header_overhead(struct perf_hpp *hpp) | ||
10 | { | ||
11 | return scnprintf(hpp->buf, hpp->size, "Overhead"); | ||
12 | } | ||
13 | |||
14 | static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused) | ||
15 | { | ||
16 | return 8; | ||
17 | } | ||
18 | |||
19 | static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he) | ||
20 | { | ||
21 | struct hists *hists = he->hists; | ||
22 | double percent = 100.0 * he->stat.period / hists->stats.total_period; | ||
23 | |||
24 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); | ||
25 | } | ||
26 | |||
27 | static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he) | ||
28 | { | ||
29 | struct hists *hists = he->hists; | ||
30 | double percent = 100.0 * he->stat.period / hists->stats.total_period; | ||
31 | const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%"; | ||
32 | |||
33 | return scnprintf(hpp->buf, hpp->size, fmt, percent); | ||
34 | } | ||
35 | |||
36 | static int hpp__header_overhead_sys(struct perf_hpp *hpp) | ||
37 | { | ||
38 | const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; | ||
39 | |||
40 | return scnprintf(hpp->buf, hpp->size, fmt, "sys"); | ||
41 | } | ||
42 | |||
43 | static int hpp__width_overhead_sys(struct perf_hpp *hpp __maybe_unused) | ||
44 | { | ||
45 | return 7; | ||
46 | } | ||
47 | |||
48 | static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he) | ||
49 | { | ||
50 | struct hists *hists = he->hists; | ||
51 | double percent = 100.0 * he->stat.period_sys / hists->stats.total_period; | ||
52 | 9 | ||
53 | return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent); | 10 | typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...); |
54 | } | ||
55 | 11 | ||
56 | static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he) | 12 | static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he, |
13 | u64 (*get_field)(struct hist_entry *), | ||
14 | const char *fmt, hpp_snprint_fn print_fn) | ||
57 | { | 15 | { |
16 | int ret; | ||
17 | double percent = 0.0; | ||
58 | struct hists *hists = he->hists; | 18 | struct hists *hists = he->hists; |
59 | double percent = 100.0 * he->stat.period_sys / hists->stats.total_period; | ||
60 | const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%"; | ||
61 | |||
62 | return scnprintf(hpp->buf, hpp->size, fmt, percent); | ||
63 | } | ||
64 | |||
65 | static int hpp__header_overhead_us(struct perf_hpp *hpp) | ||
66 | { | ||
67 | const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; | ||
68 | 19 | ||
69 | return scnprintf(hpp->buf, hpp->size, fmt, "user"); | 20 | if (hists->stats.total_period) |
70 | } | 21 | percent = 100.0 * get_field(he) / hists->stats.total_period; |
71 | 22 | ||
72 | static int hpp__width_overhead_us(struct perf_hpp *hpp __maybe_unused) | 23 | ret = print_fn(hpp->buf, hpp->size, fmt, percent); |
73 | { | 24 | return ret; |
74 | return 7; | ||
75 | } | 25 | } |
76 | 26 | ||
77 | static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he) | 27 | static int __hpp__raw_fmt(struct perf_hpp *hpp, struct hist_entry *he, |
28 | u64 (*get_field)(struct hist_entry *), | ||
29 | const char *fmt, hpp_snprint_fn print_fn) | ||
78 | { | 30 | { |
79 | struct hists *hists = he->hists; | 31 | int ret; |
80 | double percent = 100.0 * he->stat.period_us / hists->stats.total_period; | ||
81 | 32 | ||
82 | return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent); | 33 | ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he)); |
34 | return ret; | ||
83 | } | 35 | } |
84 | 36 | ||
85 | static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he) | ||
86 | { | ||
87 | struct hists *hists = he->hists; | ||
88 | double percent = 100.0 * he->stat.period_us / hists->stats.total_period; | ||
89 | const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%"; | ||
90 | 37 | ||
91 | return scnprintf(hpp->buf, hpp->size, fmt, percent); | 38 | #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ |
39 | static int hpp__header_##_type(struct perf_hpp *hpp) \ | ||
40 | { \ | ||
41 | int len = _min_width; \ | ||
42 | \ | ||
43 | return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ | ||
92 | } | 44 | } |
93 | 45 | ||
94 | static int hpp__header_overhead_guest_sys(struct perf_hpp *hpp) | 46 | #define __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ |
95 | { | 47 | static int hpp__width_##_type(struct perf_hpp *hpp __maybe_unused) \ |
96 | return scnprintf(hpp->buf, hpp->size, "guest sys"); | 48 | { \ |
49 | int len = _min_width; \ | ||
50 | \ | ||
51 | return len; \ | ||
97 | } | 52 | } |
98 | 53 | ||
99 | static int hpp__width_overhead_guest_sys(struct perf_hpp *hpp __maybe_unused) | 54 | #define __HPP_COLOR_PERCENT_FN(_type, _field) \ |
100 | { | 55 | static u64 he_get_##_field(struct hist_entry *he) \ |
101 | return 9; | 56 | { \ |
57 | return he->stat._field; \ | ||
58 | } \ | ||
59 | \ | ||
60 | static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ | ||
61 | { \ | ||
62 | return __hpp__percent_fmt(hpp, he, he_get_##_field, " %6.2f%%", \ | ||
63 | (hpp_snprint_fn)percent_color_snprintf); \ | ||
102 | } | 64 | } |
103 | 65 | ||
104 | static int hpp__color_overhead_guest_sys(struct perf_hpp *hpp, | 66 | #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ |
105 | struct hist_entry *he) | 67 | static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ |
106 | { | 68 | { \ |
107 | struct hists *hists = he->hists; | 69 | const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ |
108 | double percent = 100.0 * he->stat.period_guest_sys / hists->stats.total_period; | 70 | return __hpp__percent_fmt(hpp, he, he_get_##_field, fmt, \ |
109 | 71 | scnprintf); \ | |
110 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent); | ||
111 | } | 72 | } |
112 | 73 | ||
113 | static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp, | 74 | #define __HPP_ENTRY_RAW_FN(_type, _field) \ |
114 | struct hist_entry *he) | 75 | static u64 he_get_raw_##_field(struct hist_entry *he) \ |
115 | { | 76 | { \ |
116 | struct hists *hists = he->hists; | 77 | return he->stat._field; \ |
117 | double percent = 100.0 * he->stat.period_guest_sys / hists->stats.total_period; | 78 | } \ |
118 | const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% "; | 79 | \ |
119 | 80 | static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) \ | |
120 | return scnprintf(hpp->buf, hpp->size, fmt, percent); | 81 | { \ |
82 | const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ | ||
83 | return __hpp__raw_fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf); \ | ||
121 | } | 84 | } |
122 | 85 | ||
123 | static int hpp__header_overhead_guest_us(struct perf_hpp *hpp) | 86 | #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ |
124 | { | 87 | __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ |
125 | return scnprintf(hpp->buf, hpp->size, "guest usr"); | 88 | __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ |
126 | } | 89 | __HPP_COLOR_PERCENT_FN(_type, _field) \ |
90 | __HPP_ENTRY_PERCENT_FN(_type, _field) | ||
127 | 91 | ||
128 | static int hpp__width_overhead_guest_us(struct perf_hpp *hpp __maybe_unused) | 92 | #define HPP_RAW_FNS(_type, _str, _field, _min_width, _unit_width) \ |
129 | { | 93 | __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ |
130 | return 9; | 94 | __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ |
131 | } | 95 | __HPP_ENTRY_RAW_FN(_type, _field) |
132 | 96 | ||
133 | static int hpp__color_overhead_guest_us(struct perf_hpp *hpp, | ||
134 | struct hist_entry *he) | ||
135 | { | ||
136 | struct hists *hists = he->hists; | ||
137 | double percent = 100.0 * he->stat.period_guest_us / hists->stats.total_period; | ||
138 | 97 | ||
139 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent); | 98 | HPP_PERCENT_FNS(overhead, "Overhead", period, 8, 8) |
140 | } | 99 | HPP_PERCENT_FNS(overhead_sys, "sys", period_sys, 8, 8) |
100 | HPP_PERCENT_FNS(overhead_us, "usr", period_us, 8, 8) | ||
101 | HPP_PERCENT_FNS(overhead_guest_sys, "guest sys", period_guest_sys, 9, 8) | ||
102 | HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us, 9, 8) | ||
141 | 103 | ||
142 | static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp, | 104 | HPP_RAW_FNS(samples, "Samples", nr_events, 12, 12) |
143 | struct hist_entry *he) | 105 | HPP_RAW_FNS(period, "Period", period, 12, 12) |
144 | { | ||
145 | struct hists *hists = he->hists; | ||
146 | double percent = 100.0 * he->stat.period_guest_us / hists->stats.total_period; | ||
147 | const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% "; | ||
148 | 106 | ||
149 | return scnprintf(hpp->buf, hpp->size, fmt, percent); | ||
150 | } | ||
151 | 107 | ||
152 | static int hpp__header_baseline(struct perf_hpp *hpp) | 108 | static int hpp__header_baseline(struct perf_hpp *hpp) |
153 | { | 109 | { |
@@ -179,7 +135,7 @@ static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he) | |||
179 | { | 135 | { |
180 | double percent = baseline_percent(he); | 136 | double percent = baseline_percent(he); |
181 | 137 | ||
182 | if (hist_entry__has_pairs(he)) | 138 | if (hist_entry__has_pairs(he) || symbol_conf.field_sep) |
183 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); | 139 | return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); |
184 | else | 140 | else |
185 | return scnprintf(hpp->buf, hpp->size, " "); | 141 | return scnprintf(hpp->buf, hpp->size, " "); |
@@ -196,44 +152,6 @@ static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he) | |||
196 | return scnprintf(hpp->buf, hpp->size, " "); | 152 | return scnprintf(hpp->buf, hpp->size, " "); |
197 | } | 153 | } |
198 | 154 | ||
199 | static int hpp__header_samples(struct perf_hpp *hpp) | ||
200 | { | ||
201 | const char *fmt = symbol_conf.field_sep ? "%s" : "%11s"; | ||
202 | |||
203 | return scnprintf(hpp->buf, hpp->size, fmt, "Samples"); | ||
204 | } | ||
205 | |||
206 | static int hpp__width_samples(struct perf_hpp *hpp __maybe_unused) | ||
207 | { | ||
208 | return 11; | ||
209 | } | ||
210 | |||
211 | static int hpp__entry_samples(struct perf_hpp *hpp, struct hist_entry *he) | ||
212 | { | ||
213 | const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%11" PRIu64; | ||
214 | |||
215 | return scnprintf(hpp->buf, hpp->size, fmt, he->stat.nr_events); | ||
216 | } | ||
217 | |||
218 | static int hpp__header_period(struct perf_hpp *hpp) | ||
219 | { | ||
220 | const char *fmt = symbol_conf.field_sep ? "%s" : "%12s"; | ||
221 | |||
222 | return scnprintf(hpp->buf, hpp->size, fmt, "Period"); | ||
223 | } | ||
224 | |||
225 | static int hpp__width_period(struct perf_hpp *hpp __maybe_unused) | ||
226 | { | ||
227 | return 12; | ||
228 | } | ||
229 | |||
230 | static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he) | ||
231 | { | ||
232 | const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64; | ||
233 | |||
234 | return scnprintf(hpp->buf, hpp->size, fmt, he->stat.period); | ||
235 | } | ||
236 | |||
237 | static int hpp__header_period_baseline(struct perf_hpp *hpp) | 155 | static int hpp__header_period_baseline(struct perf_hpp *hpp) |
238 | { | 156 | { |
239 | const char *fmt = symbol_conf.field_sep ? "%s" : "%12s"; | 157 | 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 | |||
254 | 172 | ||
255 | return scnprintf(hpp->buf, hpp->size, fmt, period); | 173 | return scnprintf(hpp->buf, hpp->size, fmt, period); |
256 | } | 174 | } |
175 | |||
257 | static int hpp__header_delta(struct perf_hpp *hpp) | 176 | static int hpp__header_delta(struct perf_hpp *hpp) |
258 | { | 177 | { |
259 | const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; | 178 | const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; |
@@ -408,9 +327,20 @@ struct perf_hpp_fmt perf_hpp__format[] = { | |||
408 | 327 | ||
409 | LIST_HEAD(perf_hpp__list); | 328 | LIST_HEAD(perf_hpp__list); |
410 | 329 | ||
330 | |||
411 | #undef HPP__COLOR_PRINT_FNS | 331 | #undef HPP__COLOR_PRINT_FNS |
412 | #undef HPP__PRINT_FNS | 332 | #undef HPP__PRINT_FNS |
413 | 333 | ||
334 | #undef HPP_PERCENT_FNS | ||
335 | #undef HPP_RAW_FNS | ||
336 | |||
337 | #undef __HPP_HEADER_FN | ||
338 | #undef __HPP_WIDTH_FN | ||
339 | #undef __HPP_COLOR_PERCENT_FN | ||
340 | #undef __HPP_ENTRY_PERCENT_FN | ||
341 | #undef __HPP_ENTRY_RAW_FN | ||
342 | |||
343 | |||
414 | void perf_hpp__init(void) | 344 | void perf_hpp__init(void) |
415 | { | 345 | { |
416 | if (symbol_conf.show_cpu_utilization) { | 346 | if (symbol_conf.show_cpu_utilization) { |