aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-12-14 11:22:59 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-14 11:34:55 -0500
commita328626b61aeda1a7d00a80c475c76ca1b815e0d (patch)
tree784f964c8c8950d58bccccaf3802a5a20efb4672 /tools
parent4e4f06e4c8f17ea96f7dd76251cab99511026401 (diff)
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>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-report.c62
-rw-r--r--tools/perf/util/session.c59
-rw-r--r--tools/perf/util/session.h7
3 files changed, 68 insertions, 60 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 854427f0e57e..5141cdccbb65 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -407,64 +407,6 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm)
407 return 0; 407 return 0;
408} 408}
409 409
410static int call__match(struct symbol *sym)
411{
412 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
413 return 1;
414
415 return 0;
416}
417
418static struct symbol **resolve_callchain(struct thread *thread,
419 struct perf_session *session,
420 struct ip_callchain *chain,
421 struct symbol **parent)
422{
423 u8 cpumode = PERF_RECORD_MISC_USER;
424 struct symbol **syms = NULL;
425 unsigned int i;
426
427 if (session->use_callchain) {
428 syms = calloc(chain->nr, sizeof(*syms));
429 if (!syms) {
430 fprintf(stderr, "Can't allocate memory for symbols\n");
431 exit(-1);
432 }
433 }
434
435 for (i = 0; i < chain->nr; i++) {
436 u64 ip = chain->ips[i];
437 struct addr_location al;
438
439 if (ip >= PERF_CONTEXT_MAX) {
440 switch (ip) {
441 case PERF_CONTEXT_HV:
442 cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
443 case PERF_CONTEXT_KERNEL:
444 cpumode = PERF_RECORD_MISC_KERNEL; break;
445 case PERF_CONTEXT_USER:
446 cpumode = PERF_RECORD_MISC_USER; break;
447 default:
448 break;
449 }
450 continue;
451 }
452
453 thread__find_addr_location(thread, session, cpumode,
454 MAP__FUNCTION, ip, &al, NULL);
455 if (al.sym != NULL) {
456 if (sort__has_parent && !*parent &&
457 call__match(al.sym))
458 *parent = al.sym;
459 if (!session->use_callchain)
460 break;
461 syms[i] = al.sym;
462 }
463 }
464
465 return syms;
466}
467
468/* 410/*
469 * collect histogram counts 411 * collect histogram counts
470 */ 412 */
@@ -478,8 +420,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
478 struct hist_entry *he; 420 struct hist_entry *he;
479 421
480 if ((sort__has_parent || self->use_callchain) && chain) 422 if ((sort__has_parent || self->use_callchain) && chain)
481 syms = resolve_callchain(al->thread, self, chain, &parent); 423 syms = perf_session__resolve_callchain(self, al->thread,
482 424 chain, &parent);
483 he = __perf_session__add_hist_entry(self, al, parent, count, &hit); 425 he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
484 if (he == NULL) 426 if (he == NULL)
485 return -ENOMEM; 427 return -ENOMEM;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index fe87a2f2e5a5..ecd54bedfb1c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -4,6 +4,7 @@
4#include <sys/types.h> 4#include <sys/types.h>
5 5
6#include "session.h" 6#include "session.h"
7#include "sort.h"
7#include "util.h" 8#include "util.h"
8 9
9static int perf_session__open(struct perf_session *self, bool force) 10static int perf_session__open(struct perf_session *self, bool force)
@@ -90,3 +91,61 @@ void perf_session__delete(struct perf_session *self)
90 free(self->cwd); 91 free(self->cwd);
91 free(self); 92 free(self);
92} 93}
94
95static bool symbol__match_parent_regex(struct symbol *sym)
96{
97 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
98 return 1;
99
100 return 0;
101}
102
103struct symbol **perf_session__resolve_callchain(struct perf_session *self,
104 struct thread *thread,
105 struct ip_callchain *chain,
106 struct symbol **parent)
107{
108 u8 cpumode = PERF_RECORD_MISC_USER;
109 struct symbol **syms = NULL;
110 unsigned int i;
111
112 if (self->use_callchain) {
113 syms = calloc(chain->nr, sizeof(*syms));
114 if (!syms) {
115 fprintf(stderr, "Can't allocate memory for symbols\n");
116 exit(-1);
117 }
118 }
119
120 for (i = 0; i < chain->nr; i++) {
121 u64 ip = chain->ips[i];
122 struct addr_location al;
123
124 if (ip >= PERF_CONTEXT_MAX) {
125 switch (ip) {
126 case PERF_CONTEXT_HV:
127 cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
128 case PERF_CONTEXT_KERNEL:
129 cpumode = PERF_RECORD_MISC_KERNEL; break;
130 case PERF_CONTEXT_USER:
131 cpumode = PERF_RECORD_MISC_USER; break;
132 default:
133 break;
134 }
135 continue;
136 }
137
138 thread__find_addr_location(thread, self, cpumode,
139 MAP__FUNCTION, ip, &al, NULL);
140 if (al.sym != NULL) {
141 if (sort__has_parent && !*parent &&
142 symbol__match_parent_regex(al.sym))
143 *parent = al.sym;
144 if (!self->use_callchain)
145 break;
146 syms[i] = al.sym;
147 }
148 }
149
150 return syms;
151}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 759d96022a39..a8f3a49ca43a 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -6,7 +6,9 @@
6#include "thread.h" 6#include "thread.h"
7#include <linux/rbtree.h> 7#include <linux/rbtree.h>
8 8
9struct ip_callchain;
9struct thread; 10struct thread;
11struct symbol;
10struct symbol_conf; 12struct symbol_conf;
11 13
12struct perf_session { 14struct perf_session {
@@ -50,6 +52,11 @@ void perf_session__delete(struct perf_session *self);
50int perf_session__process_events(struct perf_session *self, 52int perf_session__process_events(struct perf_session *self,
51 struct perf_event_ops *event_ops); 53 struct perf_event_ops *event_ops);
52 54
55struct symbol **perf_session__resolve_callchain(struct perf_session *self,
56 struct thread *thread,
57 struct ip_callchain *chain,
58 struct symbol **parent);
59
53int perf_header__read_build_ids(int input, u64 offset, u64 file_size); 60int perf_header__read_build_ids(int input, u64 offset, u64 file_size);
54 61
55#endif /* __PERF_SESSION_H */ 62#endif /* __PERF_SESSION_H */