aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-10 13:58:12 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-10 13:58:12 -0500
commit560f78a3b6f771d78e24e5c83f4dd943ee2b4f15 (patch)
tree66de5239b041803e8ce7e5a8b42e447cfe79537f
parent4d03347b50ec3b6f37beb557487f74a9a3d47558 (diff)
Add sched_switch plugin to make the events look more like the old plugin
The event output for scheduler context switches and wakeups changed the output format. This adds a plugin to make those changes look more like the sched_switch plugin. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--Makefile9
-rw-r--r--plugin_sched_switch.c164
2 files changed, 172 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 1b73a9e..f159a46 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,8 @@ LIBS = -L. -ltracecmd -ldl
9%.o: %.c 9%.o: %.c
10 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ 10 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@
11 11
12TARGETS = libparsevent.a libtracecmd.a trace-cmd plugin_hrtimer.so plugin_mac80211.so 12TARGETS = libparsevent.a libtracecmd.a trace-cmd plugin_hrtimer.so plugin_mac80211.so \
13 plugin_sched_switch.so
13 14
14all: $(TARGETS) 15all: $(TARGETS)
15 16
@@ -63,6 +64,12 @@ plugin_hrtimer.o: plugin_hrtimer.c parse-events.h
63plugin_hrtimer.so: plugin_hrtimer.o 64plugin_hrtimer.so: plugin_hrtimer.o
64 $(CC) -shared -nostartfiles -o $@ $< 65 $(CC) -shared -nostartfiles -o $@ $<
65 66
67plugin_sched_switch.o: plugin_sched_switch.c parse-events.h
68 $(CC) -c $(CFLAGS) -fPIC -o $@ $<
69
70plugin_sched_switch.so: plugin_sched_switch.o
71 $(CC) -shared -nostartfiles -o $@ $<
72
66plugin_mac80211.o: plugin_mac80211.c parse-events.h 73plugin_mac80211.o: plugin_mac80211.c parse-events.h
67 $(CC) -c $(CFLAGS) -fPIC -o $@ $< 74 $(CC) -c $(CFLAGS) -fPIC -o $@ $<
68 75
diff --git a/plugin_sched_switch.c b/plugin_sched_switch.c
new file mode 100644
index 0000000..b85a12a
--- /dev/null
+++ b/plugin_sched_switch.c
@@ -0,0 +1,164 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "trace-cmd.h"
6
7static int get_field_val(struct trace_seq *s, void *data,
8 struct event *event, const char *name,
9 unsigned long long *val, int fail)
10{
11 struct format_field *field;
12
13 field = pevent_find_any_field(event, name);
14 if (!field) {
15 if (fail)
16 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
17 return -1;
18 }
19
20 if (pevent_read_number_field(field, data, val)) {
21 if (fail)
22 trace_seq_printf(s, " %s=INVALID", name);
23 return -1;
24 }
25
26 return 0;
27}
28
29static void write_state(struct trace_seq *s, int val)
30{
31 const char states[] = "SDTtZXxW";
32 int found = 0;
33 int i;
34
35 for (i=0; i < (sizeof(states) - 1); i++) {
36 if (!(val & (1 << i)))
37 continue;
38
39 if (found)
40 trace_seq_putc(s, '|');
41
42 found = 1;
43 trace_seq_putc(s, states[i]);
44 }
45
46 if (!found)
47 trace_seq_putc(s, 'R');
48}
49
50static int sched_wakeup_handler(struct trace_seq *s, void *data, int size,
51 struct event *event, int cpu,
52 unsigned long long nsecs)
53{
54 struct format_field *field;
55 unsigned long long val;
56
57 if (get_field_val(s, data, event, "common_pid", &val, 1))
58 return trace_seq_putc(s, '!');
59
60 trace_seq_printf(s, "%lld:", val);
61
62 if (get_field_val(s, data, event, "prev_prio", &val, 0))
63 trace_seq_puts(s, "?:");
64 else
65 trace_seq_printf(s, "%lld:", val);
66
67 if (get_field_val(s, data, event, "prev_state", &val, 0))
68 trace_seq_putc(s, '?');
69 else
70 write_state(s, val);
71
72 trace_seq_puts(s, " + ");
73
74 if (get_field_val(s, data, event, "pid", &val, 1))
75 return trace_seq_putc(s, '!');
76
77 trace_seq_printf(s, "%lld:", val);
78
79 if (get_field_val(s, data, event, "prio", &val, 1))
80 return trace_seq_putc(s, '!');
81
82 trace_seq_printf(s, "%lld:", val);
83
84 if (get_field_val(s, data, event, "state", &val, 0))
85 trace_seq_putc(s, '?');
86 else
87 write_state(s, val);
88
89 trace_seq_putc(s, ' ');
90
91 field = pevent_find_any_field(event, "comm");
92 if (!field) {
93 trace_seq_printf(s, "<CANT FIND FIELD %s>", "next_comm");
94 return trace_seq_putc(s, '!');
95 }
96
97 trace_seq_printf(s, "%.*s", field->size, (char *)(data + field->offset));
98
99 if (get_field_val(s, data, event, "success", &val, 0) == 0)
100 trace_seq_puts(s, val ? " Success" : " Failed");
101
102 return 0;
103}
104
105static int sched_switch_handler(struct trace_seq *s, void *data, int size,
106 struct event *event, int cpu,
107 unsigned long long nsecs)
108{
109 struct format_field *field;
110 unsigned long long val;
111
112 if (get_field_val(s, data, event, "prev_pid", &val, 1))
113 return trace_seq_putc(s, '!');
114
115 trace_seq_printf(s, "%lld:", val);
116
117 if (get_field_val(s, data, event, "prev_prio", &val, 1))
118 return trace_seq_putc(s, '!');
119
120 trace_seq_printf(s, "%lld:", val);
121
122 if (get_field_val(s, data, event, "prev_state", &val, 1))
123 return trace_seq_putc(s, '!');
124
125 write_state(s, val);
126
127 trace_seq_puts(s, " ==> ");
128
129 if (get_field_val(s, data, event, "next_pid", &val, 1))
130 return trace_seq_putc(s, '!');
131
132 trace_seq_printf(s, "%lld:", val);
133
134 if (get_field_val(s, data, event, "next_prio", &val, 1))
135 return trace_seq_putc(s, '!');
136
137 trace_seq_printf(s, "%lld:", val);
138
139 trace_seq_putc(s, ' ');
140
141 field = pevent_find_any_field(event, "next_comm");
142 if (!field) {
143 trace_seq_printf(s, "<CANT FIND FIELD %s>", "next_comm");
144 return trace_seq_putc(s, '!');
145 }
146
147 trace_seq_printf(s, "%.*s", field->size, (char *)(data + field->offset));
148
149 return 0;
150}
151
152int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
153{
154 pevent_register_event_handler(pevent, -1, "sched", "sched_switch",
155 sched_switch_handler);
156
157 pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup",
158 sched_wakeup_handler);
159
160 pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
161 sched_wakeup_handler);
162
163 return 0;
164}