Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e2fc44f authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarNamhyung Kim <namhyung@kernel.org>
Acked-by: default avatarPekka 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent ef86d68a
Loading
Loading
Loading
Loading
+105 −0
Original line number Diff line number Diff line
@@ -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;
+9 −0
Original line number Diff line number Diff line
@@ -31,9 +31,18 @@ unsigned char sane_ctype[256] = {
};

const char *graph_line =
	"_____________________________________________________________________"
	"_____________________________________________________________________"
	"_____________________________________________________________________";
const char *graph_dotted_line =
	"---------------------------------------------------------------------"
	"---------------------------------------------------------------------"
	"---------------------------------------------------------------------";
const char *spaces =
	"                                                                     "
	"                                                                     "
	"                                                                     ";
const char *dots =
	"....................................................................."
	"....................................................................."
	".....................................................................";
+2 −0
Original line number Diff line number Diff line
@@ -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