aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-05-09 12:02:23 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-05-09 12:10:39 -0400
commit28e2a106d16046ca792722795f809e3f80a5af80 (patch)
treec84149ddf45d02044187fe4511cead93d009b6ee
parent39d1e1b1e26dc84d40bf2792287d0d61e44b57df (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.c9
-rw-r--r--tools/perf/builtin-diff.c14
-rw-r--r--tools/perf/builtin-report.c12
-rw-r--r--tools/perf/util/hist.c36
-rw-r--r--tools/perf/util/hist.h5
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
101static int perf_session__add_hist_entry(struct perf_session *self, 99static 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;
25static int perf_session__add_hist_entry(struct perf_session *self, 25static 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
41static int diff__process_sample_event(event_t *event, struct perf_session *session) 33static 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 }
119out_free_syms: 111out_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
11void __perf_session__add_count(struct hist_entry *he, 11static 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
36static 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
39struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, 50struct 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; 93out:
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;
12struct symbol; 12struct symbol;
13struct rb_root; 13struct rb_root;
14 14
15void __perf_session__add_count(struct hist_entry *he,
16 struct addr_location *al,
17 u64 count);
18struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, 15struct 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);
22extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); 19extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
23extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); 20extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
24int hist_entry__fprintf(struct hist_entry *self, 21int hist_entry__fprintf(struct hist_entry *self,