2 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation;
8 * version 2.1 of the License (not later!)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, see <http://www.gnu.org/licenses>
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 #include "event-parse.h"
25 #include "trace-seq.h"
27 static void write_state(struct trace_seq
*s
, int val
)
29 const char states
[] = "SDTtZXxW";
33 for (i
= 0; i
< (sizeof(states
) - 1); i
++) {
34 if (!(val
& (1 << i
)))
38 trace_seq_putc(s
, '|');
41 trace_seq_putc(s
, states
[i
]);
45 trace_seq_putc(s
, 'R');
48 static void write_and_save_comm(struct tep_format_field
*field
,
49 struct tep_record
*record
,
50 struct trace_seq
*s
, int pid
)
55 comm
= (char *)(record
->data
+ field
->offset
);
57 trace_seq_printf(s
, "%.*s",
60 /* make sure the comm has a \0 at the end. */
61 trace_seq_terminate(s
);
62 comm
= &s
->buffer
[len
];
64 /* Help out the comm to ids. This will handle dups */
65 tep_register_comm(field
->event
->tep
, comm
, pid
);
68 static int sched_wakeup_handler(struct trace_seq
*s
,
69 struct tep_record
*record
,
70 struct tep_event
*event
, void *context
)
72 struct tep_format_field
*field
;
73 unsigned long long val
;
75 if (tep_get_field_val(s
, event
, "pid", record
, &val
, 1))
76 return trace_seq_putc(s
, '!');
78 field
= tep_find_any_field(event
, "comm");
80 write_and_save_comm(field
, record
, s
, val
);
81 trace_seq_putc(s
, ':');
83 trace_seq_printf(s
, "%lld", val
);
85 if (tep_get_field_val(s
, event
, "prio", record
, &val
, 0) == 0)
86 trace_seq_printf(s
, " [%lld]", val
);
88 if (tep_get_field_val(s
, event
, "success", record
, &val
, 1) == 0)
89 trace_seq_printf(s
, " success=%lld", val
);
91 if (tep_get_field_val(s
, event
, "target_cpu", record
, &val
, 0) == 0)
92 trace_seq_printf(s
, " CPU:%03llu", val
);
97 static int sched_switch_handler(struct trace_seq
*s
,
98 struct tep_record
*record
,
99 struct tep_event
*event
, void *context
)
101 struct tep_format_field
*field
;
102 unsigned long long val
;
104 if (tep_get_field_val(s
, event
, "prev_pid", record
, &val
, 1))
105 return trace_seq_putc(s
, '!');
107 field
= tep_find_any_field(event
, "prev_comm");
109 write_and_save_comm(field
, record
, s
, val
);
110 trace_seq_putc(s
, ':');
112 trace_seq_printf(s
, "%lld ", val
);
114 if (tep_get_field_val(s
, event
, "prev_prio", record
, &val
, 0) == 0)
115 trace_seq_printf(s
, "[%d] ", (int) val
);
117 if (tep_get_field_val(s
, event
, "prev_state", record
, &val
, 0) == 0)
120 trace_seq_puts(s
, " ==> ");
122 if (tep_get_field_val(s
, event
, "next_pid", record
, &val
, 1))
123 return trace_seq_putc(s
, '!');
125 field
= tep_find_any_field(event
, "next_comm");
127 write_and_save_comm(field
, record
, s
, val
);
128 trace_seq_putc(s
, ':');
130 trace_seq_printf(s
, "%lld", val
);
132 if (tep_get_field_val(s
, event
, "next_prio", record
, &val
, 0) == 0)
133 trace_seq_printf(s
, " [%d]", (int) val
);
138 int TEP_PLUGIN_LOADER(struct tep_handle
*tep
)
140 tep_register_event_handler(tep
, -1, "sched", "sched_switch",
141 sched_switch_handler
, NULL
);
143 tep_register_event_handler(tep
, -1, "sched", "sched_wakeup",
144 sched_wakeup_handler
, NULL
);
146 tep_register_event_handler(tep
, -1, "sched", "sched_wakeup_new",
147 sched_wakeup_handler
, NULL
);
151 void TEP_PLUGIN_UNLOADER(struct tep_handle
*tep
)
153 tep_unregister_event_handler(tep
, -1, "sched", "sched_switch",
154 sched_switch_handler
, NULL
);
156 tep_unregister_event_handler(tep
, -1, "sched", "sched_wakeup",
157 sched_wakeup_handler
, NULL
);
159 tep_unregister_event_handler(tep
, -1, "sched", "sched_wakeup_new",
160 sched_wakeup_handler
, NULL
);