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 "callchain.h" 8 #include "color.h" 9 #include "events_stats.h" 10 #include "evsel.h" 11 #include "map_symbol.h" 12 #include "mem-events.h" 13 #include "mutex.h" 14 #include "sample.h" 15 #include "spark.h" 16 #include "stat.h" 17 18 struct addr_location; 19 struct mem_info; 20 struct kvm_info; 21 struct branch_info; 22 struct branch_stack; 23 struct block_info; 24 struct ui_progress; 25 26 enum hist_filter { 27 HIST_FILTER__DSO, 28 HIST_FILTER__THREAD, 29 HIST_FILTER__PARENT, 30 HIST_FILTER__SYMBOL, 31 HIST_FILTER__GUEST, 32 HIST_FILTER__HOST, 33 HIST_FILTER__SOCKET, 34 HIST_FILTER__C2C, 35 HIST_FILTER__PARALLELISM, 36 }; 37 38 typedef u16 filter_mask_t; 39 40 enum hist_column { 41 HISTC_SYMBOL, 42 HISTC_TIME, 43 HISTC_DSO, 44 HISTC_THREAD, 45 HISTC_COMM, 46 HISTC_CGROUP_ID, 47 HISTC_CGROUP, 48 HISTC_PARENT, 49 HISTC_PARALLELISM, 50 HISTC_CPU, 51 HISTC_SOCKET, 52 HISTC_SRCLINE, 53 HISTC_SRCFILE, 54 HISTC_MISPREDICT, 55 HISTC_IN_TX, 56 HISTC_ABORT, 57 HISTC_SYMBOL_FROM, 58 HISTC_SYMBOL_TO, 59 HISTC_DSO_FROM, 60 HISTC_DSO_TO, 61 HISTC_LOCAL_WEIGHT, 62 HISTC_GLOBAL_WEIGHT, 63 HISTC_CODE_PAGE_SIZE, 64 HISTC_MEM_DADDR_SYMBOL, 65 HISTC_MEM_DADDR_DSO, 66 HISTC_MEM_PHYS_DADDR, 67 HISTC_MEM_DATA_PAGE_SIZE, 68 HISTC_MEM_LOCKED, 69 HISTC_MEM_TLB, 70 HISTC_MEM_LVL, 71 HISTC_MEM_SNOOP, 72 HISTC_MEM_DCACHELINE, 73 HISTC_MEM_IADDR_SYMBOL, 74 HISTC_TRANSACTION, 75 HISTC_CYCLES, 76 HISTC_SRCLINE_FROM, 77 HISTC_SRCLINE_TO, 78 HISTC_TRACE, 79 HISTC_SYM_SIZE, 80 HISTC_DSO_SIZE, 81 HISTC_SYMBOL_IPC, 82 HISTC_MEM_BLOCKED, 83 HISTC_LOCAL_INS_LAT, 84 HISTC_GLOBAL_INS_LAT, 85 HISTC_LOCAL_P_STAGE_CYC, 86 HISTC_GLOBAL_P_STAGE_CYC, 87 HISTC_ADDR_FROM, 88 HISTC_ADDR_TO, 89 HISTC_ADDR, 90 HISTC_SIMD, 91 HISTC_TYPE, 92 HISTC_TYPE_OFFSET, 93 HISTC_SYMBOL_OFFSET, 94 HISTC_TYPE_CACHELINE, 95 HISTC_CALLCHAIN_BRANCH_PREDICTED, 96 HISTC_CALLCHAIN_BRANCH_ABORT, 97 HISTC_CALLCHAIN_BRANCH_CYCLES, 98 HISTC_NR_COLS, /* Last entry */ 99 }; 100 101 struct thread; 102 struct dso; 103 104 #define MEM_STAT_LEN 8 105 106 struct he_mem_stat { 107 /* meaning of entries depends on enum mem_stat_type */ 108 u64 entries[MEM_STAT_LEN]; 109 }; 110 111 struct hists { 112 struct rb_root_cached entries_in_array[2]; 113 struct rb_root_cached *entries_in; 114 struct rb_root_cached entries; 115 struct rb_root_cached entries_collapsed; 116 u64 nr_entries; 117 u64 nr_non_filtered_entries; 118 u64 callchain_period; 119 u64 callchain_non_filtered_period; 120 u64 callchain_latency; 121 u64 callchain_non_filtered_latency; 122 struct thread *thread_filter; 123 const struct dso *dso_filter; 124 const char *uid_filter_str; 125 const char *symbol_filter_str; 126 unsigned long *parallelism_filter; 127 struct mutex lock; 128 struct hists_stats stats; 129 u64 event_stream; 130 u16 col_len[HISTC_NR_COLS]; 131 bool has_callchains; 132 int socket_filter; 133 struct perf_hpp_list *hpp_list; 134 struct list_head hpp_formats; 135 int nr_hpp_node; 136 int nr_mem_stats; 137 enum mem_stat_type *mem_stat_types; 138 struct he_mem_stat *mem_stat_total; 139 }; 140 141 #define hists__has(__h, __f) (__h)->hpp_list->__f 142 143 struct hist_entry_iter; 144 145 struct hist_iter_ops { 146 int (*prepare_entry)(struct hist_entry_iter *, struct addr_location *); 147 int (*add_single_entry)(struct hist_entry_iter *, struct addr_location *); 148 int (*next_entry)(struct hist_entry_iter *, struct addr_location *); 149 int (*add_next_entry)(struct hist_entry_iter *, struct addr_location *); 150 int (*finish_entry)(struct hist_entry_iter *, struct addr_location *); 151 }; 152 153 struct hist_entry_iter { 154 int total; 155 int curr; 156 157 struct evsel *evsel; 158 struct perf_sample *sample; 159 struct hist_entry *he; 160 struct symbol *parent; 161 162 struct mem_info *mi; 163 struct branch_info *bi; 164 struct hist_entry **he_cache; 165 166 const struct hist_iter_ops *ops; 167 /* user-defined callback function (optional) */ 168 int (*add_entry_cb)(struct hist_entry_iter *iter, 169 struct addr_location *al, bool single, void *arg); 170 bool hide_unresolved; 171 }; 172 173 extern const struct hist_iter_ops hist_iter_normal; 174 extern const struct hist_iter_ops hist_iter_branch; 175 extern const struct hist_iter_ops hist_iter_mem; 176 extern const struct hist_iter_ops hist_iter_cumulative; 177 178 struct res_sample { 179 u64 time; 180 int cpu; 181 int tid; 182 }; 183 184 struct he_stat { 185 u64 period; 186 /* 187 * Period re-scaled from CPU time to wall-clock time (divided by the 188 * parallelism at the time of the sample). This represents effect of 189 * the event on latency rather than CPU consumption. 190 */ 191 u64 latency; 192 u64 period_sys; 193 u64 period_us; 194 u64 period_guest_sys; 195 u64 period_guest_us; 196 u64 weight1; 197 u64 weight2; 198 u64 weight3; 199 u32 nr_events; 200 }; 201 202 struct namespace_id { 203 u64 dev; 204 u64 ino; 205 }; 206 207 struct hist_entry_diff { 208 bool computed; 209 union { 210 /* PERF_HPP__DELTA */ 211 double period_ratio_delta; 212 213 /* PERF_HPP__RATIO */ 214 double period_ratio; 215 216 /* HISTC_WEIGHTED_DIFF */ 217 s64 wdiff; 218 219 /* PERF_HPP_DIFF__CYCLES */ 220 s64 cycles; 221 }; 222 struct stats stats; 223 unsigned long svals[NUM_SPARKS]; 224 }; 225 226 struct hist_entry_ops { 227 void *(*new)(size_t size); 228 void (*free)(void *ptr); 229 }; 230 231 /** 232 * struct hist_entry - histogram entry 233 * 234 * @row_offset - offset from the first callchain expanded to appear on screen 235 * @nr_rows - rows expanded in callchain, recalculated on folding/unfolding 236 */ 237 struct hist_entry { 238 struct rb_node rb_node_in; 239 struct rb_node rb_node; 240 union { 241 struct list_head node; 242 struct list_head head; 243 } pairs; 244 struct he_stat stat; 245 struct he_stat *stat_acc; 246 struct he_mem_stat *mem_stat; 247 struct map_symbol ms; 248 struct thread *thread; 249 struct comm *comm; 250 struct namespace_id cgroup_id; 251 u64 cgroup; 252 u64 ip; 253 u64 transaction; 254 u64 code_page_size; 255 u64 weight; 256 u64 ins_lat; 257 u64 p_stage_cyc; 258 s32 socket; 259 s32 cpu; 260 int parallelism; 261 int mem_type_off; 262 u8 cpumode; 263 u8 depth; 264 struct simd_flags simd_flags; 265 266 /* We are added by hists__add_dummy_entry. */ 267 bool dummy; 268 bool leaf; 269 270 char level; 271 filter_mask_t filtered; 272 273 u16 callchain_size; 274 union { 275 /* 276 * Since perf diff only supports the stdio output, TUI 277 * fields are only accessed from perf report (or perf 278 * top). So make it a union to reduce memory usage. 279 */ 280 struct hist_entry_diff diff; 281 struct /* for TUI */ { 282 u16 row_offset; 283 u16 nr_rows; 284 bool init_have_children; 285 bool unfolded; 286 bool has_children; 287 bool has_no_entry; 288 }; 289 }; 290 char *srcline; 291 char *srcfile; 292 struct symbol *parent; 293 struct branch_info *branch_info; 294 long time; 295 struct hists *hists; 296 struct mem_info *mem_info; 297 struct block_info *block_info; 298 struct kvm_info *kvm_info; 299 void *raw_data; 300 u32 raw_size; 301 int num_res; 302 struct res_sample *res_samples; 303 void *trace_output; 304 struct perf_hpp_list *hpp_list; 305 struct hist_entry *parent_he; 306 struct hist_entry_ops *ops; 307 struct annotated_data_type *mem_type; 308 union { 309 /* this is for hierarchical entry structure */ 310 struct { 311 struct rb_root_cached hroot_in; 312 struct rb_root_cached hroot_out; 313 }; /* non-leaf entries */ 314 struct rb_root sorted_chain; /* leaf entry has callchains */ 315 }; 316 struct callchain_root callchain[0]; /* must be last member */ 317 }; 318 319 static __pure inline bool hist_entry__has_callchains(struct hist_entry *he) 320 { 321 return he->callchain_size != 0; 322 } 323 324 static inline bool hist_entry__has_pairs(struct hist_entry *he) 325 { 326 return !list_empty(&he->pairs.node); 327 } 328 329 static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he) 330 { 331 if (hist_entry__has_pairs(he)) 332 return list_entry(he->pairs.node.next, struct hist_entry, pairs.node); 333 return NULL; 334 } 335 336 static inline void hist_entry__add_pair(struct hist_entry *pair, 337 struct hist_entry *he) 338 { 339 list_add_tail(&pair->pairs.node, &he->pairs.head); 340 } 341 342 struct hist_entry *hists__add_entry(struct hists *hists, 343 struct addr_location *al, 344 struct symbol *parent, 345 struct branch_info *bi, 346 struct mem_info *mi, 347 struct kvm_info *ki, 348 struct perf_sample *sample, 349 bool sample_self); 350 351 struct hist_entry *hists__add_entry_ops(struct hists *hists, 352 struct hist_entry_ops *ops, 353 struct addr_location *al, 354 struct symbol *sym_parent, 355 struct branch_info *bi, 356 struct mem_info *mi, 357 struct kvm_info *ki, 358 struct perf_sample *sample, 359 bool sample_self); 360 361 struct hist_entry *hists__add_entry_block(struct hists *hists, 362 struct addr_location *al, 363 struct block_info *bi); 364 365 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, 366 int max_stack_depth, void *arg); 367 368 struct perf_hpp; 369 struct perf_hpp_fmt; 370 371 int hist_entry__transaction_len(void); 372 int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size, 373 struct hists *hists); 374 int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp, 375 struct perf_hpp_fmt *fmt, int printed); 376 int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, size_t size, 377 unsigned int width); 378 void hist_entry__delete(struct hist_entry *he); 379 380 typedef int (*hists__resort_cb_t)(struct hist_entry *he, void *arg); 381 382 void evsel__output_resort_cb(struct evsel *evsel, struct ui_progress *prog, 383 hists__resort_cb_t cb, void *cb_arg); 384 void evsel__output_resort(struct evsel *evsel, struct ui_progress *prog); 385 void hists__output_resort(struct hists *hists, struct ui_progress *prog); 386 void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog, 387 hists__resort_cb_t cb); 388 int hists__collapse_resort(struct hists *hists, struct ui_progress *prog); 389 390 void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); 391 void hists__delete_entries(struct hists *hists); 392 void hists__output_recalc_col_len(struct hists *hists, int max_rows); 393 394 struct hist_entry *hists__get_entry(struct hists *hists, int idx); 395 396 u64 hists__total_period(struct hists *hists); 397 u64 hists__total_latency(struct hists *hists); 398 void hists__reset_stats(struct hists *hists); 399 void hists__inc_stats(struct hists *hists, struct hist_entry *h); 400 void hists__inc_nr_events(struct hists *hists); 401 void hists__inc_nr_samples(struct hists *hists, bool filtered); 402 void hists__inc_nr_lost_samples(struct hists *hists, u32 lost); 403 void hists__inc_nr_dropped_samples(struct hists *hists, u32 lost); 404 405 size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 406 int max_cols, float min_pcnt, FILE *fp, 407 bool ignore_callchains); 408 size_t evlist__fprintf_nr_events(struct evlist *evlist, FILE *fp); 409 410 void hists__filter_by_dso(struct hists *hists); 411 void hists__filter_by_thread(struct hists *hists); 412 void hists__filter_by_symbol(struct hists *hists); 413 void hists__filter_by_socket(struct hists *hists); 414 void hists__filter_by_parallelism(struct hists *hists); 415 416 static inline bool hists__has_filter(struct hists *hists) 417 { 418 return hists->thread_filter || hists->dso_filter || 419 hists->symbol_filter_str || (hists->socket_filter > -1) || 420 hists->parallelism_filter; 421 } 422 423 u16 hists__col_len(struct hists *hists, enum hist_column col); 424 void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len); 425 bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len); 426 void hists__reset_col_len(struct hists *hists); 427 void hists__calc_col_len(struct hists *hists, struct hist_entry *he); 428 429 void hists__match(struct hists *leader, struct hists *other); 430 int hists__link(struct hists *leader, struct hists *other); 431 int hists__unlink(struct hists *hists); 432 433 static inline float hist_entry__get_percent_limit(struct hist_entry *he) 434 { 435 u64 period = he->stat.period; 436 u64 total_period = hists__total_period(he->hists); 437 438 if (unlikely(total_period == 0)) 439 return 0; 440 441 if (symbol_conf.cumulate_callchain) 442 period = he->stat_acc->period; 443 444 return period * 100.0 / total_period; 445 } 446 447 struct hists_evsel { 448 struct evsel evsel; 449 struct hists hists; 450 }; 451 452 static inline struct evsel *hists_to_evsel(struct hists *hists) 453 { 454 struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists); 455 return &hevsel->evsel; 456 } 457 458 static inline struct hists *evsel__hists(struct evsel *evsel) 459 { 460 struct hists_evsel *hevsel = (struct hists_evsel *)evsel; 461 return &hevsel->hists; 462 } 463 464 static __pure inline bool hists__has_callchains(struct hists *hists) 465 { 466 return hists->has_callchains; 467 } 468 469 int hists__init(void); 470 int __hists__init(struct hists *hists, struct perf_hpp_list *hpp_list); 471 472 struct rb_root_cached *hists__get_rotate_entries_in(struct hists *hists); 473 474 struct perf_hpp { 475 char *buf; 476 size_t size; 477 const char *sep; 478 void *ptr; 479 bool skip; 480 }; 481 482 typedef int64_t (*perf_hpp_fmt_cmp_t)( 483 struct perf_hpp_fmt *, struct hist_entry *, struct hist_entry *); 484 485 struct perf_hpp_fmt { 486 const char *name; 487 int (*header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 488 struct hists *hists, int line, int *span); 489 int (*width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 490 struct hists *hists); 491 void (*init)(struct perf_hpp_fmt *fmt, struct hist_entry *he); 492 int (*color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 493 struct hist_entry *he); 494 int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 495 struct hist_entry *he); 496 perf_hpp_fmt_cmp_t cmp; 497 perf_hpp_fmt_cmp_t collapse; 498 perf_hpp_fmt_cmp_t sort; 499 bool (*equal)(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b); 500 void (*free)(struct perf_hpp_fmt *fmt); 501 502 struct list_head list; 503 struct list_head sort_list; 504 bool elide; 505 int len; 506 int user_len; 507 int idx; 508 int level; 509 }; 510 511 struct perf_hpp_list { 512 struct list_head fields; 513 struct list_head sorts; 514 515 int nr_header_lines; 516 int need_collapse; 517 int parent; 518 int sym; 519 int dso; 520 int socket; 521 int thread; 522 int comm; 523 }; 524 525 extern struct perf_hpp_list perf_hpp_list; 526 527 struct perf_hpp_list_node { 528 struct list_head list; 529 struct perf_hpp_list hpp; 530 int level; 531 bool skip; 532 }; 533 534 void perf_hpp_list__column_register(struct perf_hpp_list *list, 535 struct perf_hpp_fmt *format); 536 void perf_hpp_list__register_sort_field(struct perf_hpp_list *list, 537 struct perf_hpp_fmt *format); 538 void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list, 539 struct perf_hpp_fmt *format); 540 541 static inline void perf_hpp__column_register(struct perf_hpp_fmt *format) 542 { 543 perf_hpp_list__column_register(&perf_hpp_list, format); 544 } 545 546 static inline void perf_hpp__register_sort_field(struct perf_hpp_fmt *format) 547 { 548 perf_hpp_list__register_sort_field(&perf_hpp_list, format); 549 } 550 551 static inline void perf_hpp__prepend_sort_field(struct perf_hpp_fmt *format) 552 { 553 perf_hpp_list__prepend_sort_field(&perf_hpp_list, format); 554 } 555 556 #define perf_hpp_list__for_each_format(_list, format) \ 557 list_for_each_entry(format, &(_list)->fields, list) 558 559 #define perf_hpp_list__for_each_format_safe(_list, format, tmp) \ 560 list_for_each_entry_safe(format, tmp, &(_list)->fields, list) 561 562 #define perf_hpp_list__for_each_sort_list(_list, format) \ 563 list_for_each_entry(format, &(_list)->sorts, sort_list) 564 565 #define perf_hpp_list__for_each_sort_list_safe(_list, format, tmp) \ 566 list_for_each_entry_safe(format, tmp, &(_list)->sorts, sort_list) 567 568 #define hists__for_each_format(hists, format) \ 569 perf_hpp_list__for_each_format((hists)->hpp_list, format) 570 571 #define hists__for_each_sort_list(hists, format) \ 572 perf_hpp_list__for_each_sort_list((hists)->hpp_list, format) 573 574 extern struct perf_hpp_fmt perf_hpp__format[]; 575 576 enum { 577 /* Matches perf_hpp__format array. */ 578 PERF_HPP__OVERHEAD, 579 PERF_HPP__LATENCY, 580 PERF_HPP__OVERHEAD_SYS, 581 PERF_HPP__OVERHEAD_US, 582 PERF_HPP__OVERHEAD_GUEST_SYS, 583 PERF_HPP__OVERHEAD_GUEST_US, 584 PERF_HPP__OVERHEAD_ACC, 585 PERF_HPP__LATENCY_ACC, 586 PERF_HPP__SAMPLES, 587 PERF_HPP__PERIOD, 588 PERF_HPP__WEIGHT1, 589 PERF_HPP__WEIGHT2, 590 PERF_HPP__WEIGHT3, 591 PERF_HPP__MEM_STAT_OP, 592 PERF_HPP__MEM_STAT_CACHE, 593 PERF_HPP__MEM_STAT_MEMORY, 594 PERF_HPP__MEM_STAT_SNOOP, 595 PERF_HPP__MEM_STAT_DTLB, 596 597 PERF_HPP__MAX_INDEX 598 }; 599 600 void perf_hpp__init(void); 601 void perf_hpp__cancel_cumulate(struct evlist *evlist); 602 void perf_hpp__cancel_latency(struct evlist *evlist); 603 void perf_hpp__setup_output_field(struct perf_hpp_list *list); 604 void perf_hpp__reset_output_field(struct perf_hpp_list *list); 605 void perf_hpp__append_sort_keys(struct perf_hpp_list *list); 606 int perf_hpp__setup_hists_formats(struct perf_hpp_list *list, 607 struct evlist *evlist); 608 int perf_hpp__alloc_mem_stats(struct perf_hpp_list *list, 609 struct evlist *evlist); 610 611 612 bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format); 613 bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *format); 614 bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists); 615 bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt); 616 bool perf_hpp__is_srcline_entry(struct perf_hpp_fmt *fmt); 617 bool perf_hpp__is_srcfile_entry(struct perf_hpp_fmt *fmt); 618 bool perf_hpp__is_thread_entry(struct perf_hpp_fmt *fmt); 619 bool perf_hpp__is_comm_entry(struct perf_hpp_fmt *fmt); 620 bool perf_hpp__is_dso_entry(struct perf_hpp_fmt *fmt); 621 bool perf_hpp__is_sym_entry(struct perf_hpp_fmt *fmt); 622 bool perf_hpp__is_parallelism_entry(struct perf_hpp_fmt *fmt); 623 624 struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt); 625 626 int hist_entry__filter(struct hist_entry *he, int type, const void *arg); 627 628 static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format, 629 struct hists *hists) 630 { 631 if (format->elide) 632 return true; 633 634 if (perf_hpp__is_dynamic_entry(format) && 635 !perf_hpp__defined_dynamic_entry(format, hists)) 636 return true; 637 638 return false; 639 } 640 641 void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists); 642 void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists); 643 void perf_hpp__set_user_width(const char *width_list_str); 644 void hists__reset_column_width(struct hists *hists); 645 646 enum perf_hpp_fmt_type { 647 PERF_HPP_FMT_TYPE__RAW, 648 PERF_HPP_FMT_TYPE__PERCENT, 649 PERF_HPP_FMT_TYPE__LATENCY, 650 PERF_HPP_FMT_TYPE__AVERAGE, 651 }; 652 653 typedef u64 (*hpp_field_fn)(struct hist_entry *he); 654 typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front); 655 typedef int (*hpp_snprint_fn)(struct perf_hpp *hpp, const char *fmt, ...); 656 657 int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 658 struct hist_entry *he, hpp_field_fn get_field, 659 const char *fmtstr, hpp_snprint_fn print_fn, 660 enum perf_hpp_fmt_type fmtype); 661 int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 662 struct hist_entry *he, hpp_field_fn get_field, 663 const char *fmtstr, hpp_snprint_fn print_fn, 664 enum perf_hpp_fmt_type fmtype); 665 int hpp__fmt_mem_stat(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 666 struct hist_entry *he, enum mem_stat_type mst, 667 const char *fmtstr, hpp_snprint_fn print_fn); 668 669 static inline void advance_hpp(struct perf_hpp *hpp, int inc) 670 { 671 hpp->buf += inc; 672 hpp->size -= inc; 673 } 674 675 static inline size_t perf_hpp__use_color(void) 676 { 677 return !symbol_conf.field_sep; 678 } 679 680 static inline size_t perf_hpp__color_overhead(void) 681 { 682 return perf_hpp__use_color() ? 683 (COLOR_MAXLEN + sizeof(PERF_COLOR_RESET)) * PERF_HPP__MAX_INDEX 684 : 0; 685 } 686 687 struct evlist; 688 689 struct hist_browser_timer { 690 void (*timer)(void *arg); 691 void *arg; 692 int refresh; 693 }; 694 695 enum rstype { 696 A_NORMAL, 697 A_ASM, 698 A_SOURCE 699 }; 700 701 struct block_hist { 702 struct hists block_hists; 703 struct perf_hpp_list block_list; 704 struct perf_hpp_fmt block_fmt; 705 int block_idx; 706 bool valid; 707 struct hist_entry he; 708 }; 709 710 #ifdef HAVE_SLANG_SUPPORT 711 #include "../ui/keysyms.h" 712 void attr_to_script(char *buf, struct perf_event_attr *attr); 713 714 int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, 715 struct hist_browser_timer *hbt); 716 717 int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel, 718 struct hist_browser_timer *hbt); 719 720 int evlist__tui_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt, 721 float min_pcnt, struct perf_env *env, bool warn_lost_event); 722 723 int script_browse(const char *script_opt, struct evsel *evsel); 724 725 void run_script(char *cmd); 726 int res_sample_browse(struct res_sample *res_samples, int num_res, 727 struct evsel *evsel, enum rstype rstype); 728 void res_sample_init(void); 729 730 int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel, 731 float min_percent, struct perf_env *env); 732 #else 733 static inline 734 int evlist__tui_browse_hists(struct evlist *evlist __maybe_unused, 735 const char *help __maybe_unused, 736 struct hist_browser_timer *hbt __maybe_unused, 737 float min_pcnt __maybe_unused, 738 struct perf_env *env __maybe_unused, 739 bool warn_lost_event __maybe_unused) 740 { 741 return 0; 742 } 743 static inline int map_symbol__tui_annotate(struct map_symbol *ms __maybe_unused, 744 struct evsel *evsel __maybe_unused, 745 struct hist_browser_timer *hbt __maybe_unused) 746 { 747 return 0; 748 } 749 750 static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused, 751 struct evsel *evsel __maybe_unused, 752 struct hist_browser_timer *hbt __maybe_unused) 753 { 754 return 0; 755 } 756 757 static inline int script_browse(const char *script_opt __maybe_unused, 758 struct evsel *evsel __maybe_unused) 759 { 760 return 0; 761 } 762 763 static inline int res_sample_browse(struct res_sample *res_samples __maybe_unused, 764 int num_res __maybe_unused, 765 struct evsel *evsel __maybe_unused, 766 enum rstype rstype __maybe_unused) 767 { 768 return 0; 769 } 770 771 static inline void res_sample_init(void) {} 772 773 static inline int block_hists_tui_browse(struct block_hist *bh __maybe_unused, 774 struct evsel *evsel __maybe_unused, 775 float min_percent __maybe_unused, 776 struct perf_env *env __maybe_unused) 777 { 778 return 0; 779 } 780 781 #define K_LEFT -1000 782 #define K_RIGHT -2000 783 #define K_SWITCH_INPUT_DATA -3000 784 #define K_RELOAD -4000 785 #endif 786 787 unsigned int hists__sort_list_width(struct hists *hists); 788 unsigned int hists__overhead_width(struct hists *hists); 789 790 void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, 791 struct perf_sample *sample, bool nonany_branch_mode, 792 u64 *total_cycles, struct evsel *evsel); 793 794 struct option; 795 int parse_filter_percentage(const struct option *opt, const char *arg, int unset); 796 int perf_hist_config(const char *var, const char *value); 797 798 void perf_hpp_list__init(struct perf_hpp_list *list); 799 800 enum hierarchy_move_dir { 801 HMD_NORMAL, 802 HMD_FORCE_SIBLING, 803 HMD_FORCE_CHILD, 804 }; 805 806 struct rb_node *rb_hierarchy_last(struct rb_node *node); 807 struct rb_node *__rb_hierarchy_next(struct rb_node *node, 808 enum hierarchy_move_dir hmd); 809 struct rb_node *rb_hierarchy_prev(struct rb_node *node); 810 811 static inline struct rb_node *rb_hierarchy_next(struct rb_node *node) 812 { 813 return __rb_hierarchy_next(node, HMD_NORMAL); 814 } 815 816 #define HIERARCHY_INDENT 3 817 818 bool hist_entry__has_hierarchy_children(struct hist_entry *he, float limit); 819 int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...); 820 int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...); 821 int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp, 822 struct perf_hpp_list *hpp_list); 823 int hists__fprintf_headers(struct hists *hists, FILE *fp); 824 int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq); 825 826 static inline int hists__scnprintf_title(struct hists *hists, char *bf, size_t size) 827 { 828 return __hists__scnprintf_title(hists, bf, size, true); 829 } 830 831 #endif /* __PERF_HIST_H */ 832