mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
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: Arnaldo 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: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
4e4f06e4c8
commit
a328626b61
3 changed files with 68 additions and 60 deletions
|
@ -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,
|
||||||
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 @@
|
||||||
#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)
|
||||||
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 @@
|
||||||
#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);
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue