xref: /openbmc/linux/tools/perf/ui/hist.c (revision a2ce067e55e328f1a6fe3dddf77a173381ffdfe1)
1ea251d51SNamhyung Kim #include <math.h>
22c5d4b4aSJiri Olsa #include <linux/compiler.h>
3ea251d51SNamhyung Kim 
4ea251d51SNamhyung Kim #include "../util/hist.h"
5ea251d51SNamhyung Kim #include "../util/util.h"
6ea251d51SNamhyung Kim #include "../util/sort.h"
74fb71074SNamhyung Kim #include "../util/evsel.h"
8ea251d51SNamhyung Kim 
9ea251d51SNamhyung Kim /* hist period print (hpp) functions */
10ea251d51SNamhyung Kim 
11a0088adcSNamhyung Kim #define hpp__call_print_fn(hpp, fn, fmt, ...)			\
12a0088adcSNamhyung Kim ({								\
13a0088adcSNamhyung Kim 	int __ret = fn(hpp, fmt, ##__VA_ARGS__);		\
14a0088adcSNamhyung Kim 	advance_hpp(hpp, __ret);				\
15a0088adcSNamhyung Kim 	__ret;							\
16a0088adcSNamhyung Kim })
17a0088adcSNamhyung Kim 
184a62109fSNamhyung Kim int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
19fb821c9eSNamhyung Kim 	       hpp_field_fn get_field, const char *fmt,
20fb821c9eSNamhyung Kim 	       hpp_snprint_fn print_fn, bool fmt_percent)
21ea251d51SNamhyung Kim {
22fb821c9eSNamhyung Kim 	int ret;
23b5ff71c3SJiri Olsa 	struct hists *hists = he->hists;
24759ff497SNamhyung Kim 	struct perf_evsel *evsel = hists_to_evsel(hists);
25a0088adcSNamhyung Kim 	char *buf = hpp->buf;
26a0088adcSNamhyung Kim 	size_t size = hpp->size;
27ea251d51SNamhyung Kim 
280c5268bfSJiri Olsa 	if (fmt_percent) {
290c5268bfSJiri Olsa 		double percent = 0.0;
30f2148330SNamhyung Kim 		u64 total = hists__total_period(hists);
310c5268bfSJiri Olsa 
32f2148330SNamhyung Kim 		if (total)
33f2148330SNamhyung Kim 			percent = 100.0 * get_field(he) / total;
344fb71074SNamhyung Kim 
35fb821c9eSNamhyung Kim 		ret = hpp__call_print_fn(hpp, print_fn, fmt, percent);
360c5268bfSJiri Olsa 	} else
37fb821c9eSNamhyung Kim 		ret = hpp__call_print_fn(hpp, print_fn, fmt, get_field(he));
385b9e2146SNamhyung Kim 
39759ff497SNamhyung Kim 	if (perf_evsel__is_group_event(evsel)) {
405b9e2146SNamhyung Kim 		int prev_idx, idx_delta;
415b9e2146SNamhyung Kim 		struct hist_entry *pair;
425b9e2146SNamhyung Kim 		int nr_members = evsel->nr_members;
435b9e2146SNamhyung Kim 
445b9e2146SNamhyung Kim 		prev_idx = perf_evsel__group_idx(evsel);
455b9e2146SNamhyung Kim 
465b9e2146SNamhyung Kim 		list_for_each_entry(pair, &he->pairs.head, pairs.node) {
475b9e2146SNamhyung Kim 			u64 period = get_field(pair);
48f2148330SNamhyung Kim 			u64 total = hists__total_period(pair->hists);
495b9e2146SNamhyung Kim 
505b9e2146SNamhyung Kim 			if (!total)
515b9e2146SNamhyung Kim 				continue;
525b9e2146SNamhyung Kim 
535b9e2146SNamhyung Kim 			evsel = hists_to_evsel(pair->hists);
545b9e2146SNamhyung Kim 			idx_delta = perf_evsel__group_idx(evsel) - prev_idx - 1;
555b9e2146SNamhyung Kim 
565b9e2146SNamhyung Kim 			while (idx_delta--) {
575b9e2146SNamhyung Kim 				/*
585b9e2146SNamhyung Kim 				 * zero-fill group members in the middle which
595b9e2146SNamhyung Kim 				 * have no sample
605b9e2146SNamhyung Kim 				 */
619b0d2fb8SNamhyung Kim 				if (fmt_percent) {
62a0088adcSNamhyung Kim 					ret += hpp__call_print_fn(hpp, print_fn,
639b0d2fb8SNamhyung Kim 								  fmt, 0.0);
649b0d2fb8SNamhyung Kim 				} else {
65a0088adcSNamhyung Kim 					ret += hpp__call_print_fn(hpp, print_fn,
669b0d2fb8SNamhyung Kim 								  fmt, 0ULL);
679b0d2fb8SNamhyung Kim 				}
685b9e2146SNamhyung Kim 			}
695b9e2146SNamhyung Kim 
70a0088adcSNamhyung Kim 			if (fmt_percent) {
71a0088adcSNamhyung Kim 				ret += hpp__call_print_fn(hpp, print_fn, fmt,
72a0088adcSNamhyung Kim 							  100.0 * period / total);
73a0088adcSNamhyung Kim 			} else {
74a0088adcSNamhyung Kim 				ret += hpp__call_print_fn(hpp, print_fn, fmt,
75a0088adcSNamhyung Kim 							  period);
76a0088adcSNamhyung Kim 			}
775b9e2146SNamhyung Kim 
785b9e2146SNamhyung Kim 			prev_idx = perf_evsel__group_idx(evsel);
795b9e2146SNamhyung Kim 		}
805b9e2146SNamhyung Kim 
815b9e2146SNamhyung Kim 		idx_delta = nr_members - prev_idx - 1;
825b9e2146SNamhyung Kim 
835b9e2146SNamhyung Kim 		while (idx_delta--) {
845b9e2146SNamhyung Kim 			/*
855b9e2146SNamhyung Kim 			 * zero-fill group members at last which have no sample
865b9e2146SNamhyung Kim 			 */
879b0d2fb8SNamhyung Kim 			if (fmt_percent) {
88a0088adcSNamhyung Kim 				ret += hpp__call_print_fn(hpp, print_fn,
899b0d2fb8SNamhyung Kim 							  fmt, 0.0);
909b0d2fb8SNamhyung Kim 			} else {
91a0088adcSNamhyung Kim 				ret += hpp__call_print_fn(hpp, print_fn,
929b0d2fb8SNamhyung Kim 							  fmt, 0ULL);
939b0d2fb8SNamhyung Kim 			}
945b9e2146SNamhyung Kim 		}
955b9e2146SNamhyung Kim 	}
96a0088adcSNamhyung Kim 
97a0088adcSNamhyung Kim 	/*
98a0088adcSNamhyung Kim 	 * Restore original buf and size as it's where caller expects
99a0088adcSNamhyung Kim 	 * the result will be saved.
100a0088adcSNamhyung Kim 	 */
101a0088adcSNamhyung Kim 	hpp->buf = buf;
102a0088adcSNamhyung Kim 	hpp->size = size;
103a0088adcSNamhyung Kim 
1044fb71074SNamhyung Kim 	return ret;
105ea251d51SNamhyung Kim }
106ea251d51SNamhyung Kim 
107f156d84eSNamhyung Kim static int field_cmp(u64 field_a, u64 field_b)
108f156d84eSNamhyung Kim {
109f156d84eSNamhyung Kim 	if (field_a > field_b)
110f156d84eSNamhyung Kim 		return 1;
111f156d84eSNamhyung Kim 	if (field_a < field_b)
112f156d84eSNamhyung Kim 		return -1;
113f156d84eSNamhyung Kim 	return 0;
114f156d84eSNamhyung Kim }
115f156d84eSNamhyung Kim 
116f156d84eSNamhyung Kim static int __hpp__sort(struct hist_entry *a, struct hist_entry *b,
117f156d84eSNamhyung Kim 		       hpp_field_fn get_field)
118f156d84eSNamhyung Kim {
119f156d84eSNamhyung Kim 	s64 ret;
120f156d84eSNamhyung Kim 	int i, nr_members;
121f156d84eSNamhyung Kim 	struct perf_evsel *evsel;
122f156d84eSNamhyung Kim 	struct hist_entry *pair;
123f156d84eSNamhyung Kim 	u64 *fields_a, *fields_b;
124f156d84eSNamhyung Kim 
125f156d84eSNamhyung Kim 	ret = field_cmp(get_field(a), get_field(b));
126f156d84eSNamhyung Kim 	if (ret || !symbol_conf.event_group)
127f156d84eSNamhyung Kim 		return ret;
128f156d84eSNamhyung Kim 
129f156d84eSNamhyung Kim 	evsel = hists_to_evsel(a->hists);
130f156d84eSNamhyung Kim 	if (!perf_evsel__is_group_event(evsel))
131f156d84eSNamhyung Kim 		return ret;
132f156d84eSNamhyung Kim 
133f156d84eSNamhyung Kim 	nr_members = evsel->nr_members;
134f156d84eSNamhyung Kim 	fields_a = calloc(sizeof(*fields_a), nr_members);
135f156d84eSNamhyung Kim 	fields_b = calloc(sizeof(*fields_b), nr_members);
136f156d84eSNamhyung Kim 
137f156d84eSNamhyung Kim 	if (!fields_a || !fields_b)
138f156d84eSNamhyung Kim 		goto out;
139f156d84eSNamhyung Kim 
140f156d84eSNamhyung Kim 	list_for_each_entry(pair, &a->pairs.head, pairs.node) {
141f156d84eSNamhyung Kim 		evsel = hists_to_evsel(pair->hists);
142f156d84eSNamhyung Kim 		fields_a[perf_evsel__group_idx(evsel)] = get_field(pair);
143f156d84eSNamhyung Kim 	}
144f156d84eSNamhyung Kim 
145f156d84eSNamhyung Kim 	list_for_each_entry(pair, &b->pairs.head, pairs.node) {
146f156d84eSNamhyung Kim 		evsel = hists_to_evsel(pair->hists);
147f156d84eSNamhyung Kim 		fields_b[perf_evsel__group_idx(evsel)] = get_field(pair);
148f156d84eSNamhyung Kim 	}
149f156d84eSNamhyung Kim 
150f156d84eSNamhyung Kim 	for (i = 1; i < nr_members; i++) {
151f156d84eSNamhyung Kim 		ret = field_cmp(fields_a[i], fields_b[i]);
152f156d84eSNamhyung Kim 		if (ret)
153f156d84eSNamhyung Kim 			break;
154f156d84eSNamhyung Kim 	}
155f156d84eSNamhyung Kim 
156f156d84eSNamhyung Kim out:
157f156d84eSNamhyung Kim 	free(fields_a);
158f156d84eSNamhyung Kim 	free(fields_b);
159f156d84eSNamhyung Kim 
160f156d84eSNamhyung Kim 	return ret;
161f156d84eSNamhyung Kim }
162f156d84eSNamhyung Kim 
1634fb71074SNamhyung Kim #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) 		\
1642c5d4b4aSJiri Olsa static int hpp__header_##_type(struct perf_hpp_fmt *fmt __maybe_unused,	\
16594a0793dSNamhyung Kim 			       struct perf_hpp *hpp,			\
16694a0793dSNamhyung Kim 			       struct perf_evsel *evsel)		\
1674fb71074SNamhyung Kim {									\
1684fb71074SNamhyung Kim 	int len = _min_width;						\
1694fb71074SNamhyung Kim 									\
17094a0793dSNamhyung Kim 	if (symbol_conf.event_group)					\
1715b9e2146SNamhyung Kim 		len = max(len, evsel->nr_members * _unit_width);	\
17294a0793dSNamhyung Kim 									\
1734fb71074SNamhyung Kim 	return scnprintf(hpp->buf, hpp->size, "%*s", len, _str);	\
174ea251d51SNamhyung Kim }
175ea251d51SNamhyung Kim 
1764fb71074SNamhyung Kim #define __HPP_WIDTH_FN(_type, _min_width, _unit_width) 			\
1772c5d4b4aSJiri Olsa static int hpp__width_##_type(struct perf_hpp_fmt *fmt __maybe_unused,	\
17894a0793dSNamhyung Kim 			      struct perf_hpp *hpp __maybe_unused,	\
17994a0793dSNamhyung Kim 			      struct perf_evsel *evsel)			\
1804fb71074SNamhyung Kim {									\
1814fb71074SNamhyung Kim 	int len = _min_width;						\
1824fb71074SNamhyung Kim 									\
18394a0793dSNamhyung Kim 	if (symbol_conf.event_group)					\
1845b9e2146SNamhyung Kim 		len = max(len, evsel->nr_members * _unit_width);	\
18594a0793dSNamhyung Kim 									\
1864fb71074SNamhyung Kim 	return len;							\
187ea251d51SNamhyung Kim }
188ea251d51SNamhyung Kim 
189a0088adcSNamhyung Kim static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...)
190a0088adcSNamhyung Kim {
191a0088adcSNamhyung Kim 	va_list args;
192a0088adcSNamhyung Kim 	ssize_t ssize = hpp->size;
193a0088adcSNamhyung Kim 	double percent;
194a0088adcSNamhyung Kim 	int ret;
195a0088adcSNamhyung Kim 
196a0088adcSNamhyung Kim 	va_start(args, fmt);
197a0088adcSNamhyung Kim 	percent = va_arg(args, double);
198a0088adcSNamhyung Kim 	ret = value_color_snprintf(hpp->buf, hpp->size, fmt, percent);
199a0088adcSNamhyung Kim 	va_end(args);
200a0088adcSNamhyung Kim 
201a0088adcSNamhyung Kim 	return (ret >= ssize) ? (ssize - 1) : ret;
202a0088adcSNamhyung Kim }
203a0088adcSNamhyung Kim 
204a0088adcSNamhyung Kim static int hpp_entry_scnprintf(struct perf_hpp *hpp, const char *fmt, ...)
205a0088adcSNamhyung Kim {
206a0088adcSNamhyung Kim 	va_list args;
207a0088adcSNamhyung Kim 	ssize_t ssize = hpp->size;
208a0088adcSNamhyung Kim 	int ret;
209a0088adcSNamhyung Kim 
210a0088adcSNamhyung Kim 	va_start(args, fmt);
211a0088adcSNamhyung Kim 	ret = vsnprintf(hpp->buf, hpp->size, fmt, args);
212a0088adcSNamhyung Kim 	va_end(args);
213a0088adcSNamhyung Kim 
214a0088adcSNamhyung Kim 	return (ret >= ssize) ? (ssize - 1) : ret;
215a0088adcSNamhyung Kim }
216a0088adcSNamhyung Kim 
2174fb71074SNamhyung Kim #define __HPP_COLOR_PERCENT_FN(_type, _field)					\
2184fb71074SNamhyung Kim static u64 he_get_##_field(struct hist_entry *he)				\
2194fb71074SNamhyung Kim {										\
2204fb71074SNamhyung Kim 	return he->stat._field;							\
2214fb71074SNamhyung Kim }										\
2224fb71074SNamhyung Kim 										\
2232c5d4b4aSJiri Olsa static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,		\
2242c5d4b4aSJiri Olsa 			      struct perf_hpp *hpp, struct hist_entry *he) 	\
2254fb71074SNamhyung Kim {										\
226fb821c9eSNamhyung Kim 	return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%",			\
227a0088adcSNamhyung Kim 			  hpp_color_scnprintf, true);				\
228ea251d51SNamhyung Kim }
229ea251d51SNamhyung Kim 
2304fb71074SNamhyung Kim #define __HPP_ENTRY_PERCENT_FN(_type, _field)					\
2312c5d4b4aSJiri Olsa static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused,		\
2322c5d4b4aSJiri Olsa 			      struct perf_hpp *hpp, struct hist_entry *he) 	\
2334fb71074SNamhyung Kim {										\
2344fb71074SNamhyung Kim 	const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%";		\
235fb821c9eSNamhyung Kim 	return __hpp__fmt(hpp, he, he_get_##_field, fmt,			\
236a0088adcSNamhyung Kim 			  hpp_entry_scnprintf, true);				\
237ea251d51SNamhyung Kim }
238ea251d51SNamhyung Kim 
239bc18b7f2SNamhyung Kim #define __HPP_SORT_FN(_type, _field)						\
240bc18b7f2SNamhyung Kim static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b)	\
241bc18b7f2SNamhyung Kim {										\
242f156d84eSNamhyung Kim 	return __hpp__sort(a, b, he_get_##_field);				\
243bc18b7f2SNamhyung Kim }
244bc18b7f2SNamhyung Kim 
2454fb71074SNamhyung Kim #define __HPP_ENTRY_RAW_FN(_type, _field)					\
2464fb71074SNamhyung Kim static u64 he_get_raw_##_field(struct hist_entry *he)				\
2474fb71074SNamhyung Kim {										\
2484fb71074SNamhyung Kim 	return he->stat._field;							\
2494fb71074SNamhyung Kim }										\
2504fb71074SNamhyung Kim 										\
2512c5d4b4aSJiri Olsa static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused,		\
2522c5d4b4aSJiri Olsa 			      struct perf_hpp *hpp, struct hist_entry *he) 	\
2534fb71074SNamhyung Kim {										\
2544fb71074SNamhyung Kim 	const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64;	\
255fb821c9eSNamhyung Kim 	return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt,			\
256a0088adcSNamhyung Kim 			  hpp_entry_scnprintf, false);				\
257ea251d51SNamhyung Kim }
258ea251d51SNamhyung Kim 
259bc18b7f2SNamhyung Kim #define __HPP_SORT_RAW_FN(_type, _field)					\
260bc18b7f2SNamhyung Kim static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b)	\
261bc18b7f2SNamhyung Kim {										\
262f156d84eSNamhyung Kim 	return __hpp__sort(a, b, he_get_raw_##_field);				\
263bc18b7f2SNamhyung Kim }
264bc18b7f2SNamhyung Kim 
265bc18b7f2SNamhyung Kim 
2664fb71074SNamhyung Kim #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width)	\
2674fb71074SNamhyung Kim __HPP_HEADER_FN(_type, _str, _min_width, _unit_width)			\
2684fb71074SNamhyung Kim __HPP_WIDTH_FN(_type, _min_width, _unit_width)				\
2694fb71074SNamhyung Kim __HPP_COLOR_PERCENT_FN(_type, _field)					\
270bc18b7f2SNamhyung Kim __HPP_ENTRY_PERCENT_FN(_type, _field)					\
271bc18b7f2SNamhyung Kim __HPP_SORT_FN(_type, _field)
272ea251d51SNamhyung Kim 
2734fb71074SNamhyung Kim #define HPP_RAW_FNS(_type, _str, _field, _min_width, _unit_width)	\
2744fb71074SNamhyung Kim __HPP_HEADER_FN(_type, _str, _min_width, _unit_width)			\
2754fb71074SNamhyung Kim __HPP_WIDTH_FN(_type, _min_width, _unit_width)				\
276bc18b7f2SNamhyung Kim __HPP_ENTRY_RAW_FN(_type, _field)					\
277bc18b7f2SNamhyung Kim __HPP_SORT_RAW_FN(_type, _field)
278b5ff71c3SJiri Olsa 
279ea251d51SNamhyung Kim 
2804fb71074SNamhyung Kim HPP_PERCENT_FNS(overhead, "Overhead", period, 8, 8)
2814fb71074SNamhyung Kim HPP_PERCENT_FNS(overhead_sys, "sys", period_sys, 8, 8)
2824fb71074SNamhyung Kim HPP_PERCENT_FNS(overhead_us, "usr", period_us, 8, 8)
2834fb71074SNamhyung Kim HPP_PERCENT_FNS(overhead_guest_sys, "guest sys", period_guest_sys, 9, 8)
2844fb71074SNamhyung Kim HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us, 9, 8)
2859ffad987SNamhyung Kim 
2864fb71074SNamhyung Kim HPP_RAW_FNS(samples, "Samples", nr_events, 12, 12)
2874fb71074SNamhyung Kim HPP_RAW_FNS(period, "Period", period, 12, 12)
288ea251d51SNamhyung Kim 
289bc18b7f2SNamhyung Kim static int64_t hpp__nop_cmp(struct hist_entry *a __maybe_unused,
290bc18b7f2SNamhyung Kim 			    struct hist_entry *b __maybe_unused)
291bc18b7f2SNamhyung Kim {
292bc18b7f2SNamhyung Kim 	return 0;
293bc18b7f2SNamhyung Kim }
294bc18b7f2SNamhyung Kim 
295ea251d51SNamhyung Kim #define HPP__COLOR_PRINT_FNS(_name)			\
2961240005eSJiri Olsa 	{						\
297ea251d51SNamhyung Kim 		.header	= hpp__header_ ## _name,	\
298ea251d51SNamhyung Kim 		.width	= hpp__width_ ## _name,		\
299ea251d51SNamhyung Kim 		.color	= hpp__color_ ## _name,		\
300bc18b7f2SNamhyung Kim 		.entry	= hpp__entry_ ## _name,		\
301bc18b7f2SNamhyung Kim 		.cmp	= hpp__nop_cmp,			\
302bc18b7f2SNamhyung Kim 		.collapse = hpp__nop_cmp,		\
303bc18b7f2SNamhyung Kim 		.sort	= hpp__sort_ ## _name,		\
3041240005eSJiri Olsa 	}
305ea251d51SNamhyung Kim 
306ea251d51SNamhyung Kim #define HPP__PRINT_FNS(_name)				\
3071240005eSJiri Olsa 	{						\
308ea251d51SNamhyung Kim 		.header	= hpp__header_ ## _name,	\
309ea251d51SNamhyung Kim 		.width	= hpp__width_ ## _name,		\
310bc18b7f2SNamhyung Kim 		.entry	= hpp__entry_ ## _name,		\
311bc18b7f2SNamhyung Kim 		.cmp	= hpp__nop_cmp,			\
312bc18b7f2SNamhyung Kim 		.collapse = hpp__nop_cmp,		\
313bc18b7f2SNamhyung Kim 		.sort	= hpp__sort_ ## _name,		\
3141240005eSJiri Olsa 	}
315ea251d51SNamhyung Kim 
316ea251d51SNamhyung Kim struct perf_hpp_fmt perf_hpp__format[] = {
3171240005eSJiri Olsa 	HPP__COLOR_PRINT_FNS(overhead),
3181240005eSJiri Olsa 	HPP__COLOR_PRINT_FNS(overhead_sys),
3191240005eSJiri Olsa 	HPP__COLOR_PRINT_FNS(overhead_us),
3201240005eSJiri Olsa 	HPP__COLOR_PRINT_FNS(overhead_guest_sys),
3211240005eSJiri Olsa 	HPP__COLOR_PRINT_FNS(overhead_guest_us),
3221240005eSJiri Olsa 	HPP__PRINT_FNS(samples),
323345dc0b4SJiri Olsa 	HPP__PRINT_FNS(period)
324ea251d51SNamhyung Kim };
325ea251d51SNamhyung Kim 
3261240005eSJiri Olsa LIST_HEAD(perf_hpp__list);
3278b536999SNamhyung Kim LIST_HEAD(perf_hpp__sort_list);
3281240005eSJiri Olsa 
3294fb71074SNamhyung Kim 
330ea251d51SNamhyung Kim #undef HPP__COLOR_PRINT_FNS
331ea251d51SNamhyung Kim #undef HPP__PRINT_FNS
332ea251d51SNamhyung Kim 
3334fb71074SNamhyung Kim #undef HPP_PERCENT_FNS
3344fb71074SNamhyung Kim #undef HPP_RAW_FNS
3354fb71074SNamhyung Kim 
3364fb71074SNamhyung Kim #undef __HPP_HEADER_FN
3374fb71074SNamhyung Kim #undef __HPP_WIDTH_FN
3384fb71074SNamhyung Kim #undef __HPP_COLOR_PERCENT_FN
3394fb71074SNamhyung Kim #undef __HPP_ENTRY_PERCENT_FN
3404fb71074SNamhyung Kim #undef __HPP_ENTRY_RAW_FN
3414fb71074SNamhyung Kim 
3424fb71074SNamhyung Kim 
3431d77822eSJiri Olsa void perf_hpp__init(void)
344ea251d51SNamhyung Kim {
34526d8b338SNamhyung Kim 	struct list_head *list;
34626d8b338SNamhyung Kim 	int i;
34726d8b338SNamhyung Kim 
34826d8b338SNamhyung Kim 	for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
349*a2ce067eSNamhyung Kim 		struct perf_hpp_fmt *fmt = &perf_hpp__format[i];
350*a2ce067eSNamhyung Kim 
351*a2ce067eSNamhyung Kim 		INIT_LIST_HEAD(&fmt->list);
352*a2ce067eSNamhyung Kim 
353*a2ce067eSNamhyung Kim 		/* sort_list may be linked by setup_sorting() */
354*a2ce067eSNamhyung Kim 		if (fmt->sort_list.next == NULL)
355*a2ce067eSNamhyung Kim 			INIT_LIST_HEAD(&fmt->sort_list);
35626d8b338SNamhyung Kim 	}
35726d8b338SNamhyung Kim 
3582b8bfa6bSJiri Olsa 	perf_hpp__column_enable(PERF_HPP__OVERHEAD);
3592b8bfa6bSJiri Olsa 
360ea251d51SNamhyung Kim 	if (symbol_conf.show_cpu_utilization) {
3611240005eSJiri Olsa 		perf_hpp__column_enable(PERF_HPP__OVERHEAD_SYS);
3621240005eSJiri Olsa 		perf_hpp__column_enable(PERF_HPP__OVERHEAD_US);
363ea251d51SNamhyung Kim 
364ea251d51SNamhyung Kim 		if (perf_guest) {
3651240005eSJiri Olsa 			perf_hpp__column_enable(PERF_HPP__OVERHEAD_GUEST_SYS);
3661240005eSJiri Olsa 			perf_hpp__column_enable(PERF_HPP__OVERHEAD_GUEST_US);
367ea251d51SNamhyung Kim 		}
368ea251d51SNamhyung Kim 	}
369ea251d51SNamhyung Kim 
370ea251d51SNamhyung Kim 	if (symbol_conf.show_nr_samples)
3711240005eSJiri Olsa 		perf_hpp__column_enable(PERF_HPP__SAMPLES);
372ea251d51SNamhyung Kim 
373ea251d51SNamhyung Kim 	if (symbol_conf.show_total_period)
3741240005eSJiri Olsa 		perf_hpp__column_enable(PERF_HPP__PERIOD);
37526d8b338SNamhyung Kim 
37626d8b338SNamhyung Kim 	/* prepend overhead field for backward compatiblity.  */
37726d8b338SNamhyung Kim 	list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
37826d8b338SNamhyung Kim 	if (list_empty(list))
37926d8b338SNamhyung Kim 		list_add(list, &perf_hpp__sort_list);
38026d8b338SNamhyung Kim 
38126d8b338SNamhyung Kim 	perf_hpp__setup_output_field();
382ea251d51SNamhyung Kim }
3831d77822eSJiri Olsa 
3841240005eSJiri Olsa void perf_hpp__column_register(struct perf_hpp_fmt *format)
3851240005eSJiri Olsa {
3861240005eSJiri Olsa 	list_add_tail(&format->list, &perf_hpp__list);
3871240005eSJiri Olsa }
3881240005eSJiri Olsa 
3898b536999SNamhyung Kim void perf_hpp__register_sort_field(struct perf_hpp_fmt *format)
3908b536999SNamhyung Kim {
3918b536999SNamhyung Kim 	list_add_tail(&format->sort_list, &perf_hpp__sort_list);
3928b536999SNamhyung Kim }
3938b536999SNamhyung Kim 
3941240005eSJiri Olsa void perf_hpp__column_enable(unsigned col)
3951d77822eSJiri Olsa {
3961d77822eSJiri Olsa 	BUG_ON(col >= PERF_HPP__MAX_INDEX);
3971240005eSJiri Olsa 	perf_hpp__column_register(&perf_hpp__format[col]);
398ea251d51SNamhyung Kim }
399ea251d51SNamhyung Kim 
40026d8b338SNamhyung Kim void perf_hpp__setup_output_field(void)
40126d8b338SNamhyung Kim {
40226d8b338SNamhyung Kim 	struct perf_hpp_fmt *fmt;
40326d8b338SNamhyung Kim 
40426d8b338SNamhyung Kim 	/* append sort keys to output field */
40526d8b338SNamhyung Kim 	perf_hpp__for_each_sort_list(fmt) {
40626d8b338SNamhyung Kim 		if (list_empty(&fmt->list))
40726d8b338SNamhyung Kim 			perf_hpp__column_register(fmt);
40826d8b338SNamhyung Kim 	}
40926d8b338SNamhyung Kim }
41026d8b338SNamhyung Kim 
411ea251d51SNamhyung Kim int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
412ea251d51SNamhyung Kim 			      struct hists *hists)
413ea251d51SNamhyung Kim {
414ea251d51SNamhyung Kim 	const char *sep = symbol_conf.field_sep;
415ea251d51SNamhyung Kim 	struct sort_entry *se;
416ea251d51SNamhyung Kim 	int ret = 0;
417ea251d51SNamhyung Kim 
418ea251d51SNamhyung Kim 	list_for_each_entry(se, &hist_entry__sort_list, list) {
419ea251d51SNamhyung Kim 		if (se->elide)
420ea251d51SNamhyung Kim 			continue;
421ea251d51SNamhyung Kim 
422ea251d51SNamhyung Kim 		ret += scnprintf(s + ret, size - ret, "%s", sep ?: "  ");
423ea251d51SNamhyung Kim 		ret += se->se_snprintf(he, s + ret, size - ret,
424ea251d51SNamhyung Kim 				       hists__col_len(hists, se->se_width_idx));
425ea251d51SNamhyung Kim 	}
426ea251d51SNamhyung Kim 
427ea251d51SNamhyung Kim 	return ret;
428ea251d51SNamhyung Kim }
4297e62ef44SNamhyung Kim 
4307e62ef44SNamhyung Kim /*
4317e62ef44SNamhyung Kim  * See hists__fprintf to match the column widths
4327e62ef44SNamhyung Kim  */
4337e62ef44SNamhyung Kim unsigned int hists__sort_list_width(struct hists *hists)
4347e62ef44SNamhyung Kim {
4351240005eSJiri Olsa 	struct perf_hpp_fmt *fmt;
4367e62ef44SNamhyung Kim 	struct sort_entry *se;
4371240005eSJiri Olsa 	int i = 0, ret = 0;
43894a0793dSNamhyung Kim 	struct perf_hpp dummy_hpp;
4397e62ef44SNamhyung Kim 
4401240005eSJiri Olsa 	perf_hpp__for_each_format(fmt) {
4417e62ef44SNamhyung Kim 		if (i)
4427e62ef44SNamhyung Kim 			ret += 2;
4437e62ef44SNamhyung Kim 
44494a0793dSNamhyung Kim 		ret += fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists));
4457e62ef44SNamhyung Kim 	}
4467e62ef44SNamhyung Kim 
4477e62ef44SNamhyung Kim 	list_for_each_entry(se, &hist_entry__sort_list, list)
4487e62ef44SNamhyung Kim 		if (!se->elide)
4497e62ef44SNamhyung Kim 			ret += 2 + hists__col_len(hists, se->se_width_idx);
4507e62ef44SNamhyung Kim 
4517e62ef44SNamhyung Kim 	if (verbose) /* Addr + origin */
4527e62ef44SNamhyung Kim 		ret += 3 + BITS_PER_LONG / 4;
4537e62ef44SNamhyung Kim 
4547e62ef44SNamhyung Kim 	return ret;
4557e62ef44SNamhyung Kim }
456