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

Commit 1b2dbbf4 authored by Namhyung Kim's avatar Namhyung Kim Committed by Ingo Molnar
Browse files

perf hists: Use own hpp_list for hierarchy mode



Now each hists has its own hpp lists in hierarchy.  So instead of having
a pointer to a single perf_hpp_fmt in a hist entry, make it point the
hpp_list for its level.  This will be used to support multiple sort keys
in a single hierarchy level.

Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1457361308-514-3-git-send-email-namhyung@kernel.org


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent c3bc0c43
Loading
Loading
Loading
Loading
+25 −20
Original line number Original line Diff line number Diff line
@@ -1388,6 +1388,7 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser,
					      HE_COLORSET_NORMAL);
					      HE_COLORSET_NORMAL);
		}
		}


		perf_hpp_list__for_each_format(entry->hpp_list, fmt) {
			ui_browser__write_nstring(&browser->b, "", 2);
			ui_browser__write_nstring(&browser->b, "", 2);
			width -= 2;
			width -= 2;


@@ -1396,7 +1397,6 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser,
			 * since this fmt is always the last column in the
			 * since this fmt is always the last column in the
			 * hierarchy mode.
			 * hierarchy mode.
			 */
			 */
		fmt = entry->fmt;
			if (fmt->color) {
			if (fmt->color) {
				width -= fmt->color(fmt, &hpp, entry);
				width -= fmt->color(fmt, &hpp, entry);
			} else {
			} else {
@@ -1409,6 +1409,7 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser,
					width++;
					width++;
			}
			}
		}
		}
	}


	/* The scroll bar isn't being used */
	/* The scroll bar isn't being used */
	if (!browser->b.navkeypressed)
	if (!browser->b.navkeypressed)
@@ -1934,7 +1935,7 @@ static int hist_browser__fprintf_hierarchy_entry(struct hist_browser *browser,
	struct perf_hpp_fmt *fmt;
	struct perf_hpp_fmt *fmt;
	bool first = true;
	bool first = true;
	int ret;
	int ret;
	int hierarchy_indent = (nr_sort_keys + 1) * HIERARCHY_INDENT;
	int hierarchy_indent = nr_sort_keys * HIERARCHY_INDENT;


	printed = fprintf(fp, "%*s", level * HIERARCHY_INDENT, "");
	printed = fprintf(fp, "%*s", level * HIERARCHY_INDENT, "");


@@ -1962,9 +1963,13 @@ static int hist_browser__fprintf_hierarchy_entry(struct hist_browser *browser,
	ret = scnprintf(hpp.buf, hpp.size, "%*s", hierarchy_indent, "");
	ret = scnprintf(hpp.buf, hpp.size, "%*s", hierarchy_indent, "");
	advance_hpp(&hpp, ret);
	advance_hpp(&hpp, ret);


	fmt = he->fmt;
	perf_hpp_list__for_each_format(he->hpp_list, fmt) {
		ret = scnprintf(hpp.buf, hpp.size, "  ");
		advance_hpp(&hpp, ret);

		ret = fmt->entry(fmt, &hpp, he);
		ret = fmt->entry(fmt, &hpp, he);
		advance_hpp(&hpp, ret);
		advance_hpp(&hpp, ret);
	}


	printed += fprintf(fp, "%s\n", rtrim(s));
	printed += fprintf(fp, "%s\n", rtrim(s));


+14 −6
Original line number Original line Diff line number Diff line
@@ -412,6 +412,7 @@ static void perf_gtk__add_hierarchy_entries(struct hists *hists,
	for (node = rb_first(root); node; node = rb_next(node)) {
	for (node = rb_first(root); node; node = rb_next(node)) {
		GtkTreeIter iter;
		GtkTreeIter iter;
		float percent;
		float percent;
		char *bf;


		he = rb_entry(node, struct hist_entry, rb_node);
		he = rb_entry(node, struct hist_entry, rb_node);
		if (he->filtered)
		if (he->filtered)
@@ -437,13 +438,20 @@ static void perf_gtk__add_hierarchy_entries(struct hists *hists,
			gtk_tree_store_set(store, &iter, col_idx++, hpp->buf, -1);
			gtk_tree_store_set(store, &iter, col_idx++, hpp->buf, -1);
		}
		}


		fmt = he->fmt;
		bf = hpp->buf;
		perf_hpp_list__for_each_format(he->hpp_list, fmt) {
			int ret;

			if (fmt->color)
			if (fmt->color)
			fmt->color(fmt, hpp, he);
				ret = fmt->color(fmt, hpp, he);
			else
			else
			fmt->entry(fmt, hpp, he);
				ret = fmt->entry(fmt, hpp, he);

			snprintf(hpp->buf + ret, hpp->size - ret, "  ");
			advance_hpp(hpp, ret + 2);
		}


		gtk_tree_store_set(store, &iter, col_idx, rtrim(hpp->buf), -1);
		gtk_tree_store_set(store, &iter, col_idx, rtrim(bf), -1);


		if (!he->leaf) {
		if (!he->leaf) {
			perf_gtk__add_hierarchy_entries(hists, &he->hroot_out,
			perf_gtk__add_hierarchy_entries(hists, &he->hroot_out,
+5 −0
Original line number Original line Diff line number Diff line
@@ -722,6 +722,7 @@ static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt)
	struct perf_hpp_list_node *node = NULL;
	struct perf_hpp_list_node *node = NULL;
	struct perf_hpp_fmt *fmt_copy;
	struct perf_hpp_fmt *fmt_copy;
	bool found = false;
	bool found = false;
	bool skip = perf_hpp__should_skip(fmt, hists);


	list_for_each_entry(node, &hists->hpp_formats, list) {
	list_for_each_entry(node, &hists->hpp_formats, list) {
		if (node->level == fmt->level) {
		if (node->level == fmt->level) {
@@ -735,6 +736,7 @@ static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt)
		if (node == NULL)
		if (node == NULL)
			return -1;
			return -1;


		node->skip = skip;
		node->level = fmt->level;
		node->level = fmt->level;
		perf_hpp_list__init(&node->hpp);
		perf_hpp_list__init(&node->hpp);


@@ -745,6 +747,9 @@ static int add_hierarchy_fmt(struct hists *hists, struct perf_hpp_fmt *fmt)
	if (fmt_copy == NULL)
	if (fmt_copy == NULL)
		return -1;
		return -1;


	if (!skip)
		node->skip = false;

	list_add_tail(&fmt_copy->list, &node->hpp.fields);
	list_add_tail(&fmt_copy->list, &node->hpp.fields);
	list_add_tail(&fmt_copy->sort_list, &node->hpp.sorts);
	list_add_tail(&fmt_copy->sort_list, &node->hpp.sorts);


+22 −22
Original line number Original line Diff line number Diff line
@@ -451,15 +451,14 @@ static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
		advance_hpp(hpp, ret);
		advance_hpp(hpp, ret);
	}
	}


	if (sep)
	if (!sep)
		ret = scnprintf(hpp->buf, hpp->size, "%s", sep);
	else
		ret = scnprintf(hpp->buf, hpp->size, "%*s",
		ret = scnprintf(hpp->buf, hpp->size, "%*s",
				(nr_sort_key - 1) * HIERARCHY_INDENT + 2, "");
				(nr_sort_key - 1) * HIERARCHY_INDENT, "");
	advance_hpp(hpp, ret);
	advance_hpp(hpp, ret);


	printed += fprintf(fp, "%s", buf);
	printed += fprintf(fp, "%s", buf);


	perf_hpp_list__for_each_format(he->hpp_list, fmt) {
		hpp->buf  = buf;
		hpp->buf  = buf;
		hpp->size = size;
		hpp->size = size;


@@ -467,7 +466,6 @@ static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
		 * No need to call hist_entry__snprintf_alignment() since this
		 * No need to call hist_entry__snprintf_alignment() since this
		 * fmt is always the last column in the hierarchy mode.
		 * fmt is always the last column in the hierarchy mode.
		 */
		 */
	fmt = he->fmt;
		if (perf_hpp__use_color() && fmt->color)
		if (perf_hpp__use_color() && fmt->color)
			fmt->color(fmt, hpp, he);
			fmt->color(fmt, hpp, he);
		else
		else
@@ -477,7 +475,9 @@ static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
		 * dynamic entries are right-aligned but we want left-aligned
		 * dynamic entries are right-aligned but we want left-aligned
		 * in the hierarchy mode
		 * in the hierarchy mode
		 */
		 */
	printed += fprintf(fp, "%s\n", ltrim(buf));
		printed += fprintf(fp, "%s%s", sep ?: "  ", ltrim(buf));
	}
	printed += putc('\n', fp);


	if (symbol_conf.use_callchain && he->leaf) {
	if (symbol_conf.use_callchain && he->leaf) {
		u64 total = hists__total_period(hists);
		u64 total = hists__total_period(hists);
+35 −25
Original line number Original line Diff line number Diff line
@@ -1091,18 +1091,25 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he);
static struct hist_entry *hierarchy_insert_entry(struct hists *hists,
static struct hist_entry *hierarchy_insert_entry(struct hists *hists,
						 struct rb_root *root,
						 struct rb_root *root,
						 struct hist_entry *he,
						 struct hist_entry *he,
						 struct perf_hpp_fmt *fmt)
						 struct perf_hpp_list *hpp_list)
{
{
	struct rb_node **p = &root->rb_node;
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;
	struct rb_node *parent = NULL;
	struct hist_entry *iter, *new;
	struct hist_entry *iter, *new;
	struct perf_hpp_fmt *fmt;
	int64_t cmp;
	int64_t cmp;


	while (*p != NULL) {
	while (*p != NULL) {
		parent = *p;
		parent = *p;
		iter = rb_entry(parent, struct hist_entry, rb_node_in);
		iter = rb_entry(parent, struct hist_entry, rb_node_in);


		cmp = 0;
		perf_hpp_list__for_each_sort_list(hpp_list, fmt) {
			cmp = fmt->collapse(fmt, iter, he);
			cmp = fmt->collapse(fmt, iter, he);
			if (cmp)
				break;
		}

		if (!cmp) {
		if (!cmp) {
			he_stat__add_stat(&iter->stat, &he->stat);
			he_stat__add_stat(&iter->stat, &he->stat);
			return iter;
			return iter;
@@ -1121,10 +1128,11 @@ static struct hist_entry *hierarchy_insert_entry(struct hists *hists,
	hists__apply_filters(hists, new);
	hists__apply_filters(hists, new);
	hists->nr_entries++;
	hists->nr_entries++;


	/* save related format for output */
	/* save related format list for output */
	new->fmt = fmt;
	new->hpp_list = hpp_list;


	/* some fields are now passed to 'new' */
	/* some fields are now passed to 'new' */
	perf_hpp_list__for_each_sort_list(hpp_list, fmt) {
		if (perf_hpp__is_trace_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
		if (perf_hpp__is_trace_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
			he->trace_output = NULL;
			he->trace_output = NULL;
		else
		else
@@ -1139,6 +1147,7 @@ static struct hist_entry *hierarchy_insert_entry(struct hists *hists,
			he->srcfile = NULL;
			he->srcfile = NULL;
		else
		else
			new->srcfile = NULL;
			new->srcfile = NULL;
	}


	rb_link_node(&new->rb_node_in, parent, p);
	rb_link_node(&new->rb_node_in, parent, p);
	rb_insert_color(&new->rb_node_in, root);
	rb_insert_color(&new->rb_node_in, root);
@@ -1149,21 +1158,19 @@ static int hists__hierarchy_insert_entry(struct hists *hists,
					 struct rb_root *root,
					 struct rb_root *root,
					 struct hist_entry *he)
					 struct hist_entry *he)
{
{
	struct perf_hpp_fmt *fmt;
	struct perf_hpp_list_node *node;
	struct hist_entry *new_he = NULL;
	struct hist_entry *new_he = NULL;
	struct hist_entry *parent = NULL;
	struct hist_entry *parent = NULL;
	int depth = 0;
	int depth = 0;
	int ret = 0;
	int ret = 0;


	hists__for_each_sort_list(hists, fmt) {
	list_for_each_entry(node, &hists->hpp_formats, list) {
		if (!perf_hpp__is_sort_entry(fmt) &&
		/* skip period (overhead) and elided columns */
		    !perf_hpp__is_dynamic_entry(fmt))
		if (node->level == 0 || node->skip)
			continue;
		if (perf_hpp__should_skip(fmt, hists))
			continue;
			continue;


		/* insert copy of 'he' for each fmt into the hierarchy */
		/* insert copy of 'he' for each fmt into the hierarchy */
		new_he = hierarchy_insert_entry(hists, root, he, fmt);
		new_he = hierarchy_insert_entry(hists, root, he, &node->hpp);
		if (new_he == NULL) {
		if (new_he == NULL) {
			ret = -1;
			ret = -1;
			break;
			break;
@@ -1358,6 +1365,7 @@ static void hierarchy_insert_output_entry(struct rb_root *root,
	struct rb_node **p = &root->rb_node;
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;
	struct rb_node *parent = NULL;
	struct hist_entry *iter;
	struct hist_entry *iter;
	struct perf_hpp_fmt *fmt;


	while (*p != NULL) {
	while (*p != NULL) {
		parent = *p;
		parent = *p;
@@ -1373,8 +1381,10 @@ static void hierarchy_insert_output_entry(struct rb_root *root,
	rb_insert_color(&he->rb_node, root);
	rb_insert_color(&he->rb_node, root);


	/* update column width of dynamic entry */
	/* update column width of dynamic entry */
	if (perf_hpp__is_dynamic_entry(he->fmt))
	perf_hpp_list__for_each_sort_list(he->hpp_list, fmt) {
		he->fmt->sort(he->fmt, he, NULL);
		if (perf_hpp__is_dynamic_entry(fmt))
			fmt->sort(fmt, he, NULL);
	}
}
}


static void hists__hierarchy_output_resort(struct hists *hists,
static void hists__hierarchy_output_resort(struct hists *hists,
Loading