summaryrefslogtreecommitdiff
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-05-10 13:04:11 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-05-10 13:13:49 -0300
commit1c02c4d2e92f2097f1bba63ec71560b0e05a7f36 (patch)
treead2a722931398ce3cd3ae850c4cfa148558a52ea /tools/perf/util
parentd118f8ba6ac2af2bf11d40cba657c813f0f39ca2 (diff)
perf hist: Introduce hists class and move lots of methods to it
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>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/event.c2
-rw-r--r--tools/perf/util/event.h14
-rw-r--r--tools/perf/util/hist.c92
-rw-r--r--tools/perf/util/hist.h48
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/perf/util/session.h12
6 files changed, 79 insertions, 91 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d2ea9dd9fdf1..cce006ec8f05 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -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;
}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 6cc1b1dced55..48c2cc9dae4f 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -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;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 0f154a530dfd..410cf56c9662 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -8,21 +8,21 @@ struct callchain_param callchain_param = {
.min_percent = 0.5
};
-static void perf_session__add_cpumode_count(struct hist_entry *he,
- unsigned int cpumode, u64 count)
+static void hist_entry__add_cpumode_count(struct hist_entry *self,
+ unsigned int cpumode, u64 count)
{
switch (cpumode) {
case PERF_RECORD_MISC_KERNEL:
- he->count_sys += count;
+ self->count_sys += count;
break;
case PERF_RECORD_MISC_USER:
- he->count_us += count;
+ self->count_us += count;
break;
case PERF_RECORD_MISC_GUEST_KERNEL:
- he->count_guest_sys += count;
+ self->count_guest_sys += count;
break;
case PERF_RECORD_MISC_GUEST_USER:
- he->count_guest_us += count;
+ self->count_guest_us += count;
break;
default:
break;
@@ -47,12 +47,11 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
return self;
}
-struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
- struct addr_location *al,
- struct symbol *sym_parent,
- u64 count)
+struct hist_entry *__hists__add_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *sym_parent, u64 count)
{
- struct rb_node **p = &hists->rb_node;
+ struct rb_node **p = &self->entries.rb_node;
struct rb_node *parent = NULL;
struct hist_entry *he;
struct hist_entry entry = {
@@ -89,9 +88,9 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
if (!he)
return NULL;
rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, hists);
+ rb_insert_color(&he->rb_node, &self->entries);
out:
- perf_session__add_cpumode_count(he, al->cpumode, count);
+ hist_entry__add_cpumode_count(he, al->cpumode, count);
return he;
}
@@ -167,7 +166,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
rb_insert_color(&he->rb_node, root);
}
-void perf_session__collapse_resort(struct rb_root *hists)
+void hists__collapse_resort(struct hists *self)
{
struct rb_root tmp;
struct rb_node *next;
@@ -177,28 +176,28 @@ void perf_session__collapse_resort(struct rb_root *hists)
return;
tmp = RB_ROOT;
- next = rb_first(hists);
+ next = rb_first(&self->entries);
while (next) {
n = rb_entry(next, struct hist_entry, rb_node);
next = rb_next(&n->rb_node);
- rb_erase(&n->rb_node, hists);
+ rb_erase(&n->rb_node, &self->entries);
collapse__insert_entry(&tmp, n);
}
- *hists = tmp;
+ self->entries = tmp;
}
/*
* reverse the map, sort on count.
*/
-static void perf_session__insert_output_hist_entry(struct rb_root *root,
- struct hist_entry *he,
- u64 min_callchain_hits)
+static void __hists__insert_output_entry(struct rb_root *entries,
+ struct hist_entry *he,
+ u64 min_callchain_hits)
{
- struct rb_node **p = &root->rb_node;
+ struct rb_node **p = &entries->rb_node;
struct rb_node *parent = NULL;
struct hist_entry *iter;
@@ -217,10 +216,10 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
}
rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, root);
+ rb_insert_color(&he->rb_node, entries);
}
-u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples)
+u64 hists__output_resort(struct hists *self)
{
struct rb_root tmp;
struct rb_node *next;
@@ -228,23 +227,21 @@ u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples)
u64 min_callchain_hits;
u64 nr_hists = 0;
- min_callchain_hits =
- total_samples * (callchain_param.min_percent / 100);
+ min_callchain_hits = self->stats.total * (callchain_param.min_percent / 100);
tmp = RB_ROOT;
- next = rb_first(hists);
+ next = rb_first(&self->entries);
while (next) {
n = rb_entry(next, struct hist_entry, rb_node);
next = rb_next(&n->rb_node);
- rb_erase(&n->rb_node, hists);
- perf_session__insert_output_hist_entry(&tmp, n,
- min_callchain_hits);
+ rb_erase(&n->rb_node, &self->entries);
+ __hists__insert_output_entry(&tmp, n, min_callchain_hits);
++nr_hists;
}
- *hists = tmp;
+ self->entries = tmp;
return nr_hists;
}
@@ -500,12 +497,9 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
return ret;
}
-int hist_entry__snprintf(struct hist_entry *self,
- char *s, size_t size,
- struct perf_session *pair_session,
- bool show_displacement,
- long displacement, bool color,
- u64 session_total)
+int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
+ struct hists *pair_hists, bool show_displacement,
+ long displacement, bool color, u64 session_total)
{
struct sort_entry *se;
u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us;
@@ -515,9 +509,9 @@ int hist_entry__snprintf(struct hist_entry *self,
if (symbol_conf.exclude_other && !self->parent)
return 0;
- if (pair_session) {
+ if (pair_hists) {
count = self->pair ? self->pair->count : 0;
- total = pair_session->events_stats.total;
+ total = pair_hists->stats.total;
count_sys = self->pair ? self->pair->count_sys : 0;
count_us = self->pair ? self->pair->count_us : 0;
count_guest_sys = self->pair ? self->pair->count_guest_sys : 0;
@@ -569,7 +563,7 @@ int hist_entry__snprintf(struct hist_entry *self,
ret += snprintf(s + ret, size - ret, "%11lld", count);
}
- if (pair_session) {
+ if (pair_hists) {
char bf[32];
double old_percent = 0, new_percent = 0, diff;
@@ -615,14 +609,12 @@ int hist_entry__snprintf(struct hist_entry *self,
return ret;
}
-int hist_entry__fprintf(struct hist_entry *self,
- struct perf_session *pair_session,
- bool show_displacement,
- long displacement, FILE *fp,
+int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
+ bool show_displacement, long displacement, FILE *fp,
u64 session_total)
{
char bf[512];
- hist_entry__snprintf(self, bf, sizeof(bf), pair_session,
+ hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
show_displacement, displacement,
true, session_total);
return fprintf(fp, "%s\n", bf);
@@ -644,10 +636,8 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
left_margin);
}
-size_t perf_session__fprintf_hists(struct rb_root *hists,
- struct perf_session *pair,
- bool show_displacement, FILE *fp,
- u64 session_total)
+size_t hists__fprintf(struct hists *self, struct hists *pair,
+ bool show_displacement, FILE *fp)
{
struct sort_entry *se;
struct rb_node *nd;
@@ -753,7 +743,7 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
fprintf(fp, "\n#\n");
print_entries:
- for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
+ for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
if (show_displacement) {
@@ -765,10 +755,10 @@ print_entries:
++position;
}
ret += hist_entry__fprintf(h, pair, show_displacement,
- displacement, fp, session_total);
+ displacement, fp, self->stats.total);
if (symbol_conf.use_callchain)
- ret += hist_entry__fprintf_callchain(h, fp, session_total);
+ ret += hist_entry__fprintf_callchain(h, fp, self->stats.total);
if (h->ms.map == NULL && verbose > 1) {
__map_groups__fprintf_maps(&h->thread->mg,
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index b49013adb34b..bdde81eca69f 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -6,34 +6,40 @@
extern struct callchain_param callchain_param;
-struct perf_session;
struct hist_entry;
struct addr_location;
struct symbol;
struct rb_root;
-struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
- struct addr_location *al,
- struct symbol *parent,
- u64 count);
+struct events_stats {
+ u64 total;
+ u64 lost;
+};
+
+struct hists {
+ struct rb_node rb_node;
+ struct rb_root entries;
+ struct events_stats stats;
+ u64 config;
+ u64 event_stream;
+ u32 type;
+};
+
+struct hist_entry *__hists__add_entry(struct hists *self,
+ struct addr_location *al,
+ struct symbol *parent, u64 count);
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
-int hist_entry__fprintf(struct hist_entry *self,
- struct perf_session *pair_session,
- bool show_displacement,
- long displacement, FILE *fp,
- u64 session_total);
-int hist_entry__snprintf(struct hist_entry *self,
- char *bf, size_t size,
- struct perf_session *pair_session,
- bool show_displacement, long displacement,
- bool color, u64 session_total);
+int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
+ bool show_displacement, long displacement, FILE *fp,
+ u64 total);
+int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
+ struct hists *pair_hists, bool show_displacement,
+ long displacement, bool color, u64 total);
void hist_entry__free(struct hist_entry *);
-u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples);
-void perf_session__collapse_resort(struct rb_root *hists);
-size_t perf_session__fprintf_hists(struct rb_root *hists,
- struct perf_session *pair,
- bool show_displacement, FILE *fp,
- u64 session_total);
+u64 hists__output_resort(struct hists *self);
+void hists__collapse_resort(struct hists *self);
+size_t hists__fprintf(struct hists *self, struct hists *pair,
+ bool show_displacement, FILE *fp);
#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4130036a0109..72a7f6ae0293 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -89,7 +89,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
memcpy(self->filename, filename, len);
self->threads = RB_ROOT;
- self->stats_by_id = RB_ROOT;
+ self->hists_tree = RB_ROOT;
self->last_match = NULL;
self->mmap_window = 32;
self->cwd = NULL;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 242d528bfae2..46190f94b547 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -1,6 +1,7 @@
#ifndef __PERF_SESSION_H
#define __PERF_SESSION_H
+#include "hist.h"
#include "event.h"
#include "header.h"
#include "symbol.h"
@@ -28,11 +29,16 @@ struct perf_session {
struct thread *last_match;
struct machine host_machine;
struct rb_root machines;
- struct events_stats events_stats;
- struct rb_root stats_by_id;
+ struct rb_root hists_tree;
unsigned long event_total[PERF_RECORD_MAX];
unsigned long unknown_events;
- struct rb_root hists;
+ /*
+ * FIXME: should point to the first entry in hists_tree and
+ * be a hists instance. Right now its only 'report'
+ * that is using ->hists_tree while all the rest use
+ * ->hists.
+ */
+ struct hists hists;
u64 sample_type;
int fd;
bool fd_pipe;