Commit 9735abf1 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Ingo Molnar

perf tools: Move hist_entry__add common code to hist.c

Now perf report and annotate do the callgraph/hit processing in
their specialized hist_entry__add functions.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: default avatarFrédéric Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 439d473b
...@@ -80,48 +80,16 @@ static void hist_hit(struct hist_entry *he, u64 ip) ...@@ -80,48 +80,16 @@ static void hist_hit(struct hist_entry *he, u64 ip)
sym->hist[offset]); sym->hist[offset]);
} }
static int static int hist_entry__add(struct thread *thread, struct map *map,
hist_entry__add(struct thread *thread, struct map *map, struct symbol *sym, u64 ip, u64 count, char level)
struct symbol *sym, u64 ip, char level)
{ {
struct rb_node **p = &hist.rb_node; bool hit;
struct rb_node *parent = NULL; struct hist_entry *he = __hist_entry__add(thread, map, sym, NULL, ip,
struct hist_entry *he; count, level, &hit);
struct hist_entry entry = { if (he == NULL)
.thread = thread,
.map = map,
.sym = sym,
.ip = ip,
.level = level,
.count = 1,
};
int cmp;
while (*p != NULL) {
parent = *p;
he = rb_entry(parent, struct hist_entry, rb_node);
cmp = hist_entry__cmp(&entry, he);
if (!cmp) {
hist_hit(he, ip);
return 0;
}
if (cmp < 0)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
he = malloc(sizeof(*he));
if (!he)
return -ENOMEM; return -ENOMEM;
*he = entry; if (hit)
rb_link_node(&he->rb_node, parent, p); hist_hit(he, ip);
rb_insert_color(&he->rb_node, &hist);
return 0; return 0;
} }
...@@ -191,7 +159,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) ...@@ -191,7 +159,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
} }
if (show & show_mask) { if (show & show_mask) {
if (hist_entry__add(thread, map, sym, ip, level)) { if (hist_entry__add(thread, map, sym, ip, 1, level)) {
fprintf(stderr, fprintf(stderr,
"problem incrementing symbol count, skipping event\n"); "problem incrementing symbol count, skipping event\n");
return -1; return -1;
......
...@@ -407,9 +407,9 @@ static int call__match(struct symbol *sym) ...@@ -407,9 +407,9 @@ static int call__match(struct symbol *sym)
return 0; return 0;
} }
static struct symbol ** static struct symbol **resolve_callchain(struct thread *thread, struct map *map,
resolve_callchain(struct thread *thread, struct map *map, struct ip_callchain *chain,
struct ip_callchain *chain, struct hist_entry *entry) struct symbol **parent)
{ {
u64 context = PERF_CONTEXT_MAX; u64 context = PERF_CONTEXT_MAX;
struct symbol **syms = NULL; struct symbol **syms = NULL;
...@@ -444,9 +444,8 @@ resolve_callchain(struct thread *thread, struct map *map, ...@@ -444,9 +444,8 @@ resolve_callchain(struct thread *thread, struct map *map,
} }
if (sym) { if (sym) {
if (sort__has_parent && call__match(sym) && if (sort__has_parent && !*parent && call__match(sym))
!entry->parent) *parent = sym;
entry->parent = sym;
if (!callchain) if (!callchain)
break; break;
syms[i] = sym; syms[i] = sym;
...@@ -465,57 +464,27 @@ hist_entry__add(struct thread *thread, struct map *map, ...@@ -465,57 +464,27 @@ hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym, u64 ip, struct ip_callchain *chain, struct symbol *sym, u64 ip, struct ip_callchain *chain,
char level, u64 count) char level, u64 count)
{ {
struct rb_node **p = &hist.rb_node; struct symbol **syms = NULL, *parent = NULL;
struct rb_node *parent = NULL; bool hit;
struct hist_entry *he; struct hist_entry *he;
struct symbol **syms = NULL;
struct hist_entry entry = {
.thread = thread,
.map = map,
.sym = sym,
.ip = ip,
.level = level,
.count = count,
.parent = NULL,
.sorted_chain = RB_ROOT
};
int cmp;
if ((sort__has_parent || callchain) && chain) if ((sort__has_parent || callchain) && chain)
syms = resolve_callchain(thread, map, chain, &entry); syms = resolve_callchain(thread, map, chain, &parent);
while (*p != NULL) {
parent = *p;
he = rb_entry(parent, struct hist_entry, rb_node);
cmp = hist_entry__cmp(&entry, he);
if (!cmp) { he = __hist_entry__add(thread, map, sym, parent,
he->count += count; ip, count, level, &hit);
if (callchain) { if (he == NULL)
append_chain(&he->callchain, chain, syms); return -ENOMEM;
free(syms);
}
return 0;
}
if (cmp < 0) if (hit)
p = &(*p)->rb_left; he->count += count;
else
p = &(*p)->rb_right;
}
he = malloc(sizeof(*he));
if (!he)
return -ENOMEM;
*he = entry;
if (callchain) { if (callchain) {
callchain_init(&he->callchain); if (!hit)
callchain_init(&he->callchain);
append_chain(&he->callchain, chain, syms); append_chain(&he->callchain, chain, syms);
free(syms); free(syms);
} }
rb_link_node(&he->rb_node, parent, p);
rb_insert_color(&he->rb_node, &hist);
return 0; return 0;
} }
......
...@@ -21,6 +21,52 @@ unsigned long total_lost; ...@@ -21,6 +21,52 @@ unsigned long total_lost;
* histogram, sorted on item, collects counts * histogram, sorted on item, collects counts
*/ */
struct hist_entry *__hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym,
struct symbol *sym_parent,
u64 ip, u64 count, char level, bool *hit)
{
struct rb_node **p = &hist.rb_node;
struct rb_node *parent = NULL;
struct hist_entry *he;
struct hist_entry entry = {
.thread = thread,
.map = map,
.sym = sym,
.ip = ip,
.level = level,
.count = count,
.parent = sym_parent,
};
int cmp;
while (*p != NULL) {
parent = *p;
he = rb_entry(parent, struct hist_entry, rb_node);
cmp = hist_entry__cmp(&entry, he);
if (!cmp) {
*hit = true;
return he;
}
if (cmp < 0)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
he = malloc(sizeof(*he));
if (!he)
return NULL;
*he = entry;
rb_link_node(&he->rb_node, parent, p);
rb_insert_color(&he->rb_node, &hist);
*hit = false;
return he;
}
int64_t int64_t
hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
{ {
......
...@@ -36,6 +36,9 @@ extern unsigned long total_fork; ...@@ -36,6 +36,9 @@ extern unsigned long total_fork;
extern unsigned long total_unknown; extern unsigned long total_unknown;
extern unsigned long total_lost; extern unsigned long total_lost;
struct hist_entry *__hist_entry__add(struct thread *thread, struct map *map,
struct symbol *sym, struct symbol *parent,
u64 ip, u64 count, char level, bool *hit);
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
extern void hist_entry__free(struct hist_entry *); extern void hist_entry__free(struct hist_entry *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment