diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-05-18 15:24:49 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-26 07:52:55 -0400 |
commit | 35a50c8a20eea22c141e05c5667ac21c48b8b65d (patch) | |
tree | 6b48bf9647023a207fd3ab1d7bfdcda5a1d38746 /Documentation/perf_counter/builtin-report.c | |
parent | 62eb93905b3b43cea407cfbc061cc7b40ae1c6e9 (diff) |
perf_counter: Use rb_trees in perf report
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter/builtin-report.c')
-rw-r--r-- | Documentation/perf_counter/builtin-report.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c index ad2f327a657..f63057fe2cd 100644 --- a/Documentation/perf_counter/builtin-report.c +++ b/Documentation/perf_counter/builtin-report.c | |||
@@ -32,7 +32,8 @@ | |||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | 33 | ||
34 | #include "../../include/linux/perf_counter.h" | 34 | #include "../../include/linux/perf_counter.h" |
35 | #include "list.h" | 35 | #include "util/list.h" |
36 | #include "util/rbtree.h" | ||
36 | 37 | ||
37 | #define SHOW_KERNEL 1 | 38 | #define SHOW_KERNEL 1 |
38 | #define SHOW_USER 2 | 39 | #define SHOW_USER 2 |
@@ -106,10 +107,10 @@ static void section__delete(struct section *self) | |||
106 | } | 107 | } |
107 | 108 | ||
108 | struct symbol { | 109 | struct symbol { |
109 | struct list_head node; | 110 | struct rb_node rb_node; |
110 | uint64_t start; | 111 | uint64_t start; |
111 | uint64_t end; | 112 | uint64_t end; |
112 | char name[0]; | 113 | char name[0]; |
113 | }; | 114 | }; |
114 | 115 | ||
115 | static struct symbol *symbol__new(uint64_t start, uint64_t len, const char *name) | 116 | static struct symbol *symbol__new(uint64_t start, uint64_t len, const char *name) |
@@ -139,7 +140,7 @@ static size_t symbol__fprintf(struct symbol *self, FILE *fp) | |||
139 | struct dso { | 140 | struct dso { |
140 | struct list_head node; | 141 | struct list_head node; |
141 | struct list_head sections; | 142 | struct list_head sections; |
142 | struct list_head syms; | 143 | struct rb_root syms; |
143 | char name[0]; | 144 | char name[0]; |
144 | }; | 145 | }; |
145 | 146 | ||
@@ -150,7 +151,7 @@ static struct dso *dso__new(const char *name) | |||
150 | if (self != NULL) { | 151 | if (self != NULL) { |
151 | strcpy(self->name, name); | 152 | strcpy(self->name, name); |
152 | INIT_LIST_HEAD(&self->sections); | 153 | INIT_LIST_HEAD(&self->sections); |
153 | INIT_LIST_HEAD(&self->syms); | 154 | self->syms = RB_ROOT; |
154 | } | 155 | } |
155 | 156 | ||
156 | return self; | 157 | return self; |
@@ -166,10 +167,14 @@ static void dso__delete_sections(struct dso *self) | |||
166 | 167 | ||
167 | static void dso__delete_symbols(struct dso *self) | 168 | static void dso__delete_symbols(struct dso *self) |
168 | { | 169 | { |
169 | struct symbol *pos, *n; | 170 | struct symbol *pos; |
171 | struct rb_node *next = rb_first(&self->syms); | ||
170 | 172 | ||
171 | list_for_each_entry_safe(pos, n, &self->syms, node) | 173 | while (next) { |
174 | pos = rb_entry(next, struct symbol, rb_node); | ||
175 | next = rb_next(&pos->rb_node); | ||
172 | symbol__delete(pos); | 176 | symbol__delete(pos); |
177 | } | ||
173 | } | 178 | } |
174 | 179 | ||
175 | static void dso__delete(struct dso *self) | 180 | static void dso__delete(struct dso *self) |
@@ -181,7 +186,21 @@ static void dso__delete(struct dso *self) | |||
181 | 186 | ||
182 | static void dso__insert_symbol(struct dso *self, struct symbol *sym) | 187 | static void dso__insert_symbol(struct dso *self, struct symbol *sym) |
183 | { | 188 | { |
184 | list_add_tail(&sym->node, &self->syms); | 189 | struct rb_node **p = &self->syms.rb_node; |
190 | struct rb_node *parent = NULL; | ||
191 | const uint64_t ip = sym->start; | ||
192 | struct symbol *s; | ||
193 | |||
194 | while (*p != NULL) { | ||
195 | parent = *p; | ||
196 | s = rb_entry(parent, struct symbol, rb_node); | ||
197 | if (ip < s->start) | ||
198 | p = &(*p)->rb_left; | ||
199 | else | ||
200 | p = &(*p)->rb_right; | ||
201 | } | ||
202 | rb_link_node(&sym->rb_node, parent, p); | ||
203 | rb_insert_color(&sym->rb_node, &self->syms); | ||
185 | } | 204 | } |
186 | 205 | ||
187 | static struct symbol *dso__find_symbol(struct dso *self, uint64_t ip) | 206 | static struct symbol *dso__find_symbol(struct dso *self, uint64_t ip) |
@@ -189,11 +208,18 @@ static struct symbol *dso__find_symbol(struct dso *self, uint64_t ip) | |||
189 | if (self == NULL) | 208 | if (self == NULL) |
190 | return NULL; | 209 | return NULL; |
191 | 210 | ||
192 | struct symbol *pos; | 211 | struct rb_node *n = self->syms.rb_node; |
193 | 212 | ||
194 | list_for_each_entry(pos, &self->syms, node) | 213 | while (n) { |
195 | if (ip >= pos->start && ip <= pos->end) | 214 | struct symbol *s = rb_entry(n, struct symbol, rb_node); |
196 | return pos; | 215 | |
216 | if (ip < s->start) | ||
217 | n = n->rb_left; | ||
218 | else if (ip > s->end) | ||
219 | n = n->rb_right; | ||
220 | else | ||
221 | return s; | ||
222 | } | ||
197 | 223 | ||
198 | return NULL; | 224 | return NULL; |
199 | } | 225 | } |
@@ -319,11 +345,13 @@ out_close: | |||
319 | 345 | ||
320 | static size_t dso__fprintf(struct dso *self, FILE *fp) | 346 | static size_t dso__fprintf(struct dso *self, FILE *fp) |
321 | { | 347 | { |
322 | struct symbol *pos; | ||
323 | size_t ret = fprintf(fp, "dso: %s\n", self->name); | 348 | size_t ret = fprintf(fp, "dso: %s\n", self->name); |
324 | 349 | ||
325 | list_for_each_entry(pos, &self->syms, node) | 350 | struct rb_node *nd; |
351 | for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) { | ||
352 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | ||
326 | ret += symbol__fprintf(pos, fp); | 353 | ret += symbol__fprintf(pos, fp); |
354 | } | ||
327 | 355 | ||
328 | return ret; | 356 | return ret; |
329 | } | 357 | } |