Commit 9b561be1 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf annotate-data: Add hist_entry__annotate_data_tty()



And move the related code into util/annotate-data.c file.

Reviewed-by: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240411033256.2099646-4-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d9aedc12
Loading
Loading
Loading
Loading
+1 −105
Original line number Diff line number Diff line
@@ -329,108 +329,6 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
	return symbol__tty_annotate2(&he->ms, evsel);
}

static void print_annotated_data_header(struct hist_entry *he, struct evsel *evsel)
{
	struct dso *dso = map__dso(he->ms.map);
	int nr_members = 1;
	int nr_samples = he->stat.nr_events;
	int width = 7;
	const char *val_hdr = "Percent";

	if (evsel__is_group_event(evsel)) {
		struct hist_entry *pair;

		list_for_each_entry(pair, &he->pairs.head, pairs.node)
			nr_samples += pair->stat.nr_events;
	}

	printf("Annotate type: '%s' in %s (%d samples):\n",
	       he->mem_type->self.type_name, dso->name, nr_samples);

	if (evsel__is_group_event(evsel)) {
		struct evsel *pos;
		int i = 0;

		for_each_group_evsel(pos, evsel)
			printf(" event[%d] = %s\n", i++, pos->name);

		nr_members = evsel->core.nr_members;
	}

	if (symbol_conf.show_total_period) {
		width = 11;
		val_hdr = "Period";
	} else if (symbol_conf.show_nr_samples) {
		width = 7;
		val_hdr = "Samples";
	}

	printf("============================================================================\n");
	printf("%*s %10s %10s  %s\n", (width + 1) * nr_members, val_hdr,
	       "offset", "size", "field");
}

static void print_annotated_data_value(struct type_hist *h, u64 period, int nr_samples)
{
	double percent = h->period ? (100.0 * period / h->period) : 0;
	const char *color = get_percent_color(percent);

	if (symbol_conf.show_total_period)
		color_fprintf(stdout, color, " %11" PRIu64, period);
	else if (symbol_conf.show_nr_samples)
		color_fprintf(stdout, color, " %7d", nr_samples);
	else
		color_fprintf(stdout, color, " %7.2f", percent);
}

static void print_annotated_data_type(struct annotated_data_type *mem_type,
				      struct annotated_member *member,
				      struct evsel *evsel, int indent)
{
	struct annotated_member *child;
	struct type_hist *h = mem_type->histograms[evsel->core.idx];
	int i, nr_events = 1, samples = 0;
	u64 period = 0;
	int width = symbol_conf.show_total_period ? 11 : 7;

	for (i = 0; i < member->size; i++) {
		samples += h->addr[member->offset + i].nr_samples;
		period += h->addr[member->offset + i].period;
	}
	print_annotated_data_value(h, period, samples);

	if (evsel__is_group_event(evsel)) {
		struct evsel *pos;

		for_each_group_member(pos, evsel) {
			h = mem_type->histograms[pos->core.idx];

			samples = 0;
			period = 0;
			for (i = 0; i < member->size; i++) {
				samples += h->addr[member->offset + i].nr_samples;
				period += h->addr[member->offset + i].period;
			}
			print_annotated_data_value(h, period, samples);
		}
		nr_events = evsel->core.nr_members;
	}

	printf(" %10d %10d  %*s%s\t%s",
	       member->offset, member->size, indent, "", member->type_name,
	       member->var_name ?: "");

	if (!list_empty(&member->children))
		printf(" {\n");

	list_for_each_entry(child, &member->children, node)
		print_annotated_data_type(mem_type, child, evsel, indent + 4);

	if (!list_empty(&member->children))
		printf("%*s}", (width + 1) * nr_events + 24 + indent, "");
	printf(";\n");
}

static void print_annotate_data_stat(struct annotated_data_stat *s)
{
#define PRINT_STAT(fld) if (s->fld) printf("%10d : %s\n", s->fld, #fld)
@@ -571,9 +469,7 @@ static void hists__find_annotations(struct hists *hists,
					goto find_next;
			}

			print_annotated_data_header(he, evsel);
			print_annotated_data_type(he->mem_type, &he->mem_type->self, evsel, 0);
			printf("\n");
			hist_entry__annotate_data_tty(he, evsel);
			goto find_next;
		}

+112 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "evlist.h"
#include "map.h"
#include "map_symbol.h"
#include "sort.h"
#include "strbuf.h"
#include "symbol.h"
#include "symbol_conf.h"
@@ -1710,3 +1711,114 @@ int annotated_data_type__update_samples(struct annotated_data_type *adt,
	h->addr[offset].period += period;
	return 0;
}

static void print_annotated_data_header(struct hist_entry *he, struct evsel *evsel)
{
	struct dso *dso = map__dso(he->ms.map);
	int nr_members = 1;
	int nr_samples = he->stat.nr_events;
	int width = 7;
	const char *val_hdr = "Percent";

	if (evsel__is_group_event(evsel)) {
		struct hist_entry *pair;

		list_for_each_entry(pair, &he->pairs.head, pairs.node)
			nr_samples += pair->stat.nr_events;
	}

	printf("Annotate type: '%s' in %s (%d samples):\n",
	       he->mem_type->self.type_name, dso->name, nr_samples);

	if (evsel__is_group_event(evsel)) {
		struct evsel *pos;
		int i = 0;

		for_each_group_evsel(pos, evsel)
			printf(" event[%d] = %s\n", i++, pos->name);

		nr_members = evsel->core.nr_members;
	}

	if (symbol_conf.show_total_period) {
		width = 11;
		val_hdr = "Period";
	} else if (symbol_conf.show_nr_samples) {
		width = 7;
		val_hdr = "Samples";
	}

	printf("============================================================================\n");
	printf("%*s %10s %10s  %s\n", (width + 1) * nr_members, val_hdr,
	       "offset", "size", "field");
}

static void print_annotated_data_value(struct type_hist *h, u64 period, int nr_samples)
{
	double percent = h->period ? (100.0 * period / h->period) : 0;
	const char *color = get_percent_color(percent);

	if (symbol_conf.show_total_period)
		color_fprintf(stdout, color, " %11" PRIu64, period);
	else if (symbol_conf.show_nr_samples)
		color_fprintf(stdout, color, " %7d", nr_samples);
	else
		color_fprintf(stdout, color, " %7.2f", percent);
}

static void print_annotated_data_type(struct annotated_data_type *mem_type,
				      struct annotated_member *member,
				      struct evsel *evsel, int indent)
{
	struct annotated_member *child;
	struct type_hist *h = mem_type->histograms[evsel->core.idx];
	int i, nr_events = 1, samples = 0;
	u64 period = 0;
	int width = symbol_conf.show_total_period ? 11 : 7;

	for (i = 0; i < member->size; i++) {
		samples += h->addr[member->offset + i].nr_samples;
		period += h->addr[member->offset + i].period;
	}
	print_annotated_data_value(h, period, samples);

	if (evsel__is_group_event(evsel)) {
		struct evsel *pos;

		for_each_group_member(pos, evsel) {
			h = mem_type->histograms[pos->core.idx];

			samples = 0;
			period = 0;
			for (i = 0; i < member->size; i++) {
				samples += h->addr[member->offset + i].nr_samples;
				period += h->addr[member->offset + i].period;
			}
			print_annotated_data_value(h, period, samples);
		}
		nr_events = evsel->core.nr_members;
	}

	printf(" %10d %10d  %*s%s\t%s",
	       member->offset, member->size, indent, "", member->type_name,
	       member->var_name ?: "");

	if (!list_empty(&member->children))
		printf(" {\n");

	list_for_each_entry(child, &member->children, node)
		print_annotated_data_type(mem_type, child, evsel, indent + 4);

	if (!list_empty(&member->children))
		printf("%*s}", (width + 1) * nr_events + 24 + indent, "");
	printf(";\n");
}

int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evsel)
{
	print_annotated_data_header(he, evsel);
	print_annotated_data_type(he->mem_type, &he->mem_type->self, evsel, 0);
	printf("\n");

	return 0;
}
+9 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
struct annotated_op_loc;
struct debuginfo;
struct evsel;
struct hist_entry;
struct map_symbol;
struct thread;

@@ -156,6 +157,8 @@ void annotated_data_type__tree_delete(struct rb_root *root);
/* Release all global variable information in the tree */
void global_var_type__tree_delete(struct rb_root *root);

int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evsel);

#else /* HAVE_DWARF_SUPPORT */

static inline struct annotated_data_type *
@@ -182,6 +185,12 @@ static inline void global_var_type__tree_delete(struct rb_root *root __maybe_unu
{
}

static inline int hist_entry__annotate_data_tty(struct hist_entry *he __maybe_unused,
						struct evsel *evsel __maybe_unused)
{
	return -1;
}

#endif /* HAVE_DWARF_SUPPORT */

#endif /* _PERF_ANNOTATE_DATA_H */