diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-09 12:02:23 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-09 12:10:39 -0400 |
commit | 28e2a106d16046ca792722795f809e3f80a5af80 (patch) | |
tree | c84149ddf45d02044187fe4511cead93d009b6ee | |
parent | 39d1e1b1e26dc84d40bf2792287d0d61e44b57df (diff) |
perf hist: Simplify the insertion of new hist_entry instances
And with that fix at least one bug:
The first hit for an entry, the one that calls malloc to create a new
instance in __perf_session__add_hist_entry, wasn't adding the count to
the per cpumode (PERF_RECORD_MISC_USER, etc) total variable.
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>
-rw-r--r-- | tools/perf/builtin-annotate.c | 9 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 14 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 12 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 36 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 5 |
5 files changed, 32 insertions, 44 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index ee154b58772b..c7ac45a59ed5 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -72,8 +72,6 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
72 | struct sym_priv *priv; | 72 | struct sym_priv *priv; |
73 | struct sym_hist *h; | 73 | struct sym_hist *h; |
74 | 74 | ||
75 | he->count++; | ||
76 | |||
77 | if (!sym || !he->ms.map) | 75 | if (!sym || !he->ms.map) |
78 | return 0; | 76 | return 0; |
79 | 77 | ||
@@ -99,9 +97,8 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
99 | } | 97 | } |
100 | 98 | ||
101 | static int perf_session__add_hist_entry(struct perf_session *self, | 99 | static int perf_session__add_hist_entry(struct perf_session *self, |
102 | struct addr_location *al, u64 count) | 100 | struct addr_location *al) |
103 | { | 101 | { |
104 | bool hit; | ||
105 | struct hist_entry *he; | 102 | struct hist_entry *he; |
106 | 103 | ||
107 | if (sym_hist_filter != NULL && | 104 | if (sym_hist_filter != NULL && |
@@ -115,7 +112,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
115 | return 0; | 112 | return 0; |
116 | } | 113 | } |
117 | 114 | ||
118 | he = __perf_session__add_hist_entry(&self->hists, al, NULL, count, &hit); | 115 | he = __perf_session__add_hist_entry(&self->hists, al, NULL, 1); |
119 | if (he == NULL) | 116 | if (he == NULL) |
120 | return -ENOMEM; | 117 | return -ENOMEM; |
121 | 118 | ||
@@ -135,7 +132,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
135 | return -1; | 132 | return -1; |
136 | } | 133 | } |
137 | 134 | ||
138 | if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) { | 135 | if (!al.filtered && perf_session__add_hist_entry(session, &al)) { |
139 | pr_warning("problem incrementing symbol count, " | 136 | pr_warning("problem incrementing symbol count, " |
140 | "skipping event\n"); | 137 | "skipping event\n"); |
141 | return -1; | 138 | return -1; |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 4cce68f23686..613a5c4f6d83 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -25,17 +25,9 @@ static bool show_displacement; | |||
25 | static int perf_session__add_hist_entry(struct perf_session *self, | 25 | static int perf_session__add_hist_entry(struct perf_session *self, |
26 | struct addr_location *al, u64 count) | 26 | struct addr_location *al, u64 count) |
27 | { | 27 | { |
28 | bool hit; | 28 | if (__perf_session__add_hist_entry(&self->hists, al, NULL, count) != NULL) |
29 | struct hist_entry *he = __perf_session__add_hist_entry(&self->hists, | 29 | return 0; |
30 | al, NULL, | 30 | return -ENOMEM; |
31 | count, &hit); | ||
32 | if (he == NULL) | ||
33 | return -ENOMEM; | ||
34 | |||
35 | if (hit) | ||
36 | __perf_session__add_count(he, al, count); | ||
37 | |||
38 | return 0; | ||
39 | } | 31 | } |
40 | 32 | ||
41 | static int diff__process_sample_event(event_t *event, struct perf_session *session) | 33 | static int diff__process_sample_event(event_t *event, struct perf_session *session) |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3a70c5807c04..5e2f47f88ec6 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -82,7 +82,6 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
82 | { | 82 | { |
83 | struct map_symbol *syms = NULL; | 83 | struct map_symbol *syms = NULL; |
84 | struct symbol *parent = NULL; | 84 | struct symbol *parent = NULL; |
85 | bool hit; | ||
86 | int err = -ENOMEM; | 85 | int err = -ENOMEM; |
87 | struct hist_entry *he; | 86 | struct hist_entry *he; |
88 | struct event_stat_id *stats; | 87 | struct event_stat_id *stats; |
@@ -103,19 +102,12 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
103 | if (stats == NULL) | 102 | if (stats == NULL) |
104 | goto out_free_syms; | 103 | goto out_free_syms; |
105 | he = __perf_session__add_hist_entry(&stats->hists, al, parent, | 104 | he = __perf_session__add_hist_entry(&stats->hists, al, parent, |
106 | data->period, &hit); | 105 | data->period); |
107 | if (he == NULL) | 106 | if (he == NULL) |
108 | goto out_free_syms; | 107 | goto out_free_syms; |
109 | |||
110 | if (hit) | ||
111 | __perf_session__add_count(he, al, data->period); | ||
112 | |||
113 | err = 0; | 108 | err = 0; |
114 | if (symbol_conf.use_callchain) { | 109 | if (symbol_conf.use_callchain) |
115 | if (!hit) | ||
116 | callchain_init(he->callchain); | ||
117 | err = append_chain(he->callchain, data->callchain, syms); | 110 | err = append_chain(he->callchain, data->callchain, syms); |
118 | } | ||
119 | out_free_syms: | 111 | out_free_syms: |
120 | free(syms); | 112 | free(syms); |
121 | return err; | 113 | return err; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index ad6b22dde27f..e0c8a722e11f 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -8,13 +8,10 @@ struct callchain_param callchain_param = { | |||
8 | .min_percent = 0.5 | 8 | .min_percent = 0.5 |
9 | }; | 9 | }; |
10 | 10 | ||
11 | void __perf_session__add_count(struct hist_entry *he, | 11 | static void perf_session__add_cpumode_count(struct hist_entry *he, |
12 | struct addr_location *al, | 12 | unsigned int cpumode, u64 count) |
13 | u64 count) | ||
14 | { | 13 | { |
15 | he->count += count; | 14 | switch (cpumode) { |
16 | |||
17 | switch (al->cpumode) { | ||
18 | case PERF_RECORD_MISC_KERNEL: | 15 | case PERF_RECORD_MISC_KERNEL: |
19 | he->count_sys += count; | 16 | he->count_sys += count; |
20 | break; | 17 | break; |
@@ -36,10 +33,24 @@ void __perf_session__add_count(struct hist_entry *he, | |||
36 | * histogram, sorted on item, collects counts | 33 | * histogram, sorted on item, collects counts |
37 | */ | 34 | */ |
38 | 35 | ||
36 | static struct hist_entry *hist_entry__new(struct hist_entry *template) | ||
37 | { | ||
38 | size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_node) : 0; | ||
39 | struct hist_entry *self = malloc(sizeof(*self) + callchain_size); | ||
40 | |||
41 | if (self != NULL) { | ||
42 | *self = *template; | ||
43 | if (symbol_conf.use_callchain) | ||
44 | callchain_init(self->callchain); | ||
45 | } | ||
46 | |||
47 | return self; | ||
48 | } | ||
49 | |||
39 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 50 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, |
40 | struct addr_location *al, | 51 | struct addr_location *al, |
41 | struct symbol *sym_parent, | 52 | struct symbol *sym_parent, |
42 | u64 count, bool *hit) | 53 | u64 count) |
43 | { | 54 | { |
44 | struct rb_node **p = &hists->rb_node; | 55 | struct rb_node **p = &hists->rb_node; |
45 | struct rb_node *parent = NULL; | 56 | struct rb_node *parent = NULL; |
@@ -64,8 +75,8 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
64 | cmp = hist_entry__cmp(&entry, he); | 75 | cmp = hist_entry__cmp(&entry, he); |
65 | 76 | ||
66 | if (!cmp) { | 77 | if (!cmp) { |
67 | *hit = true; | 78 | he->count += count; |
68 | return he; | 79 | goto out; |
69 | } | 80 | } |
70 | 81 | ||
71 | if (cmp < 0) | 82 | if (cmp < 0) |
@@ -74,14 +85,13 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
74 | p = &(*p)->rb_right; | 85 | p = &(*p)->rb_right; |
75 | } | 86 | } |
76 | 87 | ||
77 | he = malloc(sizeof(*he) + (symbol_conf.use_callchain ? | 88 | he = hist_entry__new(&entry); |
78 | sizeof(struct callchain_node) : 0)); | ||
79 | if (!he) | 89 | if (!he) |
80 | return NULL; | 90 | return NULL; |
81 | *he = entry; | ||
82 | rb_link_node(&he->rb_node, parent, p); | 91 | rb_link_node(&he->rb_node, parent, p); |
83 | rb_insert_color(&he->rb_node, hists); | 92 | rb_insert_color(&he->rb_node, hists); |
84 | *hit = false; | 93 | out: |
94 | perf_session__add_cpumode_count(he, al->cpumode, count); | ||
85 | return he; | 95 | return he; |
86 | } | 96 | } |
87 | 97 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 9df1c340ec92..b49013adb34b 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -12,13 +12,10 @@ struct addr_location; | |||
12 | struct symbol; | 12 | struct symbol; |
13 | struct rb_root; | 13 | struct rb_root; |
14 | 14 | ||
15 | void __perf_session__add_count(struct hist_entry *he, | ||
16 | struct addr_location *al, | ||
17 | u64 count); | ||
18 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 15 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, |
19 | struct addr_location *al, | 16 | struct addr_location *al, |
20 | struct symbol *parent, | 17 | struct symbol *parent, |
21 | u64 count, bool *hit); | 18 | u64 count); |
22 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | 19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); |
23 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | 20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); |
24 | int hist_entry__fprintf(struct hist_entry *self, | 21 | int hist_entry__fprintf(struct hist_entry *self, |