4 #include <linux/compiler.h> 6 #include "../util/hist.h" 7 #include "../util/util.h" 8 #include "../util/sort.h" 9 #include "../util/evsel.h" 10 #include "../util/evlist.h" 14 #define hpp__call_print_fn(hpp, fn, fmt, ...) \ 16 int __ret = fn(hpp, fmt, ##__VA_ARGS__); \ 17 advance_hpp(hpp, __ret); \ 36 percent = 100.0 * get_field(he) / total;
43 int prev_idx, idx_delta;
50 u64 period = get_field(pair);
75 100.0 * period / total);
84 idx_delta = nr_members - prev_idx - 1;
117 return __hpp__fmt(hpp, he, get_field, fmtstr, 1,
118 print_fn, fmt_percent);
126 return __hpp__fmt(hpp, he, get_field, fmtstr, len, print_fn, fmt_percent);
135 return snprintf(hpp->
buf, hpp->
size,
" %*s", len - 1,
"N/A");
138 return hpp__fmt(fmt, hpp, he, get_field, fmtstr, print_fn, fmt_percent);
143 if (field_a > field_b)
145 if (field_a < field_b)
157 u64 *fields_a, *fields_b;
159 ret =
field_cmp(get_field(a), get_field(b));
168 fields_a = calloc(nr_members,
sizeof(*fields_a));
169 fields_b = calloc(nr_members,
sizeof(*fields_b));
171 if (!fields_a || !fields_b)
184 for (i = 1; i < nr_members; i++) {
185 ret =
field_cmp(fields_a[i], fields_b[i]);
206 ret =
field_cmp(get_field(a), get_field(b));
221 struct perf_hpp *hpp __maybe_unused,
230 if (len < (
int)strlen(fmt->
name))
231 len = strlen(fmt->
name);
238 int *span __maybe_unused)
241 return scnprintf(hpp->
buf, hpp->
size,
"%*s", len, fmt->
name);
247 ssize_t ssize = hpp->
size;
252 len = va_arg(args,
int);
253 percent = va_arg(args,
double);
257 return (ret >= ssize) ? (ssize - 1) : ret;
263 ssize_t ssize = hpp->
size;
267 ret = vsnprintf(hpp->
buf, hpp->
size, fmt, args);
270 return (ret >= ssize) ? (ssize - 1) : ret;
273 #define __HPP_COLOR_PERCENT_FN(_type, _field) \ 274 static u64 he_get_##_field(struct hist_entry *he) \ 276 return he->stat._field; \ 279 static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ 280 struct perf_hpp *hpp, struct hist_entry *he) \ 282 return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ 283 hpp_color_scnprintf, true); \ 286 #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ 287 static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ 288 struct perf_hpp *hpp, struct hist_entry *he) \ 290 return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ 291 hpp_entry_scnprintf, true); \ 294 #define __HPP_SORT_FN(_type, _field) \ 295 static int64_t hpp__sort_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ 296 struct hist_entry *a, struct hist_entry *b) \ 298 return __hpp__sort(a, b, he_get_##_field); \ 301 #define __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ 302 static u64 he_get_acc_##_field(struct hist_entry *he) \ 304 return he->stat_acc->_field; \ 307 static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ 308 struct perf_hpp *hpp, struct hist_entry *he) \ 310 return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ 311 hpp_color_scnprintf, true); \ 314 #define __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ 315 static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ 316 struct perf_hpp *hpp, struct hist_entry *he) \ 318 return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ 319 hpp_entry_scnprintf, true); \ 322 #define __HPP_SORT_ACC_FN(_type, _field) \ 323 static int64_t hpp__sort_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ 324 struct hist_entry *a, struct hist_entry *b) \ 326 return __hpp__sort_acc(a, b, he_get_acc_##_field); \ 329 #define __HPP_ENTRY_RAW_FN(_type, _field) \ 330 static u64 he_get_raw_##_field(struct hist_entry *he) \ 332 return he->stat._field; \ 335 static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ 336 struct perf_hpp *hpp, struct hist_entry *he) \ 338 return hpp__fmt(fmt, hpp, he, he_get_raw_##_field, " %*"PRIu64, \ 339 hpp_entry_scnprintf, false); \ 342 #define __HPP_SORT_RAW_FN(_type, _field) \ 343 static int64_t hpp__sort_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ 344 struct hist_entry *a, struct hist_entry *b) \ 346 return __hpp__sort(a, b, he_get_raw_##_field); \ 350 #define HPP_PERCENT_FNS(_type, _field) \ 351 __HPP_COLOR_PERCENT_FN(_type, _field) \ 352 __HPP_ENTRY_PERCENT_FN(_type, _field) \ 353 __HPP_SORT_FN(_type, _field) 355 #define HPP_PERCENT_ACC_FNS(_type, _field) \ 356 __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ 357 __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ 358 __HPP_SORT_ACC_FN(_type, _field) 360 #define HPP_RAW_FNS(_type, _field) \ 361 __HPP_ENTRY_RAW_FN(_type, _field) \ 362 __HPP_SORT_RAW_FN(_type, _field) 394 #define HPP__COLOR_PRINT_FNS(_name, _fn, _idx) \ 397 .header = hpp__header_fn, \ 398 .width = hpp__width_fn, \ 399 .color = hpp__color_ ## _fn, \ 400 .entry = hpp__entry_ ## _fn, \ 401 .cmp = hpp__nop_cmp, \ 402 .collapse = hpp__nop_cmp, \ 403 .sort = hpp__sort_ ## _fn, \ 404 .idx = PERF_HPP__ ## _idx, \ 405 .equal = hpp__equal, \ 408 #define HPP__COLOR_ACC_PRINT_FNS(_name, _fn, _idx) \ 411 .header = hpp__header_fn, \ 412 .width = hpp__width_fn, \ 413 .color = hpp__color_ ## _fn, \ 414 .entry = hpp__entry_ ## _fn, \ 415 .cmp = hpp__nop_cmp, \ 416 .collapse = hpp__nop_cmp, \ 417 .sort = hpp__sort_ ## _fn, \ 418 .idx = PERF_HPP__ ## _idx, \ 419 .equal = hpp__equal, \ 422 #define HPP__PRINT_FNS(_name, _fn, _idx) \ 425 .header = hpp__header_fn, \ 426 .width = hpp__width_fn, \ 427 .entry = hpp__entry_ ## _fn, \ 428 .cmp = hpp__nop_cmp, \ 429 .collapse = hpp__nop_cmp, \ 430 .sort = hpp__sort_ ## _fn, \ 431 .idx = PERF_HPP__ ## _idx, \ 432 .equal = hpp__equal, \ 448 .sorts = LIST_HEAD_INIT(perf_hpp_list.
sorts),
449 .nr_header_lines = 1,
452 #undef HPP__COLOR_PRINT_FNS 453 #undef HPP__COLOR_ACC_PRINT_FNS 454 #undef HPP__PRINT_FNS 456 #undef HPP_PERCENT_FNS 457 #undef HPP_PERCENT_ACC_FNS 460 #undef __HPP_HEADER_FN 461 #undef __HPP_WIDTH_FN 462 #undef __HPP_COLOR_PERCENT_FN 463 #undef __HPP_ENTRY_PERCENT_FN 464 #undef __HPP_COLOR_ACC_PERCENT_FN 465 #undef __HPP_ENTRY_ACC_PERCENT_FN 466 #undef __HPP_ENTRY_RAW_FN 468 #undef __HPP_SORT_ACC_FN 469 #undef __HPP_SORT_RAW_FN 479 INIT_LIST_HEAD(&fmt->
list);
536 list_del_init(&format->
list);
550 if (acc->
equal(acc, fmt)) {
555 if (ovh->
equal(ovh, fmt))
556 fmt->
name =
"Overhead";
614 BUG_ON(!list_empty(&fmt->
list));
627 list_del_init(&fmt->
list);
634 list_del_init(&fmt->
list);
659 ret += fmt->
width(fmt, &dummy_hpp, hists);
663 ret += 3 + BITS_PER_LONG / 4;
684 ret += fmt->
width(fmt, &dummy_hpp, hists);
741 const char *ptr = width_list_str;
746 int len = strtol(ptr, &p, 10);
771 node =
malloc(
sizeof(*node));
784 if (fmt_copy == NULL)
void perf_hpp__setup_output_field(struct perf_hpp_list *list)
bool is_strict_order(const char *order)
int(* width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hists *hists)
bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *format)
void perf_hpp__cancel_cumulate(void)
static bool fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
u64(* hpp_field_fn)(struct hist_entry *he)
u64 hists__total_period(struct hists *hists)
int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent)
static void skip(int size)
static bool perf_hpp__should_skip(struct perf_hpp_fmt *format, struct hists *hists)
int(* entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he)
void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists)
static bool perf_hpp__is_hpp_entry(struct perf_hpp_fmt *a)
void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list, struct perf_hpp_fmt *format)
#define HPP__COLOR_PRINT_FNS(_name, _fn, _idx)
void perf_hpp_list__register_sort_field(struct perf_hpp_list *list, struct perf_hpp_fmt *format)
struct list_head sort_list
#define HPP_RAW_FNS(_type, _field)
bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format)
static struct hists * evsel__hists(struct perf_evsel *evsel)
void(* free)(struct perf_hpp_fmt *fmt)
void perf_hpp__init(void)
#define perf_hpp_list__for_each_sort_list_safe(_list, format, tmp)
static void perf_hpp__column_register(struct perf_hpp_fmt *format)
#define perf_hpp_list__for_each_format(_list, format)
struct callchain_root callchain[0]
struct list_head hpp_formats
void hists__reset_column_width(struct hists *hists)
static void perf_hpp__register_sort_field(struct perf_hpp_fmt *format)
bool(* equal)(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
static __pure bool hist_entry__has_callchains(struct hist_entry *he)
int(* header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hists *hists, int line, int *span)
#define HPP_PERCENT_FNS(_type, _field)
struct perf_hpp_fmt * perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt)
static struct perf_evsel * hists_to_evsel(struct hists *hists)
static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, hpp_field_fn get_field)
int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent)
static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, const char *fmt, int len, hpp_snprint_fn print_fn, bool fmt_percent)
void perf_hpp__append_sort_keys(struct perf_hpp_list *list)
#define evlist__for_each_entry(evlist, evsel)
static int hpp__header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hists *hists, int line __maybe_unused, int *span __maybe_unused)
void perf_hpp__column_unregister(struct perf_hpp_fmt *format)
void perf_hpp__reset_output_field(struct perf_hpp_list *list)
int perf_hpp__setup_hists_formats(struct perf_hpp_list *list, struct perf_evlist *evlist)
static int field_cmp(u64 field_a, u64 field_b)
#define hists__has(__h, __f)
static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt)
struct perf_hpp_fmt perf_hpp__format[]
int(* hpp_snprint_fn)(struct perf_hpp *hpp, const char *fmt,...)
static int64_t hpp__nop_cmp(struct perf_hpp_fmt *fmt __maybe_unused, struct hist_entry *a __maybe_unused, struct hist_entry *b __maybe_unused)
unsigned int hists__sort_list_width(struct hists *hists)
static int hpp__width_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp __maybe_unused, struct hists *hists)
#define hpp__call_print_fn(hpp, fn, fmt,...)
static int perf_evsel__group_idx(struct perf_evsel *evsel)
#define HPP__PRINT_FNS(_name, _fn, _idx)
bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists)
#define HPP__COLOR_ACC_PRINT_FNS(_name, _fn, _idx)
#define hists__for_each_format(hists, format)
static int sym(yyscan_t scanner, int type, int config)
int hpp_dimension__add_output(unsigned col)
int(* color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he)
static double percent(int st, int tot)
void perf_hpp_list__column_register(struct perf_hpp_list *list, struct perf_hpp_fmt *format)
unsigned int hists__overhead_width(struct hists *hists)
void perf_hpp_list__init(struct perf_hpp_list *list)
static bool hpp__equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
static bool perf_evsel__is_group_event(struct perf_evsel *evsel)
void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists)
#define HPP_PERCENT_ACC_FNS(_type, _field)
static void fmt_free(struct perf_hpp_fmt *fmt)
int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt,...)
void perf_hpp__set_user_width(const char *width_list_str)
int percent_color_len_snprintf(char *bf, size_t size, const char *fmt,...)
#define perf_hpp_list__for_each_format_safe(_list, format, tmp)
static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b, hpp_field_fn get_field)
static int hpp_entry_scnprintf(struct perf_hpp *hpp, const char *fmt,...)
bool show_cpu_utilization
union hist_entry::@139 pairs
#define perf_hpp_list__for_each_sort_list(_list, format)