Skip to content

Commit

Permalink
perf hist: Introduce hists class and move lots of methods to it
Browse files Browse the repository at this point in the history
In cbbc79a we introduced support for multiple events by introducing a
new "event_stat_id" struct and then made several perf_session methods
receive a point to it instead of a pointer to perf_session, and kept the
event_stats and hists rb_tree in perf_session.

While working on the new newt based browser, I realised that it would be
better to introduce a new class, "hists" (short for "histograms"),
renaming the "event_stat_id" struct and the perf_session methods that
were really "hists" methods, as they manipulate only struct hists
members, not touching anything in the other perf_session members.

Other optimizations, such as calculating the maximum lenght of a symbol
name present in an hists instance will be possible as we add them,
avoiding a re-traversal just for finding that information.

The rationale for the name "hists" to replace "event_stat_id" is that we
may have multiple sets of hists for the same event_stat id, as, for
instance, the 'perf diff' tool has, so event stat id is not what
characterizes what this struct and the functions that manipulate it do.

Cc: Eric B Munson <ebmunson@us.ibm.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Arnaldo Carvalho de Melo committed May 10, 2010
1 parent d118f8b commit 1c02c4d
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 164 deletions.
17 changes: 8 additions & 9 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip)
return 0;
}

static int perf_session__add_hist_entry(struct perf_session *self,
struct addr_location *al)
static int hists__add_entry(struct hists *self, struct addr_location *al)
{
struct hist_entry *he;

Expand All @@ -112,7 +111,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
return 0;
}

he = __perf_session__add_hist_entry(&self->hists, al, NULL, 1);
he = __hists__add_entry(self, al, NULL, 1);
if (he == NULL)
return -ENOMEM;

Expand All @@ -132,7 +131,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
return -1;
}

if (!al.filtered && perf_session__add_hist_entry(session, &al)) {
if (!al.filtered && hists__add_entry(&session->hists, &al)) {
pr_warning("problem incrementing symbol count, "
"skipping event\n");
return -1;
Expand Down Expand Up @@ -514,11 +513,11 @@ static void annotate_sym(struct hist_entry *he)
free_source_line(he, len);
}

static void perf_session__find_annotations(struct perf_session *self)
static void hists__find_annotations(struct hists *self)
{
struct rb_node *nd;

for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
struct sym_priv *priv;

Expand Down Expand Up @@ -570,9 +569,9 @@ static int __cmd_annotate(void)
if (verbose > 2)
perf_session__fprintf_dsos(session, stdout);

perf_session__collapse_resort(&session->hists);
perf_session__output_resort(&session->hists, session->event_total[0]);
perf_session__find_annotations(session);
hists__collapse_resort(&session->hists);
hists__output_resort(&session->hists);
hists__find_annotations(&session->hists);
out_delete:
perf_session__delete(session);

Expand Down
50 changes: 23 additions & 27 deletions tools/perf/builtin-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ static char diff__default_sort_order[] = "dso,symbol";
static bool force;
static bool show_displacement;

static int perf_session__add_hist_entry(struct perf_session *self,
struct addr_location *al, u64 count)
static int hists__add_entry(struct hists *self,
struct addr_location *al, u64 count)
{
if (__perf_session__add_hist_entry(&self->hists, al, NULL, count) != NULL)
if (__hists__add_entry(self, al, NULL, count) != NULL)
return 0;
return -ENOMEM;
}
Expand All @@ -49,12 +49,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi

event__parse_sample(event, session->sample_type, &data);

if (perf_session__add_hist_entry(session, &al, data.period)) {
if (hists__add_entry(&session->hists, &al, data.period)) {
pr_warning("problem incrementing symbol count, skipping event\n");
return -1;
}

session->events_stats.total += data.period;
session->hists.stats.total += data.period;
return 0;
}

Expand Down Expand Up @@ -87,35 +87,34 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
rb_insert_color(&he->rb_node, root);
}

static void perf_session__resort_hist_entries(struct perf_session *self)
static void hists__resort_entries(struct hists *self)
{
unsigned long position = 1;
struct rb_root tmp = RB_ROOT;
struct rb_node *next = rb_first(&self->hists);
struct rb_node *next = rb_first(&self->entries);

while (next != NULL) {
struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node);

next = rb_next(&n->rb_node);
rb_erase(&n->rb_node, &self->hists);
rb_erase(&n->rb_node, &self->entries);
n->position = position++;
perf_session__insert_hist_entry_by_name(&tmp, n);
}

self->hists = tmp;
self->entries = tmp;
}

static void perf_session__set_hist_entries_positions(struct perf_session *self)
static void hists__set_positions(struct hists *self)
{
perf_session__output_resort(&self->hists, self->events_stats.total);
perf_session__resort_hist_entries(self);
hists__output_resort(self);
hists__resort_entries(self);
}

static struct hist_entry *
perf_session__find_hist_entry(struct perf_session *self,
struct hist_entry *he)
static struct hist_entry *hists__find_entry(struct hists *self,
struct hist_entry *he)
{
struct rb_node *n = self->hists.rb_node;
struct rb_node *n = self->entries.rb_node;

while (n) {
struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node);
Expand All @@ -132,14 +131,13 @@ perf_session__find_hist_entry(struct perf_session *self,
return NULL;
}

static void perf_session__match_hists(struct perf_session *old_session,
struct perf_session *new_session)
static void hists__match(struct hists *older, struct hists *newer)
{
struct rb_node *nd;

for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) {
for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) {
struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node);
pos->pair = perf_session__find_hist_entry(old_session, pos);
pos->pair = hists__find_entry(older, pos);
}
}

Expand All @@ -159,15 +157,13 @@ static int __cmd_diff(void)
goto out_delete;
}

perf_session__output_resort(&session[1]->hists,
session[1]->events_stats.total);
hists__output_resort(&session[1]->hists);
if (show_displacement)
perf_session__set_hist_entries_positions(session[0]);
hists__set_positions(&session[0]->hists);

perf_session__match_hists(session[0], session[1]);
perf_session__fprintf_hists(&session[1]->hists, session[0],
show_displacement, stdout,
session[1]->events_stats.total);
hists__match(&session[0]->hists, &session[1]->hists);
hists__fprintf(&session[1]->hists, &session[0]->hists,
show_displacement, stdout);
out_delete:
for (i = 0; i < 2; ++i)
perf_session__delete(session[i]);
Expand Down
71 changes: 35 additions & 36 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,17 @@ static char *pretty_printing_style = default_pretty_printing_style;

static char callchain_default_opt[] = "fractal,0.5";

static struct event_stat_id *get_stats(struct perf_session *self,
u64 event_stream, u32 type, u64 config)
static struct hists *perf_session__hists_findnew(struct perf_session *self,
u64 event_stream, u32 type,
u64 config)
{
struct rb_node **p = &self->stats_by_id.rb_node;
struct rb_node **p = &self->hists_tree.rb_node;
struct rb_node *parent = NULL;
struct event_stat_id *iter, *new;
struct hists *iter, *new;

while (*p != NULL) {
parent = *p;
iter = rb_entry(parent, struct event_stat_id, rb_node);
iter = rb_entry(parent, struct hists, rb_node);
if (iter->config == config)
return iter;

Expand All @@ -64,15 +65,15 @@ static struct event_stat_id *get_stats(struct perf_session *self,
p = &(*p)->rb_left;
}

new = malloc(sizeof(struct event_stat_id));
new = malloc(sizeof(struct hists));
if (new == NULL)
return NULL;
memset(new, 0, sizeof(struct event_stat_id));
memset(new, 0, sizeof(struct hists));
new->event_stream = event_stream;
new->config = config;
new->type = type;
rb_link_node(&new->rb_node, parent, p);
rb_insert_color(&new->rb_node, &self->stats_by_id);
rb_insert_color(&new->rb_node, &self->hists_tree);
return new;
}

Expand All @@ -84,7 +85,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
struct symbol *parent = NULL;
int err = -ENOMEM;
struct hist_entry *he;
struct event_stat_id *stats;
struct hists *hists;
struct perf_event_attr *attr;

if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) {
Expand All @@ -96,13 +97,12 @@ static int perf_session__add_hist_entry(struct perf_session *self,

attr = perf_header__find_attr(data->id, &self->header);
if (attr)
stats = get_stats(self, data->id, attr->type, attr->config);
hists = perf_session__hists_findnew(self, data->id, attr->type, attr->config);
else
stats = get_stats(self, data->id, 0, 0);
if (stats == NULL)
hists = perf_session__hists_findnew(self, data->id, 0, 0);
if (hists == NULL)
goto out_free_syms;
he = __perf_session__add_hist_entry(&stats->hists, al, parent,
data->period);
he = __hists__add_entry(hists, al, parent, data->period);
if (he == NULL)
goto out_free_syms;
err = 0;
Expand All @@ -117,18 +117,19 @@ static int add_event_total(struct perf_session *session,
struct sample_data *data,
struct perf_event_attr *attr)
{
struct event_stat_id *stats;
struct hists *hists;

if (attr)
stats = get_stats(session, data->id, attr->type, attr->config);
hists = perf_session__hists_findnew(session, data->id,
attr->type, attr->config);
else
stats = get_stats(session, data->id, 0, 0);
hists = perf_session__hists_findnew(session, data->id, 0, 0);

if (!stats)
if (!hists)
return -ENOMEM;

stats->stats.total += data->period;
session->events_stats.total += data->period;
hists->stats.total += data->period;
session->hists.stats.total += data->period;
return 0;
}

Expand Down Expand Up @@ -292,35 +293,33 @@ static int __cmd_report(void)
if (verbose > 2)
perf_session__fprintf_dsos(session, stdout);

next = rb_first(&session->stats_by_id);
next = rb_first(&session->hists_tree);
while (next) {
struct event_stat_id *stats;
struct hists *hists;
u64 nr_hists;

stats = rb_entry(next, struct event_stat_id, rb_node);
perf_session__collapse_resort(&stats->hists);
nr_hists = perf_session__output_resort(&stats->hists,
stats->stats.total);
hists = rb_entry(next, struct hists, rb_node);
hists__collapse_resort(hists);
nr_hists = hists__output_resort(hists);
if (use_browser)
perf_session__browse_hists(&stats->hists, nr_hists,
stats->stats.total, help,
perf_session__browse_hists(&hists->entries, nr_hists,
hists->stats.total, help,
input_name);
else {
if (rb_first(&session->stats_by_id) ==
rb_last(&session->stats_by_id))
if (rb_first(&session->hists.entries) ==
rb_last(&session->hists.entries))
fprintf(stdout, "# Samples: %Ld\n#\n",
stats->stats.total);
hists->stats.total);
else
fprintf(stdout, "# Samples: %Ld %s\n#\n",
stats->stats.total,
__event_name(stats->type, stats->config));
hists->stats.total,
__event_name(hists->type, hists->config));

perf_session__fprintf_hists(&stats->hists, NULL, false, stdout,
stats->stats.total);
hists__fprintf(hists, NULL, false, stdout);
fprintf(stdout, "\n\n");
}

next = rb_next(&stats->rb_node);
next = rb_next(&hists->rb_node);
}

if (!use_browser && sort_order == default_sort_order &&
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
data.time, thread->comm);
}

session->events_stats.total += data.period;
session->hists.stats.total += data.period;
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ int event__process_comm(event_t *self, struct perf_session *session)
int event__process_lost(event_t *self, struct perf_session *session)
{
dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
session->events_stats.lost += self->lost.lost;
session->hists.stats.lost += self->lost.lost;
return 0;
}

Expand Down
14 changes: 0 additions & 14 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,20 +131,6 @@ typedef union event_union {
struct build_id_event build_id;
} event_t;

struct events_stats {
u64 total;
u64 lost;
};

struct event_stat_id {
struct rb_node rb_node;
struct rb_root hists;
struct events_stats stats;
u64 config;
u64 event_stream;
u32 type;
};

void event__print_totals(void);

struct perf_session;
Expand Down
Loading

0 comments on commit 1c02c4d

Please sign in to comment.