xref: /OK3568_Linux_fs/kernel/tools/perf/util/hist.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __PERF_HIST_H
3*4882a593Smuzhiyun #define __PERF_HIST_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/rbtree.h>
6*4882a593Smuzhiyun #include <linux/types.h>
7*4882a593Smuzhiyun #include <pthread.h>
8*4882a593Smuzhiyun #include "evsel.h"
9*4882a593Smuzhiyun #include "color.h"
10*4882a593Smuzhiyun #include "events_stats.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun struct hist_entry;
13*4882a593Smuzhiyun struct hist_entry_ops;
14*4882a593Smuzhiyun struct addr_location;
15*4882a593Smuzhiyun struct map_symbol;
16*4882a593Smuzhiyun struct mem_info;
17*4882a593Smuzhiyun struct branch_info;
18*4882a593Smuzhiyun struct branch_stack;
19*4882a593Smuzhiyun struct block_info;
20*4882a593Smuzhiyun struct symbol;
21*4882a593Smuzhiyun struct ui_progress;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun enum hist_filter {
24*4882a593Smuzhiyun 	HIST_FILTER__DSO,
25*4882a593Smuzhiyun 	HIST_FILTER__THREAD,
26*4882a593Smuzhiyun 	HIST_FILTER__PARENT,
27*4882a593Smuzhiyun 	HIST_FILTER__SYMBOL,
28*4882a593Smuzhiyun 	HIST_FILTER__GUEST,
29*4882a593Smuzhiyun 	HIST_FILTER__HOST,
30*4882a593Smuzhiyun 	HIST_FILTER__SOCKET,
31*4882a593Smuzhiyun 	HIST_FILTER__C2C,
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun enum hist_column {
35*4882a593Smuzhiyun 	HISTC_SYMBOL,
36*4882a593Smuzhiyun 	HISTC_TIME,
37*4882a593Smuzhiyun 	HISTC_DSO,
38*4882a593Smuzhiyun 	HISTC_THREAD,
39*4882a593Smuzhiyun 	HISTC_COMM,
40*4882a593Smuzhiyun 	HISTC_CGROUP_ID,
41*4882a593Smuzhiyun 	HISTC_CGROUP,
42*4882a593Smuzhiyun 	HISTC_PARENT,
43*4882a593Smuzhiyun 	HISTC_CPU,
44*4882a593Smuzhiyun 	HISTC_SOCKET,
45*4882a593Smuzhiyun 	HISTC_SRCLINE,
46*4882a593Smuzhiyun 	HISTC_SRCFILE,
47*4882a593Smuzhiyun 	HISTC_MISPREDICT,
48*4882a593Smuzhiyun 	HISTC_IN_TX,
49*4882a593Smuzhiyun 	HISTC_ABORT,
50*4882a593Smuzhiyun 	HISTC_SYMBOL_FROM,
51*4882a593Smuzhiyun 	HISTC_SYMBOL_TO,
52*4882a593Smuzhiyun 	HISTC_DSO_FROM,
53*4882a593Smuzhiyun 	HISTC_DSO_TO,
54*4882a593Smuzhiyun 	HISTC_LOCAL_WEIGHT,
55*4882a593Smuzhiyun 	HISTC_GLOBAL_WEIGHT,
56*4882a593Smuzhiyun 	HISTC_MEM_DADDR_SYMBOL,
57*4882a593Smuzhiyun 	HISTC_MEM_DADDR_DSO,
58*4882a593Smuzhiyun 	HISTC_MEM_PHYS_DADDR,
59*4882a593Smuzhiyun 	HISTC_MEM_LOCKED,
60*4882a593Smuzhiyun 	HISTC_MEM_TLB,
61*4882a593Smuzhiyun 	HISTC_MEM_LVL,
62*4882a593Smuzhiyun 	HISTC_MEM_SNOOP,
63*4882a593Smuzhiyun 	HISTC_MEM_DCACHELINE,
64*4882a593Smuzhiyun 	HISTC_MEM_IADDR_SYMBOL,
65*4882a593Smuzhiyun 	HISTC_TRANSACTION,
66*4882a593Smuzhiyun 	HISTC_CYCLES,
67*4882a593Smuzhiyun 	HISTC_SRCLINE_FROM,
68*4882a593Smuzhiyun 	HISTC_SRCLINE_TO,
69*4882a593Smuzhiyun 	HISTC_TRACE,
70*4882a593Smuzhiyun 	HISTC_SYM_SIZE,
71*4882a593Smuzhiyun 	HISTC_DSO_SIZE,
72*4882a593Smuzhiyun 	HISTC_SYMBOL_IPC,
73*4882a593Smuzhiyun 	HISTC_NR_COLS, /* Last entry */
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun struct thread;
77*4882a593Smuzhiyun struct dso;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun struct hists {
80*4882a593Smuzhiyun 	struct rb_root_cached	entries_in_array[2];
81*4882a593Smuzhiyun 	struct rb_root_cached	*entries_in;
82*4882a593Smuzhiyun 	struct rb_root_cached	entries;
83*4882a593Smuzhiyun 	struct rb_root_cached	entries_collapsed;
84*4882a593Smuzhiyun 	u64			nr_entries;
85*4882a593Smuzhiyun 	u64			nr_non_filtered_entries;
86*4882a593Smuzhiyun 	u64			callchain_period;
87*4882a593Smuzhiyun 	u64			callchain_non_filtered_period;
88*4882a593Smuzhiyun 	struct thread		*thread_filter;
89*4882a593Smuzhiyun 	const struct dso	*dso_filter;
90*4882a593Smuzhiyun 	const char		*uid_filter_str;
91*4882a593Smuzhiyun 	const char		*symbol_filter_str;
92*4882a593Smuzhiyun 	pthread_mutex_t		lock;
93*4882a593Smuzhiyun 	struct events_stats	stats;
94*4882a593Smuzhiyun 	u64			event_stream;
95*4882a593Smuzhiyun 	u16			col_len[HISTC_NR_COLS];
96*4882a593Smuzhiyun 	bool			has_callchains;
97*4882a593Smuzhiyun 	int			socket_filter;
98*4882a593Smuzhiyun 	struct perf_hpp_list	*hpp_list;
99*4882a593Smuzhiyun 	struct list_head	hpp_formats;
100*4882a593Smuzhiyun 	int			nr_hpp_node;
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun #define hists__has(__h, __f) (__h)->hpp_list->__f
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun struct hist_entry_iter;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun struct hist_iter_ops {
108*4882a593Smuzhiyun 	int (*prepare_entry)(struct hist_entry_iter *, struct addr_location *);
109*4882a593Smuzhiyun 	int (*add_single_entry)(struct hist_entry_iter *, struct addr_location *);
110*4882a593Smuzhiyun 	int (*next_entry)(struct hist_entry_iter *, struct addr_location *);
111*4882a593Smuzhiyun 	int (*add_next_entry)(struct hist_entry_iter *, struct addr_location *);
112*4882a593Smuzhiyun 	int (*finish_entry)(struct hist_entry_iter *, struct addr_location *);
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun struct hist_entry_iter {
116*4882a593Smuzhiyun 	int total;
117*4882a593Smuzhiyun 	int curr;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	bool hide_unresolved;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	struct evsel *evsel;
122*4882a593Smuzhiyun 	struct perf_sample *sample;
123*4882a593Smuzhiyun 	struct hist_entry *he;
124*4882a593Smuzhiyun 	struct symbol *parent;
125*4882a593Smuzhiyun 	void *priv;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	const struct hist_iter_ops *ops;
128*4882a593Smuzhiyun 	/* user-defined callback function (optional) */
129*4882a593Smuzhiyun 	int (*add_entry_cb)(struct hist_entry_iter *iter,
130*4882a593Smuzhiyun 			    struct addr_location *al, bool single, void *arg);
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun extern const struct hist_iter_ops hist_iter_normal;
134*4882a593Smuzhiyun extern const struct hist_iter_ops hist_iter_branch;
135*4882a593Smuzhiyun extern const struct hist_iter_ops hist_iter_mem;
136*4882a593Smuzhiyun extern const struct hist_iter_ops hist_iter_cumulative;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun struct hist_entry *hists__add_entry(struct hists *hists,
139*4882a593Smuzhiyun 				    struct addr_location *al,
140*4882a593Smuzhiyun 				    struct symbol *parent,
141*4882a593Smuzhiyun 				    struct branch_info *bi,
142*4882a593Smuzhiyun 				    struct mem_info *mi,
143*4882a593Smuzhiyun 				    struct perf_sample *sample,
144*4882a593Smuzhiyun 				    bool sample_self);
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun struct hist_entry *hists__add_entry_ops(struct hists *hists,
147*4882a593Smuzhiyun 					struct hist_entry_ops *ops,
148*4882a593Smuzhiyun 					struct addr_location *al,
149*4882a593Smuzhiyun 					struct symbol *sym_parent,
150*4882a593Smuzhiyun 					struct branch_info *bi,
151*4882a593Smuzhiyun 					struct mem_info *mi,
152*4882a593Smuzhiyun 					struct perf_sample *sample,
153*4882a593Smuzhiyun 					bool sample_self);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun struct hist_entry *hists__add_entry_block(struct hists *hists,
156*4882a593Smuzhiyun 					  struct addr_location *al,
157*4882a593Smuzhiyun 					  struct block_info *bi);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
160*4882a593Smuzhiyun 			 int max_stack_depth, void *arg);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun struct perf_hpp;
163*4882a593Smuzhiyun struct perf_hpp_fmt;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
166*4882a593Smuzhiyun int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
167*4882a593Smuzhiyun int hist_entry__transaction_len(void);
168*4882a593Smuzhiyun int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
169*4882a593Smuzhiyun 			      struct hists *hists);
170*4882a593Smuzhiyun int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
171*4882a593Smuzhiyun 				   struct perf_hpp_fmt *fmt, int printed);
172*4882a593Smuzhiyun void hist_entry__delete(struct hist_entry *he);
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun typedef int (*hists__resort_cb_t)(struct hist_entry *he, void *arg);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun void evsel__output_resort_cb(struct evsel *evsel, struct ui_progress *prog,
177*4882a593Smuzhiyun 			     hists__resort_cb_t cb, void *cb_arg);
178*4882a593Smuzhiyun void evsel__output_resort(struct evsel *evsel, struct ui_progress *prog);
179*4882a593Smuzhiyun void hists__output_resort(struct hists *hists, struct ui_progress *prog);
180*4882a593Smuzhiyun void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog,
181*4882a593Smuzhiyun 			     hists__resort_cb_t cb);
182*4882a593Smuzhiyun int hists__collapse_resort(struct hists *hists, struct ui_progress *prog);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
185*4882a593Smuzhiyun void hists__delete_entries(struct hists *hists);
186*4882a593Smuzhiyun void hists__output_recalc_col_len(struct hists *hists, int max_rows);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun struct hist_entry *hists__get_entry(struct hists *hists, int idx);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun u64 hists__total_period(struct hists *hists);
191*4882a593Smuzhiyun void hists__reset_stats(struct hists *hists);
192*4882a593Smuzhiyun void hists__inc_stats(struct hists *hists, struct hist_entry *h);
193*4882a593Smuzhiyun void hists__inc_nr_events(struct hists *hists, u32 type);
194*4882a593Smuzhiyun void hists__inc_nr_samples(struct hists *hists, bool filtered);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
197*4882a593Smuzhiyun 		      int max_cols, float min_pcnt, FILE *fp,
198*4882a593Smuzhiyun 		      bool ignore_callchains);
199*4882a593Smuzhiyun size_t perf_evlist__fprintf_nr_events(struct evlist *evlist, FILE *fp);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun void hists__filter_by_dso(struct hists *hists);
202*4882a593Smuzhiyun void hists__filter_by_thread(struct hists *hists);
203*4882a593Smuzhiyun void hists__filter_by_symbol(struct hists *hists);
204*4882a593Smuzhiyun void hists__filter_by_socket(struct hists *hists);
205*4882a593Smuzhiyun 
hists__has_filter(struct hists * hists)206*4882a593Smuzhiyun static inline bool hists__has_filter(struct hists *hists)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun 	return hists->thread_filter || hists->dso_filter ||
209*4882a593Smuzhiyun 		hists->symbol_filter_str || (hists->socket_filter > -1);
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun u16 hists__col_len(struct hists *hists, enum hist_column col);
213*4882a593Smuzhiyun void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len);
214*4882a593Smuzhiyun bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len);
215*4882a593Smuzhiyun void hists__reset_col_len(struct hists *hists);
216*4882a593Smuzhiyun void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun void hists__match(struct hists *leader, struct hists *other);
219*4882a593Smuzhiyun int hists__link(struct hists *leader, struct hists *other);
220*4882a593Smuzhiyun int hists__unlink(struct hists *hists);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun struct hists_evsel {
223*4882a593Smuzhiyun 	struct evsel evsel;
224*4882a593Smuzhiyun 	struct hists	  hists;
225*4882a593Smuzhiyun };
226*4882a593Smuzhiyun 
hists_to_evsel(struct hists * hists)227*4882a593Smuzhiyun static inline struct evsel *hists_to_evsel(struct hists *hists)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun 	struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists);
230*4882a593Smuzhiyun 	return &hevsel->evsel;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
evsel__hists(struct evsel * evsel)233*4882a593Smuzhiyun static inline struct hists *evsel__hists(struct evsel *evsel)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	struct hists_evsel *hevsel = (struct hists_evsel *)evsel;
236*4882a593Smuzhiyun 	return &hevsel->hists;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun 
hists__has_callchains(struct hists * hists)239*4882a593Smuzhiyun static __pure inline bool hists__has_callchains(struct hists *hists)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	return hists->has_callchains;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun int hists__init(void);
245*4882a593Smuzhiyun int __hists__init(struct hists *hists, struct perf_hpp_list *hpp_list);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun struct rb_root_cached *hists__get_rotate_entries_in(struct hists *hists);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun struct perf_hpp {
250*4882a593Smuzhiyun 	char *buf;
251*4882a593Smuzhiyun 	size_t size;
252*4882a593Smuzhiyun 	const char *sep;
253*4882a593Smuzhiyun 	void *ptr;
254*4882a593Smuzhiyun 	bool skip;
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun struct perf_hpp_fmt {
258*4882a593Smuzhiyun 	const char *name;
259*4882a593Smuzhiyun 	int (*header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
260*4882a593Smuzhiyun 		      struct hists *hists, int line, int *span);
261*4882a593Smuzhiyun 	int (*width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
262*4882a593Smuzhiyun 		     struct hists *hists);
263*4882a593Smuzhiyun 	int (*color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
264*4882a593Smuzhiyun 		     struct hist_entry *he);
265*4882a593Smuzhiyun 	int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
266*4882a593Smuzhiyun 		     struct hist_entry *he);
267*4882a593Smuzhiyun 	int64_t (*cmp)(struct perf_hpp_fmt *fmt,
268*4882a593Smuzhiyun 		       struct hist_entry *a, struct hist_entry *b);
269*4882a593Smuzhiyun 	int64_t (*collapse)(struct perf_hpp_fmt *fmt,
270*4882a593Smuzhiyun 			    struct hist_entry *a, struct hist_entry *b);
271*4882a593Smuzhiyun 	int64_t (*sort)(struct perf_hpp_fmt *fmt,
272*4882a593Smuzhiyun 			struct hist_entry *a, struct hist_entry *b);
273*4882a593Smuzhiyun 	bool (*equal)(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b);
274*4882a593Smuzhiyun 	void (*free)(struct perf_hpp_fmt *fmt);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	struct list_head list;
277*4882a593Smuzhiyun 	struct list_head sort_list;
278*4882a593Smuzhiyun 	bool elide;
279*4882a593Smuzhiyun 	int len;
280*4882a593Smuzhiyun 	int user_len;
281*4882a593Smuzhiyun 	int idx;
282*4882a593Smuzhiyun 	int level;
283*4882a593Smuzhiyun };
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun struct perf_hpp_list {
286*4882a593Smuzhiyun 	struct list_head fields;
287*4882a593Smuzhiyun 	struct list_head sorts;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	int nr_header_lines;
290*4882a593Smuzhiyun 	int need_collapse;
291*4882a593Smuzhiyun 	int parent;
292*4882a593Smuzhiyun 	int sym;
293*4882a593Smuzhiyun 	int dso;
294*4882a593Smuzhiyun 	int socket;
295*4882a593Smuzhiyun 	int thread;
296*4882a593Smuzhiyun 	int comm;
297*4882a593Smuzhiyun };
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun extern struct perf_hpp_list perf_hpp_list;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun struct perf_hpp_list_node {
302*4882a593Smuzhiyun 	struct list_head	list;
303*4882a593Smuzhiyun 	struct perf_hpp_list	hpp;
304*4882a593Smuzhiyun 	int			level;
305*4882a593Smuzhiyun 	bool			skip;
306*4882a593Smuzhiyun };
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun void perf_hpp_list__column_register(struct perf_hpp_list *list,
309*4882a593Smuzhiyun 				    struct perf_hpp_fmt *format);
310*4882a593Smuzhiyun void perf_hpp_list__register_sort_field(struct perf_hpp_list *list,
311*4882a593Smuzhiyun 					struct perf_hpp_fmt *format);
312*4882a593Smuzhiyun void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
313*4882a593Smuzhiyun 				       struct perf_hpp_fmt *format);
314*4882a593Smuzhiyun 
perf_hpp__column_register(struct perf_hpp_fmt * format)315*4882a593Smuzhiyun static inline void perf_hpp__column_register(struct perf_hpp_fmt *format)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	perf_hpp_list__column_register(&perf_hpp_list, format);
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
perf_hpp__register_sort_field(struct perf_hpp_fmt * format)320*4882a593Smuzhiyun static inline void perf_hpp__register_sort_field(struct perf_hpp_fmt *format)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	perf_hpp_list__register_sort_field(&perf_hpp_list, format);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun 
perf_hpp__prepend_sort_field(struct perf_hpp_fmt * format)325*4882a593Smuzhiyun static inline void perf_hpp__prepend_sort_field(struct perf_hpp_fmt *format)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	perf_hpp_list__prepend_sort_field(&perf_hpp_list, format);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun #define perf_hpp_list__for_each_format(_list, format) \
331*4882a593Smuzhiyun 	list_for_each_entry(format, &(_list)->fields, list)
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun #define perf_hpp_list__for_each_format_safe(_list, format, tmp)	\
334*4882a593Smuzhiyun 	list_for_each_entry_safe(format, tmp, &(_list)->fields, list)
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun #define perf_hpp_list__for_each_sort_list(_list, format) \
337*4882a593Smuzhiyun 	list_for_each_entry(format, &(_list)->sorts, sort_list)
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun #define perf_hpp_list__for_each_sort_list_safe(_list, format, tmp)	\
340*4882a593Smuzhiyun 	list_for_each_entry_safe(format, tmp, &(_list)->sorts, sort_list)
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun #define hists__for_each_format(hists, format) \
343*4882a593Smuzhiyun 	perf_hpp_list__for_each_format((hists)->hpp_list, format)
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun #define hists__for_each_sort_list(hists, format) \
346*4882a593Smuzhiyun 	perf_hpp_list__for_each_sort_list((hists)->hpp_list, format)
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun extern struct perf_hpp_fmt perf_hpp__format[];
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun enum {
351*4882a593Smuzhiyun 	/* Matches perf_hpp__format array. */
352*4882a593Smuzhiyun 	PERF_HPP__OVERHEAD,
353*4882a593Smuzhiyun 	PERF_HPP__OVERHEAD_SYS,
354*4882a593Smuzhiyun 	PERF_HPP__OVERHEAD_US,
355*4882a593Smuzhiyun 	PERF_HPP__OVERHEAD_GUEST_SYS,
356*4882a593Smuzhiyun 	PERF_HPP__OVERHEAD_GUEST_US,
357*4882a593Smuzhiyun 	PERF_HPP__OVERHEAD_ACC,
358*4882a593Smuzhiyun 	PERF_HPP__SAMPLES,
359*4882a593Smuzhiyun 	PERF_HPP__PERIOD,
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	PERF_HPP__MAX_INDEX
362*4882a593Smuzhiyun };
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun void perf_hpp__init(void);
365*4882a593Smuzhiyun void perf_hpp__cancel_cumulate(void);
366*4882a593Smuzhiyun void perf_hpp__setup_output_field(struct perf_hpp_list *list);
367*4882a593Smuzhiyun void perf_hpp__reset_output_field(struct perf_hpp_list *list);
368*4882a593Smuzhiyun void perf_hpp__append_sort_keys(struct perf_hpp_list *list);
369*4882a593Smuzhiyun int perf_hpp__setup_hists_formats(struct perf_hpp_list *list,
370*4882a593Smuzhiyun 				  struct evlist *evlist);
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format);
374*4882a593Smuzhiyun bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *format);
375*4882a593Smuzhiyun bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists);
376*4882a593Smuzhiyun bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt);
377*4882a593Smuzhiyun bool perf_hpp__is_srcline_entry(struct perf_hpp_fmt *fmt);
378*4882a593Smuzhiyun bool perf_hpp__is_srcfile_entry(struct perf_hpp_fmt *fmt);
379*4882a593Smuzhiyun bool perf_hpp__is_thread_entry(struct perf_hpp_fmt *fmt);
380*4882a593Smuzhiyun bool perf_hpp__is_comm_entry(struct perf_hpp_fmt *fmt);
381*4882a593Smuzhiyun bool perf_hpp__is_dso_entry(struct perf_hpp_fmt *fmt);
382*4882a593Smuzhiyun bool perf_hpp__is_sym_entry(struct perf_hpp_fmt *fmt);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt);
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun int hist_entry__filter(struct hist_entry *he, int type, const void *arg);
387*4882a593Smuzhiyun 
perf_hpp__should_skip(struct perf_hpp_fmt * format,struct hists * hists)388*4882a593Smuzhiyun static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format,
389*4882a593Smuzhiyun 					 struct hists *hists)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	if (format->elide)
392*4882a593Smuzhiyun 		return true;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	if (perf_hpp__is_dynamic_entry(format) &&
395*4882a593Smuzhiyun 	    !perf_hpp__defined_dynamic_entry(format, hists))
396*4882a593Smuzhiyun 		return true;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	return false;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists);
402*4882a593Smuzhiyun void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists);
403*4882a593Smuzhiyun void perf_hpp__set_user_width(const char *width_list_str);
404*4882a593Smuzhiyun void hists__reset_column_width(struct hists *hists);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun typedef u64 (*hpp_field_fn)(struct hist_entry *he);
407*4882a593Smuzhiyun typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);
408*4882a593Smuzhiyun typedef int (*hpp_snprint_fn)(struct perf_hpp *hpp, const char *fmt, ...);
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
411*4882a593Smuzhiyun 	     struct hist_entry *he, hpp_field_fn get_field,
412*4882a593Smuzhiyun 	     const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent);
413*4882a593Smuzhiyun int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
414*4882a593Smuzhiyun 		 struct hist_entry *he, hpp_field_fn get_field,
415*4882a593Smuzhiyun 		 const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent);
416*4882a593Smuzhiyun 
advance_hpp(struct perf_hpp * hpp,int inc)417*4882a593Smuzhiyun static inline void advance_hpp(struct perf_hpp *hpp, int inc)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	hpp->buf  += inc;
420*4882a593Smuzhiyun 	hpp->size -= inc;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun 
perf_hpp__use_color(void)423*4882a593Smuzhiyun static inline size_t perf_hpp__use_color(void)
424*4882a593Smuzhiyun {
425*4882a593Smuzhiyun 	return !symbol_conf.field_sep;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
perf_hpp__color_overhead(void)428*4882a593Smuzhiyun static inline size_t perf_hpp__color_overhead(void)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	return perf_hpp__use_color() ?
431*4882a593Smuzhiyun 	       (COLOR_MAXLEN + sizeof(PERF_COLOR_RESET)) * PERF_HPP__MAX_INDEX
432*4882a593Smuzhiyun 	       : 0;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun struct evlist;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun struct hist_browser_timer {
438*4882a593Smuzhiyun 	void (*timer)(void *arg);
439*4882a593Smuzhiyun 	void *arg;
440*4882a593Smuzhiyun 	int refresh;
441*4882a593Smuzhiyun };
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun struct annotation_options;
444*4882a593Smuzhiyun struct res_sample;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun enum rstype {
447*4882a593Smuzhiyun 	A_NORMAL,
448*4882a593Smuzhiyun 	A_ASM,
449*4882a593Smuzhiyun 	A_SOURCE
450*4882a593Smuzhiyun };
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun struct block_hist;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun #ifdef HAVE_SLANG_SUPPORT
455*4882a593Smuzhiyun #include "../ui/keysyms.h"
456*4882a593Smuzhiyun void attr_to_script(char *buf, struct perf_event_attr *attr);
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
459*4882a593Smuzhiyun 			     struct hist_browser_timer *hbt,
460*4882a593Smuzhiyun 			     struct annotation_options *annotation_opts);
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel,
463*4882a593Smuzhiyun 			     struct hist_browser_timer *hbt,
464*4882a593Smuzhiyun 			     struct annotation_options *annotation_opts);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help,
467*4882a593Smuzhiyun 				  struct hist_browser_timer *hbt,
468*4882a593Smuzhiyun 				  float min_pcnt,
469*4882a593Smuzhiyun 				  struct perf_env *env,
470*4882a593Smuzhiyun 				  bool warn_lost_event,
471*4882a593Smuzhiyun 				  struct annotation_options *annotation_options);
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun int script_browse(const char *script_opt, struct evsel *evsel);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun void run_script(char *cmd);
476*4882a593Smuzhiyun int res_sample_browse(struct res_sample *res_samples, int num_res,
477*4882a593Smuzhiyun 		      struct evsel *evsel, enum rstype rstype);
478*4882a593Smuzhiyun void res_sample_init(void);
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
481*4882a593Smuzhiyun 			   float min_percent, struct perf_env *env,
482*4882a593Smuzhiyun 			   struct annotation_options *annotation_opts);
483*4882a593Smuzhiyun #else
484*4882a593Smuzhiyun static inline
perf_evlist__tui_browse_hists(struct evlist * evlist __maybe_unused,const char * help __maybe_unused,struct hist_browser_timer * hbt __maybe_unused,float min_pcnt __maybe_unused,struct perf_env * env __maybe_unused,bool warn_lost_event __maybe_unused,struct annotation_options * annotation_options __maybe_unused)485*4882a593Smuzhiyun int perf_evlist__tui_browse_hists(struct evlist *evlist __maybe_unused,
486*4882a593Smuzhiyun 				  const char *help __maybe_unused,
487*4882a593Smuzhiyun 				  struct hist_browser_timer *hbt __maybe_unused,
488*4882a593Smuzhiyun 				  float min_pcnt __maybe_unused,
489*4882a593Smuzhiyun 				  struct perf_env *env __maybe_unused,
490*4882a593Smuzhiyun 				  bool warn_lost_event __maybe_unused,
491*4882a593Smuzhiyun 				  struct annotation_options *annotation_options __maybe_unused)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun 	return 0;
494*4882a593Smuzhiyun }
map_symbol__tui_annotate(struct map_symbol * ms __maybe_unused,struct evsel * evsel __maybe_unused,struct hist_browser_timer * hbt __maybe_unused,struct annotation_options * annotation_options __maybe_unused)495*4882a593Smuzhiyun static inline int map_symbol__tui_annotate(struct map_symbol *ms __maybe_unused,
496*4882a593Smuzhiyun 					   struct evsel *evsel __maybe_unused,
497*4882a593Smuzhiyun 					   struct hist_browser_timer *hbt __maybe_unused,
498*4882a593Smuzhiyun 					   struct annotation_options *annotation_options __maybe_unused)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun 	return 0;
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
hist_entry__tui_annotate(struct hist_entry * he __maybe_unused,struct evsel * evsel __maybe_unused,struct hist_browser_timer * hbt __maybe_unused,struct annotation_options * annotation_opts __maybe_unused)503*4882a593Smuzhiyun static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused,
504*4882a593Smuzhiyun 					   struct evsel *evsel __maybe_unused,
505*4882a593Smuzhiyun 					   struct hist_browser_timer *hbt __maybe_unused,
506*4882a593Smuzhiyun 					   struct annotation_options *annotation_opts __maybe_unused)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun 	return 0;
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun 
script_browse(const char * script_opt __maybe_unused,struct evsel * evsel __maybe_unused)511*4882a593Smuzhiyun static inline int script_browse(const char *script_opt __maybe_unused,
512*4882a593Smuzhiyun 				struct evsel *evsel __maybe_unused)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun 	return 0;
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun 
res_sample_browse(struct res_sample * res_samples __maybe_unused,int num_res __maybe_unused,struct evsel * evsel __maybe_unused,enum rstype rstype __maybe_unused)517*4882a593Smuzhiyun static inline int res_sample_browse(struct res_sample *res_samples __maybe_unused,
518*4882a593Smuzhiyun 				    int num_res __maybe_unused,
519*4882a593Smuzhiyun 				    struct evsel *evsel __maybe_unused,
520*4882a593Smuzhiyun 				    enum rstype rstype __maybe_unused)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun 	return 0;
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun 
res_sample_init(void)525*4882a593Smuzhiyun static inline void res_sample_init(void) {}
526*4882a593Smuzhiyun 
block_hists_tui_browse(struct block_hist * bh __maybe_unused,struct evsel * evsel __maybe_unused,float min_percent __maybe_unused,struct perf_env * env __maybe_unused,struct annotation_options * annotation_opts __maybe_unused)527*4882a593Smuzhiyun static inline int block_hists_tui_browse(struct block_hist *bh __maybe_unused,
528*4882a593Smuzhiyun 					 struct evsel *evsel __maybe_unused,
529*4882a593Smuzhiyun 					 float min_percent __maybe_unused,
530*4882a593Smuzhiyun 					 struct perf_env *env __maybe_unused,
531*4882a593Smuzhiyun 					 struct annotation_options *annotation_opts __maybe_unused)
532*4882a593Smuzhiyun {
533*4882a593Smuzhiyun 	return 0;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun #define K_LEFT  -1000
537*4882a593Smuzhiyun #define K_RIGHT -2000
538*4882a593Smuzhiyun #define K_SWITCH_INPUT_DATA -3000
539*4882a593Smuzhiyun #define K_RELOAD -4000
540*4882a593Smuzhiyun #endif
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun unsigned int hists__sort_list_width(struct hists *hists);
543*4882a593Smuzhiyun unsigned int hists__overhead_width(struct hists *hists);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
546*4882a593Smuzhiyun 			  struct perf_sample *sample, bool nonany_branch_mode,
547*4882a593Smuzhiyun 			  u64 *total_cycles);
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun struct option;
550*4882a593Smuzhiyun int parse_filter_percentage(const struct option *opt, const char *arg, int unset);
551*4882a593Smuzhiyun int perf_hist_config(const char *var, const char *value);
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun void perf_hpp_list__init(struct perf_hpp_list *list);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun enum hierarchy_move_dir {
556*4882a593Smuzhiyun 	HMD_NORMAL,
557*4882a593Smuzhiyun 	HMD_FORCE_SIBLING,
558*4882a593Smuzhiyun 	HMD_FORCE_CHILD,
559*4882a593Smuzhiyun };
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun struct rb_node *rb_hierarchy_last(struct rb_node *node);
562*4882a593Smuzhiyun struct rb_node *__rb_hierarchy_next(struct rb_node *node,
563*4882a593Smuzhiyun 				    enum hierarchy_move_dir hmd);
564*4882a593Smuzhiyun struct rb_node *rb_hierarchy_prev(struct rb_node *node);
565*4882a593Smuzhiyun 
rb_hierarchy_next(struct rb_node * node)566*4882a593Smuzhiyun static inline struct rb_node *rb_hierarchy_next(struct rb_node *node)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun 	return __rb_hierarchy_next(node, HMD_NORMAL);
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun #define HIERARCHY_INDENT  3
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun bool hist_entry__has_hierarchy_children(struct hist_entry *he, float limit);
574*4882a593Smuzhiyun int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...);
575*4882a593Smuzhiyun int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...);
576*4882a593Smuzhiyun int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp,
577*4882a593Smuzhiyun 			   struct perf_hpp_list *hpp_list);
578*4882a593Smuzhiyun int hists__fprintf_headers(struct hists *hists, FILE *fp);
579*4882a593Smuzhiyun int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq);
580*4882a593Smuzhiyun 
hists__scnprintf_title(struct hists * hists,char * bf,size_t size)581*4882a593Smuzhiyun static inline int hists__scnprintf_title(struct hists *hists, char *bf, size_t size)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun 	return __hists__scnprintf_title(hists, bf, size, true);
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun #endif	/* __PERF_HIST_H */
587