aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/stdio/hist.c
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2016-02-24 10:13:41 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-02-24 18:21:12 -0500
commitef86d68a088c324e4bd85f82387d1f9a571affd0 (patch)
treee66c0b0d4906207cfac3cc9e8948e554fe49b2bd /tools/perf/ui/stdio/hist.c
parent1f2d72cf3258eacd667cd1920e64c9b64b9984d5 (diff)
perf ui/stdio: Implement hierarchy output mode
The hierarchy output mode is to group entries for each level so that user can see higher level picture more easily. It also helps to find out which component is most costly. The output will look like below: 15.11% swapper 14.97% [kernel.vmlinux] 0.09% [libahci] 0.05% [iwlwifi] 10.29% irq/33-iwlwifi 6.45% [kernel.vmlinux] 1.41% [mac80211] 1.15% [iwldvm] 1.14% [iwlwifi] 0.14% [cfg80211] 4.81% firefox 3.92% libxul.so 0.34% [kernel.vmlinux] Signed-off-by: Namhyung Kim <namhyung@kernel.org> Acked-by: Pekka Enberg <penberg@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/r/1456326830-30456-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/stdio/hist.c')
-rw-r--r--tools/perf/ui/stdio/hist.c79
1 files changed, 78 insertions, 1 deletions
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 87b022ff03d8..90b86776f964 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -410,6 +410,76 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
410 return hpp->buf - start; 410 return hpp->buf - start;
411} 411}
412 412
413static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
414 struct perf_hpp *hpp,
415 int nr_sort_key, struct hists *hists,
416 FILE *fp)
417{
418 const char *sep = symbol_conf.field_sep;
419 struct perf_hpp_fmt *fmt;
420 char *buf = hpp->buf;
421 int ret, printed = 0;
422 bool first = true;
423
424 if (symbol_conf.exclude_other && !he->parent)
425 return 0;
426
427 ret = scnprintf(hpp->buf, hpp->size, "%*s", he->depth * HIERARCHY_INDENT, "");
428 advance_hpp(hpp, ret);
429
430 hists__for_each_format(he->hists, fmt) {
431 if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
432 break;
433
434 /*
435 * If there's no field_sep, we still need
436 * to display initial ' '.
437 */
438 if (!sep || !first) {
439 ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: " ");
440 advance_hpp(hpp, ret);
441 } else
442 first = false;
443
444 if (perf_hpp__use_color() && fmt->color)
445 ret = fmt->color(fmt, hpp, he);
446 else
447 ret = fmt->entry(fmt, hpp, he);
448
449 ret = hist_entry__snprintf_alignment(he, hpp, fmt, ret);
450 advance_hpp(hpp, ret);
451 }
452
453 if (sep)
454 ret = scnprintf(hpp->buf, hpp->size, "%s", sep);
455 else
456 ret = scnprintf(hpp->buf, hpp->size, "%*s",
457 (nr_sort_key - 1) * HIERARCHY_INDENT + 2, "");
458 advance_hpp(hpp, ret);
459
460 /*
461 * No need to call hist_entry__snprintf_alignment() since this
462 * fmt is always the last column in the hierarchy mode.
463 */
464 fmt = he->fmt;
465 if (perf_hpp__use_color() && fmt->color)
466 fmt->color(fmt, hpp, he);
467 else
468 fmt->entry(fmt, hpp, he);
469
470 printed += fprintf(fp, "%s\n", buf);
471
472 if (symbol_conf.use_callchain && he->leaf) {
473 u64 total = hists__total_period(hists);
474
475 printed += hist_entry_callchain__fprintf(he, total, 0, fp);
476 goto out;
477 }
478
479out:
480 return printed;
481}
482
413static int hist_entry__fprintf(struct hist_entry *he, size_t size, 483static int hist_entry__fprintf(struct hist_entry *he, size_t size,
414 struct hists *hists, 484 struct hists *hists,
415 char *bf, size_t bfsz, FILE *fp) 485 char *bf, size_t bfsz, FILE *fp)
@@ -424,6 +494,13 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
424 if (size == 0 || size > bfsz) 494 if (size == 0 || size > bfsz)
425 size = hpp.size = bfsz; 495 size = hpp.size = bfsz;
426 496
497 if (symbol_conf.report_hierarchy) {
498 int nr_sort = hists->hpp_list->nr_sort_keys;
499
500 return hist_entry__hierarchy_fprintf(he, &hpp, nr_sort,
501 hists, fp);
502 }
503
427 hist_entry__snprintf(he, &hpp); 504 hist_entry__snprintf(he, &hpp);
428 505
429 ret = fprintf(fp, "%s\n", bf); 506 ret = fprintf(fp, "%s\n", bf);
@@ -522,7 +599,7 @@ print_entries:
522 goto out; 599 goto out;
523 } 600 }
524 601
525 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { 602 for (nd = rb_first(&hists->entries); nd; nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD)) {
526 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 603 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
527 float percent; 604 float percent;
528 605