diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2009-09-12 01:52:51 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-19 05:42:11 -0400 |
commit | 8755a8f27ae590dde225f9005ee18c6d9c4c6d78 (patch) | |
tree | 1a86744bf0f5ee71bc5f2d0c29f86f9721aa6f4a /tools/perf/util/header.c | |
parent | 393b2ad8c757ba3ccd2a99ca5bbcd6db4d3fa53d (diff) |
perf: Store trace event name/id pairs in perf.data
The trace event name<->id mapping is dynamic for each kernel
compile. In order for perf.data to be useable outside the actual
system, we thus need to store a table of this mapping for later
use.
This patch adds this table to perf.data, and provides helper
functions for lookup up fields from this table.
To avoid mistakes, lookup-from-table is kept completely seprate
from lookup-from-local-debugfs.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20090912130405.6960d099@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r-- | tools/perf/util/header.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index ec4d4c2f9522..ef9114583994 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -86,6 +86,44 @@ void perf_header__add_attr(struct perf_header *self, | |||
86 | self->attr[pos] = attr; | 86 | self->attr[pos] = attr; |
87 | } | 87 | } |
88 | 88 | ||
89 | struct perf_trace_event_type { | ||
90 | u64 event_id; | ||
91 | char name[64]; | ||
92 | }; | ||
93 | |||
94 | static int event_count; | ||
95 | static struct perf_trace_event_type *events; | ||
96 | |||
97 | void perf_header__push_event(u64 id, const char *name) | ||
98 | { | ||
99 | if (strlen(name) > 64) | ||
100 | printf("Event %s will be truncated\n", name); | ||
101 | |||
102 | if (!events) { | ||
103 | events = malloc(sizeof(struct perf_trace_event_type)); | ||
104 | if (!events) | ||
105 | die("nomem"); | ||
106 | } else { | ||
107 | events = realloc(events, (event_count + 1) * sizeof(struct perf_trace_event_type)); | ||
108 | if (!events) | ||
109 | die("nomem"); | ||
110 | } | ||
111 | memset(&events[event_count], 0, sizeof(struct perf_trace_event_type)); | ||
112 | events[event_count].event_id = id; | ||
113 | strncpy(events[event_count].name, name, 63); | ||
114 | event_count++; | ||
115 | } | ||
116 | |||
117 | char *perf_header__find_event(u64 id) | ||
118 | { | ||
119 | int i; | ||
120 | for (i = 0 ; i < event_count; i++) { | ||
121 | if (events[i].event_id == id) | ||
122 | return events[i].name; | ||
123 | } | ||
124 | return NULL; | ||
125 | } | ||
126 | |||
89 | static const char *__perf_magic = "PERFFILE"; | 127 | static const char *__perf_magic = "PERFFILE"; |
90 | 128 | ||
91 | #define PERF_MAGIC (*(u64 *)__perf_magic) | 129 | #define PERF_MAGIC (*(u64 *)__perf_magic) |
@@ -106,6 +144,7 @@ struct perf_file_header { | |||
106 | u64 attr_size; | 144 | u64 attr_size; |
107 | struct perf_file_section attrs; | 145 | struct perf_file_section attrs; |
108 | struct perf_file_section data; | 146 | struct perf_file_section data; |
147 | struct perf_file_section event_types; | ||
109 | }; | 148 | }; |
110 | 149 | ||
111 | static void do_write(int fd, void *buf, size_t size) | 150 | static void do_write(int fd, void *buf, size_t size) |
@@ -154,6 +193,11 @@ void perf_header__write(struct perf_header *self, int fd) | |||
154 | do_write(fd, &f_attr, sizeof(f_attr)); | 193 | do_write(fd, &f_attr, sizeof(f_attr)); |
155 | } | 194 | } |
156 | 195 | ||
196 | self->event_offset = lseek(fd, 0, SEEK_CUR); | ||
197 | self->event_size = event_count * sizeof(struct perf_trace_event_type); | ||
198 | if (events) | ||
199 | do_write(fd, events, self->event_size); | ||
200 | |||
157 | 201 | ||
158 | self->data_offset = lseek(fd, 0, SEEK_CUR); | 202 | self->data_offset = lseek(fd, 0, SEEK_CUR); |
159 | 203 | ||
@@ -169,6 +213,10 @@ void perf_header__write(struct perf_header *self, int fd) | |||
169 | .offset = self->data_offset, | 213 | .offset = self->data_offset, |
170 | .size = self->data_size, | 214 | .size = self->data_size, |
171 | }, | 215 | }, |
216 | .event_types = { | ||
217 | .offset = self->event_offset, | ||
218 | .size = self->event_size, | ||
219 | }, | ||
172 | }; | 220 | }; |
173 | 221 | ||
174 | lseek(fd, 0, SEEK_SET); | 222 | lseek(fd, 0, SEEK_SET); |
@@ -234,6 +282,17 @@ struct perf_header *perf_header__read(int fd) | |||
234 | lseek(fd, tmp, SEEK_SET); | 282 | lseek(fd, tmp, SEEK_SET); |
235 | } | 283 | } |
236 | 284 | ||
285 | if (f_header.event_types.size) { | ||
286 | lseek(fd, f_header.event_types.offset, SEEK_SET); | ||
287 | events = malloc(f_header.event_types.size); | ||
288 | if (!events) | ||
289 | die("nomem"); | ||
290 | do_read(fd, events, f_header.event_types.size); | ||
291 | event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); | ||
292 | } | ||
293 | self->event_offset = f_header.event_types.offset; | ||
294 | self->event_size = f_header.event_types.size; | ||
295 | |||
237 | self->data_offset = f_header.data.offset; | 296 | self->data_offset = f_header.data.offset; |
238 | self->data_size = f_header.data.size; | 297 | self->data_size = f_header.data.size; |
239 | 298 | ||