perf annotate-data: Add hist_entry__annotate_data_tty()
And move the related code into util/annotate-data.c file. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung 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: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d9aedc12d3
commit
9b561be15f
@ -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 @@ find_next:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user