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