diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-trace.c | 5 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 44 | ||||
-rw-r--r-- | tools/perf/util/trace-event.c | 61 | ||||
-rw-r--r-- | tools/perf/util/trace-event.h | 2 |
4 files changed, 68 insertions, 44 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9f2a242fa79c..56afe339661a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "util/intlist.h" | 11 | #include "util/intlist.h" |
12 | #include "util/thread_map.h" | 12 | #include "util/thread_map.h" |
13 | #include "util/stat.h" | 13 | #include "util/stat.h" |
14 | #include "trace-event.h" | ||
14 | 15 | ||
15 | #include <libaudit.h> | 16 | #include <libaudit.h> |
16 | #include <stdlib.h> | 17 | #include <stdlib.h> |
@@ -1430,11 +1431,11 @@ static int trace__read_syscall_info(struct trace *trace, int id) | |||
1430 | sc->fmt = syscall_fmt__find(sc->name); | 1431 | sc->fmt = syscall_fmt__find(sc->name); |
1431 | 1432 | ||
1432 | snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); | 1433 | snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); |
1433 | sc->tp_format = event_format__new("syscalls", tp_name); | 1434 | sc->tp_format = trace_event__tp_format("syscalls", tp_name); |
1434 | 1435 | ||
1435 | if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) { | 1436 | if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) { |
1436 | snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias); | 1437 | snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias); |
1437 | sc->tp_format = event_format__new("syscalls", tp_name); | 1438 | sc->tp_format = trace_event__tp_format("syscalls", tp_name); |
1438 | } | 1439 | } |
1439 | 1440 | ||
1440 | if (sc->tp_format == NULL) | 1441 | if (sc->tp_format == NULL) |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6a046ed73f98..7b510fd1f08d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "target.h" | 23 | #include "target.h" |
24 | #include "perf_regs.h" | 24 | #include "perf_regs.h" |
25 | #include "debug.h" | 25 | #include "debug.h" |
26 | #include "trace-event.h" | ||
26 | 27 | ||
27 | static struct { | 28 | static struct { |
28 | bool sample_id_all; | 29 | bool sample_id_all; |
@@ -180,47 +181,6 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | |||
180 | return evsel; | 181 | return evsel; |
181 | } | 182 | } |
182 | 183 | ||
183 | struct event_format *event_format__new(const char *sys, const char *name) | ||
184 | { | ||
185 | int fd, n; | ||
186 | char *filename; | ||
187 | void *bf = NULL, *nbf; | ||
188 | size_t size = 0, alloc_size = 0; | ||
189 | struct event_format *format = NULL; | ||
190 | |||
191 | if (asprintf(&filename, "%s/%s/%s/format", tracing_events_path, sys, name) < 0) | ||
192 | goto out; | ||
193 | |||
194 | fd = open(filename, O_RDONLY); | ||
195 | if (fd < 0) | ||
196 | goto out_free_filename; | ||
197 | |||
198 | do { | ||
199 | if (size == alloc_size) { | ||
200 | alloc_size += BUFSIZ; | ||
201 | nbf = realloc(bf, alloc_size); | ||
202 | if (nbf == NULL) | ||
203 | goto out_free_bf; | ||
204 | bf = nbf; | ||
205 | } | ||
206 | |||
207 | n = read(fd, bf + size, alloc_size - size); | ||
208 | if (n < 0) | ||
209 | goto out_free_bf; | ||
210 | size += n; | ||
211 | } while (n > 0); | ||
212 | |||
213 | pevent_parse_format(NULL, &format, bf, size, sys); | ||
214 | |||
215 | out_free_bf: | ||
216 | free(bf); | ||
217 | close(fd); | ||
218 | out_free_filename: | ||
219 | free(filename); | ||
220 | out: | ||
221 | return format; | ||
222 | } | ||
223 | |||
224 | struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) | 184 | struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) |
225 | { | 185 | { |
226 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 186 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); |
@@ -235,7 +195,7 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int | |||
235 | if (asprintf(&evsel->name, "%s:%s", sys, name) < 0) | 195 | if (asprintf(&evsel->name, "%s:%s", sys, name) < 0) |
236 | goto out_free; | 196 | goto out_free; |
237 | 197 | ||
238 | evsel->tp_format = event_format__new(sys, name); | 198 | evsel->tp_format = trace_event__tp_format(sys, name); |
239 | if (evsel->tp_format == NULL) | 199 | if (evsel->tp_format == NULL) |
240 | goto out_free; | 200 | goto out_free; |
241 | 201 | ||
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index a155a77f3023..d9f5f6137ab3 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c | |||
@@ -1,6 +1,24 @@ | |||
1 | 1 | ||
2 | #include <stdio.h> | ||
3 | #include <unistd.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <errno.h> | ||
6 | #include <sys/types.h> | ||
7 | #include <sys/stat.h> | ||
8 | #include <fcntl.h> | ||
9 | #include <linux/kernel.h> | ||
2 | #include <traceevent/event-parse.h> | 10 | #include <traceevent/event-parse.h> |
3 | #include "trace-event.h" | 11 | #include "trace-event.h" |
12 | #include "util.h" | ||
13 | |||
14 | /* | ||
15 | * global trace_event object used by trace_event__tp_format | ||
16 | * | ||
17 | * TODO There's no cleanup call for this. Add some sort of | ||
18 | * __exit function support and call trace_event__cleanup | ||
19 | * there. | ||
20 | */ | ||
21 | static struct trace_event tevent; | ||
4 | 22 | ||
5 | int trace_event__init(struct trace_event *t) | 23 | int trace_event__init(struct trace_event *t) |
6 | { | 24 | { |
@@ -19,3 +37,46 @@ void trace_event__cleanup(struct trace_event *t) | |||
19 | pevent_free(t->pevent); | 37 | pevent_free(t->pevent); |
20 | traceevent_unload_plugins(t->plugin_list); | 38 | traceevent_unload_plugins(t->plugin_list); |
21 | } | 39 | } |
40 | |||
41 | static struct event_format* | ||
42 | tp_format(const char *sys, const char *name) | ||
43 | { | ||
44 | struct pevent *pevent = tevent.pevent; | ||
45 | struct event_format *event = NULL; | ||
46 | char path[PATH_MAX]; | ||
47 | size_t size; | ||
48 | char *data; | ||
49 | |||
50 | scnprintf(path, PATH_MAX, "%s/%s/%s/format", | ||
51 | tracing_events_path, sys, name); | ||
52 | |||
53 | if (filename__read_str(path, &data, &size)) | ||
54 | return NULL; | ||
55 | |||
56 | pevent_parse_format(pevent, &event, data, size, sys); | ||
57 | |||
58 | free(data); | ||
59 | return event; | ||
60 | } | ||
61 | |||
62 | struct event_format* | ||
63 | trace_event__tp_format(const char *sys, const char *name) | ||
64 | { | ||
65 | static bool initialized; | ||
66 | |||
67 | if (!initialized) { | ||
68 | int be = traceevent_host_bigendian(); | ||
69 | struct pevent *pevent; | ||
70 | |||
71 | if (trace_event__init(&tevent)) | ||
72 | return NULL; | ||
73 | |||
74 | pevent = tevent.pevent; | ||
75 | pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); | ||
76 | pevent_set_file_bigendian(pevent, be); | ||
77 | pevent_set_host_bigendian(pevent, be); | ||
78 | initialized = true; | ||
79 | } | ||
80 | |||
81 | return tp_format(sys, name); | ||
82 | } | ||
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 75dded36a2f1..3a01618c5b87 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
@@ -18,6 +18,8 @@ struct trace_event { | |||
18 | 18 | ||
19 | int trace_event__init(struct trace_event *t); | 19 | int trace_event__init(struct trace_event *t); |
20 | void trace_event__cleanup(struct trace_event *t); | 20 | void trace_event__cleanup(struct trace_event *t); |
21 | struct event_format* | ||
22 | trace_event__tp_format(const char *sys, const char *name); | ||
21 | 23 | ||
22 | int bigendian(void); | 24 | int bigendian(void); |
23 | 25 | ||