3 #include <linux/string.h> 5 #include "../../util/util.h" 6 #include "../../util/hist.h" 7 #include "../../util/sort.h" 8 #include "../../util/evsel.h" 9 #include "../../util/srcline.h" 10 #include "../../util/string2.h" 11 #include "../../util/thread.h" 12 #include "../../util/sane_ctype.h" 17 int ret = fprintf(fp,
" ");
19 for (i = 0; i < left_margin; i++)
20 ret += fprintf(fp,
" ");
31 for (i = 0; i < depth; i++)
32 if (depth_mask & (1 << i))
33 ret += fprintf(fp,
"| ");
35 ret += fprintf(fp,
" ");
37 ret += fprintf(fp,
"\n");
44 int depth,
int depth_mask,
int period,
45 u64 total_samples,
int left_margin)
49 char bf[1024], *alloc_str = NULL;
54 for (i = 0; i < depth; i++) {
55 if (depth_mask & (1 << i))
56 ret += fprintf(fp,
"|");
58 ret += fprintf(fp,
" ");
59 if (!period && i == depth - 1) {
60 ret += fprintf(fp,
"--");
62 ret += fprintf(fp,
"--");
64 ret += fprintf(fp,
"%s",
" ");
73 if (asprintf(&alloc_str,
"%s%s", str, buf) < 0)
74 str =
"Not enough memory!";
91 rem_sq_bracket =
malloc(
sizeof(*rem_sq_bracket) + 6);
92 if (!rem_sq_bracket) {
93 fprintf(stderr,
"Not enough memory to display remaining hits\n");
97 strcpy(rem_sq_bracket->
name,
"[...]");
102 u64 total_samples,
int depth,
103 int depth_mask,
int left_margin)
105 struct rb_node *
node, *next;
108 int new_depth_mask = depth_mask;
112 uint entries_printed = 0;
115 remaining = total_samples;
117 node = rb_first(root);
134 next = rb_next(node);
136 new_depth_mask &= ~(1 << (depth - 1));
145 list_for_each_entry(chain, &child->
val,
list) {
155 new_total = total_samples;
159 new_depth_mask | (1 << depth),
167 remaining && remaining != total_samples) {
177 if (rem_node.
count <= 0)
181 new_depth_mask &= ~(1 << (depth - 1));
183 new_depth_mask, 0, total_samples,
210 u64 total_samples, u64 parent_samples,
215 u32 entries_printed = 0;
216 bool printed =
false;
217 struct rb_node *
node;
222 node = rb_first(root);
225 list_for_each_entry(chain, &cnode->
val, list) {
237 ret += fprintf(fp,
"|\n");
239 ret += fprintf(fp,
"---");
245 ret += fprintf(fp,
"%s",
253 ret += fprintf(fp,
"\n");
262 total_samples = parent_samples;
268 ret += fprintf(fp,
"\n");
287 list_for_each_entry(chain, &node->
val,
list) {
288 if (chain->
ip >= PERF_CONTEXT_MAX)
291 bf,
sizeof(bf),
false));
301 u32 entries_printed = 0;
303 struct rb_node *rb_node = rb_first(tree);
308 ret += fprintf(fp,
" ");
310 ret += fprintf(fp,
"\n");
312 ret += fprintf(fp,
"\n");
316 rb_node = rb_next(rb_node);
336 list_for_each_entry(chain, &node->
val,
list) {
337 if (chain->
ip >= PERF_CONTEXT_MAX)
339 ret += fprintf(fp,
"%s%s", first ?
"" : sep,
341 bf,
sizeof(bf),
false));
352 u32 entries_printed = 0;
354 struct rb_node *rb_node = rb_first(tree);
361 ret += fprintf(fp,
" ");
363 ret += fprintf(fp,
"\n");
367 rb_node = rb_next(rb_node);
374 u64 total_samples,
int left_margin,
385 parent_samples, left_margin);
389 parent_samples, left_margin);
400 pr_err(
"Bad callchain mode\n");
426 if (!sep || !first) {
427 ret = scnprintf(hpp->
buf, hpp->
size,
"%s", sep ?:
" ");
433 ret = fmt->
color(fmt, hpp, he);
435 ret = fmt->
entry(fmt, hpp, he);
457 char *buf = hpp->
buf;
459 int ret, printed = 0;
476 if (!sep || !first) {
477 ret = scnprintf(hpp->
buf, hpp->
size,
"%s", sep ?:
" ");
483 ret = fmt->
color(fmt, hpp, he);
485 ret = fmt->
entry(fmt, hpp, he);
492 ret = scnprintf(hpp->
buf, hpp->
size,
"%*s",
496 printed += fprintf(fp,
"%s", buf);
507 fmt->
color(fmt, hpp, he);
509 fmt->
entry(fmt, hpp, he);
515 printed += fprintf(fp,
"%s%s", sep ?:
" ",
ltrim(buf));
517 printed += putc(
'\n', fp);
531 char *bf,
size_t bfsz, FILE *fp,
535 int callchain_ret = 0;
543 if (size == 0 || size > bfsz)
544 size = hpp.
size = bfsz;
551 ret = fprintf(fp,
"%s\n", bf);
557 ret += callchain_ret;
563 const char *line, FILE *fp)
565 if (sep != NULL || indent < 2)
574 bool first_node, first_col;
578 unsigned header_width = 0;
593 fmt->
header(fmt, hpp, hists, 0, NULL);
594 fprintf(fp,
"%s%s", hpp->
buf, sep ?:
" ");
601 header_width += fprintf(fp,
" / ");
610 header_width += fprintf(fp,
"+");
613 fmt->
header(fmt, hpp, hists, 0, NULL);
615 header_width += fprintf(fp,
"%s",
trim(hpp->
buf));
631 fprintf(fp,
"%s", sep ?:
"..");
634 width = fmt->
width(fmt, hpp, hists);
635 fprintf(fp,
"%.*s", width,
dots);
651 width += fmt->
width(fmt, hpp, hists);
654 if (width > header_width)
655 header_width = width;
660 fprintf(fp,
"%s%-.*s", sep ?:
" ", header_width,
dots);
662 fprintf(fp,
"\n#\n");
680 fprintf(fp,
"%s", sep ?:
" ");
684 fmt->
header(fmt, hpp, hists, line, &span);
687 fprintf(fp,
"%s", hpp->
buf);
725 fprintf(fp,
"%s", sep ?:
" ");
729 width = fmt->
width(fmt, hpp, hists);
730 for (i = 0; i <
width; i++)
757 int max_cols,
float min_pcnt, FILE *fp,
778 if (max_rows && nr_rows >= max_rows)
799 if (percent < min_pcnt)
804 if (max_rows && ++nr_rows >= max_rows)
815 fprintf(fp,
"%*sno entry >= %.2f%%\n", indent,
"", min_pcnt);
817 if (max_rows && ++nr_rows >= max_rows)
829 zfree(&rem_sq_bracket);
843 if (!strcmp(name,
"UNKNOWN"))
846 ret += fprintf(fp,
"%16s events: %10d\n", name, stats->
nr_events[i]);
int callchain_node__fprintf_value(struct callchain_node *node, FILE *fp, u64 total)
const char * col_width_list_str
int(* width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hists *hists)
u64 hists__total_period(struct hists *hists)
static void init_rem_hits(void)
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)
const char * graph_dotted_line
int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp, struct perf_hpp_fmt *fmt, int printed)
char * callchain_list__sym_name(struct callchain_list *cl, char *bf, size_t bfsize, bool show_dso)
struct perf_hpp_list * hpp_list
static size_t callchain__fprintf_folded(FILE *fp, struct rb_root *tree, u64 total_samples)
static struct callchain_list rem_hits
static size_t hist_entry_callchain__fprintf(struct hist_entry *he, u64 total_samples, int left_margin, FILE *fp)
static struct symbol * rem_sq_bracket
static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, int left_margin)
static void fprintf_line(struct hists *hists, struct perf_hpp *hpp, int line, FILE *fp)
static unsigned callchain_cumul_counts(struct callchain_node *node)
static char * trim(char *s)
#define perf_hpp_list__for_each_format(_list, format)
int callchain_list_counts__printf_value(struct callchain_list *clist, FILE *fp, char *bf, int bfsize)
struct list_head hpp_formats
static int hists__fprintf_hierarchy_headers(struct hists *hists, struct perf_hpp *hpp, FILE *fp)
int hists__fprintf_headers(struct hists *hists, FILE *fp)
void hists__reset_column_width(struct hists *hists)
static __pure bool hist_entry__has_callchains(struct hist_entry *he)
static int print_hierarchy_indent(const char *sep, int indent, const char *line, FILE *fp)
int(* header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hists *hists, int line, int *span)
static int hist_entry__hierarchy_fprintf(struct hist_entry *he, struct perf_hpp *hpp, struct hists *hists, FILE *fp)
static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, u64 total_samples, int depth, int depth_mask, int left_margin)
size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
struct callchain_node * parent
static int str(yyscan_t scanner, int token)
struct rb_root sorted_chain
bool hist_entry__has_hierarchy_children(struct hist_entry *he, float limit)
unsigned int children_count
const char * perf_event__name(unsigned int id)
static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
static size_t __callchain__fprintf_folded(FILE *fp, struct callchain_node *node)
unsigned int hists__sort_list_width(struct hists *hists)
int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp, struct perf_hpp_list *hpp_list)
size_t events_stats__fprintf(struct events_stats *stats, FILE *fp)
static int hist_entry__fprintf(struct hist_entry *he, size_t size, char *bf, size_t bfsz, FILE *fp, bool use_callchain)
static size_t perf_hpp__color_overhead(void)
static size_t __callchain__fprintf_flat(FILE *fp, struct callchain_node *node, u64 total_samples)
static bool need_percent_display(struct rb_node *node, u64 parent_samples)
struct rb_node * __rb_hierarchy_next(struct rb_node *node, enum hierarchy_move_dir hmd)
#define hists__for_each_format(hists, format)
bool show_branchflag_count
int(* color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he)
static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
static void advance_hpp(struct perf_hpp *hpp, int inc)
static double percent(int st, int tot)
unsigned int hists__overhead_width(struct hists *hists)
static int hists__fprintf_standard_headers(struct hists *hists, struct perf_hpp *hpp, FILE *fp)
struct perf_hpp_list * hpp_list
struct events_stats stats
u32 nr_events[PERF_RECORD_HEADER_MAX]
static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, u64 total_samples, u64 parent_samples, int left_margin)
static size_t perf_hpp__use_color(void)
struct he_stat * stat_acc
static u64 callchain_cumul_hits(struct callchain_node *node)
void perf_hpp__set_user_width(const char *width_list_str)
size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp, bool use_callchain)
static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node, struct callchain_list *chain, int depth, int depth_mask, int period, u64 total_samples, int left_margin)
static float hist_entry__get_percent_limit(struct hist_entry *he)
static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *tree, u64 total_samples)