Skip to content

Commit

Permalink
perf_counter: Use rb_trees in perf report
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed May 26, 2009
1 parent 62eb939 commit 35a50c8
Show file tree
Hide file tree
Showing 4 changed files with 601 additions and 16 deletions.
3 changes: 3 additions & 0 deletions Documentation/perf_counter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ LIB_FILE=libperf.a

LIB_H += ../../include/linux/perf_counter.h
LIB_H += perf.h
LIB_H += util/list.h
LIB_H += util/rbtree.h
LIB_H += util/levenshtein.h
LIB_H += util/parse-options.h
LIB_H += util/parse-events.h
Expand All @@ -306,6 +308,7 @@ LIB_OBJS += util/levenshtein.o
LIB_OBJS += util/parse-options.o
LIB_OBJS += util/parse-events.o
LIB_OBJS += util/path.o
LIB_OBJS += util/rbtree.o
LIB_OBJS += util/run-command.o
LIB_OBJS += util/quote.o
LIB_OBJS += util/strbuf.o
Expand Down
60 changes: 44 additions & 16 deletions Documentation/perf_counter/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
#include <linux/types.h>

#include "../../include/linux/perf_counter.h"
#include "list.h"
#include "util/list.h"
#include "util/rbtree.h"

#define SHOW_KERNEL 1
#define SHOW_USER 2
Expand Down Expand Up @@ -106,10 +107,10 @@ static void section__delete(struct section *self)
}

struct symbol {
struct list_head node;
uint64_t start;
uint64_t end;
char name[0];
struct rb_node rb_node;
uint64_t start;
uint64_t end;
char name[0];
};

static struct symbol *symbol__new(uint64_t start, uint64_t len, const char *name)
Expand Down Expand Up @@ -139,7 +140,7 @@ static size_t symbol__fprintf(struct symbol *self, FILE *fp)
struct dso {
struct list_head node;
struct list_head sections;
struct list_head syms;
struct rb_root syms;
char name[0];
};

Expand All @@ -150,7 +151,7 @@ static struct dso *dso__new(const char *name)
if (self != NULL) {
strcpy(self->name, name);
INIT_LIST_HEAD(&self->sections);
INIT_LIST_HEAD(&self->syms);
self->syms = RB_ROOT;
}

return self;
Expand All @@ -166,10 +167,14 @@ static void dso__delete_sections(struct dso *self)

static void dso__delete_symbols(struct dso *self)
{
struct symbol *pos, *n;
struct symbol *pos;
struct rb_node *next = rb_first(&self->syms);

list_for_each_entry_safe(pos, n, &self->syms, node)
while (next) {
pos = rb_entry(next, struct symbol, rb_node);
next = rb_next(&pos->rb_node);
symbol__delete(pos);
}
}

static void dso__delete(struct dso *self)
Expand All @@ -181,19 +186,40 @@ static void dso__delete(struct dso *self)

static void dso__insert_symbol(struct dso *self, struct symbol *sym)
{
list_add_tail(&sym->node, &self->syms);
struct rb_node **p = &self->syms.rb_node;
struct rb_node *parent = NULL;
const uint64_t ip = sym->start;
struct symbol *s;

while (*p != NULL) {
parent = *p;
s = rb_entry(parent, struct symbol, rb_node);
if (ip < s->start)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
rb_link_node(&sym->rb_node, parent, p);
rb_insert_color(&sym->rb_node, &self->syms);
}

static struct symbol *dso__find_symbol(struct dso *self, uint64_t ip)
{
if (self == NULL)
return NULL;

struct symbol *pos;
struct rb_node *n = self->syms.rb_node;

list_for_each_entry(pos, &self->syms, node)
if (ip >= pos->start && ip <= pos->end)
return pos;
while (n) {
struct symbol *s = rb_entry(n, struct symbol, rb_node);

if (ip < s->start)
n = n->rb_left;
else if (ip > s->end)
n = n->rb_right;
else
return s;
}

return NULL;
}
Expand Down Expand Up @@ -319,11 +345,13 @@ static int dso__load(struct dso *self)

static size_t dso__fprintf(struct dso *self, FILE *fp)
{
struct symbol *pos;
size_t ret = fprintf(fp, "dso: %s\n", self->name);

list_for_each_entry(pos, &self->syms, node)
struct rb_node *nd;
for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) {
struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
ret += symbol__fprintf(pos, fp);
}

return ret;
}
Expand Down
Loading

0 comments on commit 35a50c8

Please sign in to comment.