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

perf session: Adopt resolve_callchain

This is really a generic library routine, so declutter
builtin-report.c a bit by moving it to the library.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260807780-19377-1-git-send-email-acme@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 4e4f06e4
...@@ -407,64 +407,6 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm) ...@@ -407,64 +407,6 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
return 0; return 0;
} }
static int call__match(struct symbol *sym)
{
if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
return 1;
return 0;
}
static struct symbol **resolve_callchain(struct thread *thread,
struct perf_session *session,
struct ip_callchain *chain,
struct symbol **parent)
{
u8 cpumode = PERF_RECORD_MISC_USER;
struct symbol **syms = NULL;
unsigned int i;
if (session->use_callchain) {
syms = calloc(chain->nr, sizeof(*syms));
if (!syms) {
fprintf(stderr, "Can't allocate memory for symbols\n");
exit(-1);
}
}
for (i = 0; i < chain->nr; i++) {
u64 ip = chain->ips[i];
struct addr_location al;
if (ip >= PERF_CONTEXT_MAX) {
switch (ip) {
case PERF_CONTEXT_HV:
cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
case PERF_CONTEXT_KERNEL:
cpumode = PERF_RECORD_MISC_KERNEL; break;
case PERF_CONTEXT_USER:
cpumode = PERF_RECORD_MISC_USER; break;
default:
break;
}
continue;
}
thread__find_addr_location(thread, session, cpumode,
MAP__FUNCTION, ip, &al, NULL);
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
call__match(al.sym))
*parent = al.sym;
if (!session->use_callchain)
break;
syms[i] = al.sym;
}
}
return syms;
}
/* /*
* collect histogram counts * collect histogram counts
*/ */
...@@ -478,8 +420,8 @@ static int perf_session__add_hist_entry(struct perf_session *self, ...@@ -478,8 +420,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
struct hist_entry *he; struct hist_entry *he;
if ((sort__has_parent || self->use_callchain) && chain) if ((sort__has_parent || self->use_callchain) && chain)
syms = resolve_callchain(al->thread, self, chain, &parent); syms = perf_session__resolve_callchain(self, al->thread,
chain, &parent);
he = __perf_session__add_hist_entry(self, al, parent, count, &hit); he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
if (he == NULL) if (he == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "session.h" #include "session.h"
#include "sort.h"
#include "util.h" #include "util.h"
static int perf_session__open(struct perf_session *self, bool force) static int perf_session__open(struct perf_session *self, bool force)
...@@ -90,3 +91,61 @@ void perf_session__delete(struct perf_session *self) ...@@ -90,3 +91,61 @@ void perf_session__delete(struct perf_session *self)
free(self->cwd); free(self->cwd);
free(self); free(self);
} }
static bool symbol__match_parent_regex(struct symbol *sym)
{
if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
return 1;
return 0;
}
struct symbol **perf_session__resolve_callchain(struct perf_session *self,
struct thread *thread,
struct ip_callchain *chain,
struct symbol **parent)
{
u8 cpumode = PERF_RECORD_MISC_USER;
struct symbol **syms = NULL;
unsigned int i;
if (self->use_callchain) {
syms = calloc(chain->nr, sizeof(*syms));
if (!syms) {
fprintf(stderr, "Can't allocate memory for symbols\n");
exit(-1);
}
}
for (i = 0; i < chain->nr; i++) {
u64 ip = chain->ips[i];
struct addr_location al;
if (ip >= PERF_CONTEXT_MAX) {
switch (ip) {
case PERF_CONTEXT_HV:
cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
case PERF_CONTEXT_KERNEL:
cpumode = PERF_RECORD_MISC_KERNEL; break;
case PERF_CONTEXT_USER:
cpumode = PERF_RECORD_MISC_USER; break;
default:
break;
}
continue;
}
thread__find_addr_location(thread, self, cpumode,
MAP__FUNCTION, ip, &al, NULL);
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
symbol__match_parent_regex(al.sym))
*parent = al.sym;
if (!self->use_callchain)
break;
syms[i] = al.sym;
}
}
return syms;
}
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
#include "thread.h" #include "thread.h"
#include <linux/rbtree.h> #include <linux/rbtree.h>
struct ip_callchain;
struct thread; struct thread;
struct symbol;
struct symbol_conf; struct symbol_conf;
struct perf_session { struct perf_session {
...@@ -50,6 +52,11 @@ void perf_session__delete(struct perf_session *self); ...@@ -50,6 +52,11 @@ void perf_session__delete(struct perf_session *self);
int perf_session__process_events(struct perf_session *self, int perf_session__process_events(struct perf_session *self,
struct perf_event_ops *event_ops); struct perf_event_ops *event_ops);
struct symbol **perf_session__resolve_callchain(struct perf_session *self,
struct thread *thread,
struct ip_callchain *chain,
struct symbol **parent);
int perf_header__read_build_ids(int input, u64 offset, u64 file_size); int perf_header__read_build_ids(int input, u64 offset, u64 file_size);
#endif /* __PERF_SESSION_H */ #endif /* __PERF_SESSION_H */
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