aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-report.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-05-18 15:24:49 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-26 07:52:55 -0400
commit35a50c8a20eea22c141e05c5667ac21c48b8b65d (patch)
tree6b48bf9647023a207fd3ab1d7bfdcda5a1d38746 /Documentation/perf_counter/builtin-report.c
parent62eb93905b3b43cea407cfbc061cc7b40ae1c6e9 (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.c60
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
108struct symbol { 109struct 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
115static struct symbol *symbol__new(uint64_t start, uint64_t len, const char *name) 116static 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)
139struct dso { 140struct 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
167static void dso__delete_symbols(struct dso *self) 168static 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
175static void dso__delete(struct dso *self) 180static void dso__delete(struct dso *self)
@@ -181,7 +186,21 @@ static void dso__delete(struct dso *self)
181 186
182static void dso__insert_symbol(struct dso *self, struct symbol *sym) 187static 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
187static struct symbol *dso__find_symbol(struct dso *self, uint64_t ip) 206static 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
320static size_t dso__fprintf(struct dso *self, FILE *fp) 346static 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}