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>
This commit is contained in:
Namhyung Kim 2016-02-25 00:13:42 +09:00 committed by Arnaldo Carvalho de Melo
parent ef86d68a08
commit 8e2fc44f46
3 changed files with 116 additions and 0 deletions

View File

@ -511,6 +511,106 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
return ret;
}
static int print_hierarchy_indent(const char *sep, int nr_sort,
const char *line, FILE *fp)
{
if (sep != NULL || nr_sort < 1)
return 0;
return fprintf(fp, "%-.*s", (nr_sort - 1) * HIERARCHY_INDENT, line);
}
static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
const char *sep, FILE *fp)
{
bool first = true;
int nr_sort;
unsigned width = 0;
unsigned header_width = 0;
struct perf_hpp_fmt *fmt;
nr_sort = hists->hpp_list->nr_sort_keys;
/* preserve max indent depth for column headers */
print_hierarchy_indent(sep, nr_sort, spaces, fp);
hists__for_each_format(hists, fmt) {
if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
break;
if (!first)
fprintf(fp, "%s", sep ?: " ");
else
first = false;
fmt->header(fmt, hpp, hists_to_evsel(hists));
fprintf(fp, "%s", hpp->buf);
}
/* combine sort headers with ' / ' */
first = true;
hists__for_each_format(hists, fmt) {
if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
continue;
if (perf_hpp__should_skip(fmt, hists))
continue;
if (!first)
header_width += fprintf(fp, " / ");
else {
header_width += fprintf(fp, "%s", sep ?: " ");
first = false;
}
fmt->header(fmt, hpp, hists_to_evsel(hists));
rtrim(hpp->buf);
header_width += fprintf(fp, "%s", hpp->buf);
}
/* preserve max indent depth for combined sort headers */
print_hierarchy_indent(sep, nr_sort, spaces, fp);
fprintf(fp, "\n# ");
/* preserve max indent depth for initial dots */
print_hierarchy_indent(sep, nr_sort, dots, fp);
first = true;
hists__for_each_format(hists, fmt) {
if (perf_hpp__is_sort_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
break;
if (!first)
fprintf(fp, "%s", sep ?: " ");
else
first = false;
width = fmt->width(fmt, hpp, hists_to_evsel(hists));
fprintf(fp, "%.*s", width, dots);
}
hists__for_each_format(hists, fmt) {
if (!perf_hpp__is_sort_entry(fmt) && !perf_hpp__is_dynamic_entry(fmt))
continue;
if (perf_hpp__should_skip(fmt, hists))
continue;
width = fmt->width(fmt, hpp, hists_to_evsel(hists));
if (width > header_width)
header_width = width;
}
fprintf(fp, "%s%-.*s", sep ?: " ", header_width, dots);
/* preserve max indent depth for dots under sort headers */
print_hierarchy_indent(sep, nr_sort, dots, fp);
fprintf(fp, "\n#\n");
return 2;
}
size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
int max_cols, float min_pcnt, FILE *fp)
{
@ -542,6 +642,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
fprintf(fp, "# ");
if (symbol_conf.report_hierarchy) {
nr_rows += print_hierarchy_header(hists, &dummy_hpp, sep, fp);
goto print_entries;
}
hists__for_each_format(hists, fmt) {
if (perf_hpp__should_skip(fmt, hists))
continue;

View File

@ -31,9 +31,18 @@ unsigned char sane_ctype[256] = {
};
const char *graph_line =
"_____________________________________________________________________"
"_____________________________________________________________________"
"_____________________________________________________________________";
const char *graph_dotted_line =
"---------------------------------------------------------------------"
"---------------------------------------------------------------------"
"---------------------------------------------------------------------";
const char *spaces =
" "
" "
" ";
const char *dots =
"....................................................................."
"....................................................................."
".....................................................................";

View File

@ -82,6 +82,8 @@
extern const char *graph_line;
extern const char *graph_dotted_line;
extern const char *spaces;
extern const char *dots;
extern char buildid_dir[];
/* On most systems <limits.h> would have given us this, but