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> 10 #include <traceevent/event-parse.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; 22 23 int trace_event__init(struct trace_event *t) 24 { 25 struct pevent *pevent = pevent_alloc(); 26 27 if (pevent) { 28 t->plugin_list = traceevent_load_plugins(pevent); 29 t->pevent = pevent; 30 } 31 32 return pevent ? 0 : -1; 33 } 34 35 void trace_event__cleanup(struct trace_event *t) 36 { 37 traceevent_unload_plugins(t->plugin_list, t->pevent); 38 pevent_free(t->pevent); 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 } 83