Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf ui/stdio: Align column header for hierarchy output

The hierarchy output mode is to group entries so the existing columns
won't fit to the new output. Treat all sort keys as a single column and
separate headers by "/".

# Overhead Command / Shared Object
# ........... ................................
#
15.11% swapper
14.97% [kernel.vmlinux]
0.09% [libahci]
0.05% [iwlwifi]
...

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-11-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
8e2fc44f ef86d68a

+116
+105
tools/perf/ui/stdio/hist.c
··· 511 511 return ret; 512 512 } 513 513 514 + static int print_hierarchy_indent(const char *sep, int nr_sort, 515 + const char *line, FILE *fp) 516 + { 517 + if (sep != NULL || nr_sort < 1) 518 + return 0; 519 + 520 + return fprintf(fp, "%-.*s", (nr_sort - 1) * HIERARCHY_INDENT, line); 521 + } 522 + 523 + static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, 524 + const char *sep, FILE *fp) 525 + { 526 + bool first = true; 527 + int nr_sort; 528 + unsigned width = 0; 529 + unsigned header_width = 0; 530 + struct perf_hpp_fmt *fmt; 531 + 532 + nr_sort = hists->hpp_list->nr_sort_keys; 533 + 534 + /* preserve max indent depth for column headers */ 535 + print_hierarchy_indent(sep, nr_sort, spaces, fp); 536 + 537 + hists__for_each_format(hists, fmt) { 538 + if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt)) 539 + break; 540 + 541 + if (!first) 542 + fprintf(fp, "%s", sep ?: " "); 543 + else 544 + first = false; 545 + 546 + fmt->header(fmt, hpp, hists_to_evsel(hists)); 547 + fprintf(fp, "%s", hpp->buf); 548 + } 549 + 550 + /* combine sort headers with ' / ' */ 551 + first = true; 552 + hists__for_each_format(hists, fmt) { 553 + if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt)) 554 + continue; 555 + if (perf_hpp__should_skip(fmt, hists)) 556 + continue; 557 + 558 + if (!first) 559 + header_width += fprintf(fp, " / "); 560 + else { 561 + header_width += fprintf(fp, "%s", sep ?: " "); 562 + first = false; 563 + } 564 + 565 + fmt->header(fmt, hpp, hists_to_evsel(hists)); 566 + rtrim(hpp->buf); 567 + 568 + header_width += fprintf(fp, "%s", hpp->buf); 569 + } 570 + 571 + /* preserve max indent depth for combined sort headers */ 572 + print_hierarchy_indent(sep, nr_sort, spaces, fp); 573 + 574 + fprintf(fp, "\n# "); 575 + 576 + /* preserve max indent depth for initial dots */ 577 + print_hierarchy_indent(sep, nr_sort, dots, fp); 578 + 579 + first = true; 580 + hists__for_each_format(hists, fmt) { 581 + if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt)) 582 + break; 583 + 584 + if (!first) 585 + fprintf(fp, "%s", sep ?: " "); 586 + else 587 + first = false; 588 + 589 + width = fmt->width(fmt, hpp, hists_to_evsel(hists)); 590 + fprintf(fp, "%.*s", width, dots); 591 + } 592 + 593 + hists__for_each_format(hists, fmt) { 594 + if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt)) 595 + continue; 596 + if (perf_hpp__should_skip(fmt, hists)) 597 + continue; 598 + 599 + width = fmt->width(fmt, hpp, hists_to_evsel(hists)); 600 + if (width > header_width) 601 + header_width = width; 602 + } 603 + 604 + fprintf(fp, "%s%-.*s", sep ?: " ", header_width, dots); 605 + 606 + /* preserve max indent depth for dots under sort headers */ 607 + print_hierarchy_indent(sep, nr_sort, dots, fp); 608 + 609 + fprintf(fp, "\n#\n"); 610 + 611 + return 2; 612 + } 613 + 514 614 size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 515 615 int max_cols, float min_pcnt, FILE *fp) 516 616 { ··· 641 541 goto print_entries; 642 542 643 543 fprintf(fp, "# "); 544 + 545 + if (symbol_conf.report_hierarchy) { 546 + nr_rows += print_hierarchy_header(hists, &dummy_hpp, sep, fp); 547 + goto print_entries; 548 + } 644 549 645 550 hists__for_each_format(hists, fmt) { 646 551 if (perf_hpp__should_skip(fmt, hists))
+9
tools/perf/util/ctype.c
··· 32 32 33 33 const char *graph_line = 34 34 "_____________________________________________________________________" 35 + "_____________________________________________________________________" 35 36 "_____________________________________________________________________"; 36 37 const char *graph_dotted_line = 37 38 "---------------------------------------------------------------------" 38 39 "---------------------------------------------------------------------" 39 40 "---------------------------------------------------------------------"; 41 + const char *spaces = 42 + " " 43 + " " 44 + " "; 45 + const char *dots = 46 + "....................................................................." 47 + "....................................................................." 48 + ".....................................................................";
+2
tools/perf/util/util.h
··· 82 82 83 83 extern const char *graph_line; 84 84 extern const char *graph_dotted_line; 85 + extern const char *spaces; 86 + extern const char *dots; 85 87 extern char buildid_dir[]; 86 88 87 89 /* On most systems <limits.h> would have given us this, but