0001
0002
0003
0004
0005 #include <stdio.h>
0006 #include <stdlib.h>
0007 #include <string.h>
0008
0009 #include "event-parse.h"
0010 #include "trace-seq.h"
0011
0012 static void write_state(struct trace_seq *s, int val)
0013 {
0014 const char states[] = "SDTtZXxW";
0015 int found = 0;
0016 int i;
0017
0018 for (i = 0; i < (sizeof(states) - 1); i++) {
0019 if (!(val & (1 << i)))
0020 continue;
0021
0022 if (found)
0023 trace_seq_putc(s, '|');
0024
0025 found = 1;
0026 trace_seq_putc(s, states[i]);
0027 }
0028
0029 if (!found)
0030 trace_seq_putc(s, 'R');
0031 }
0032
0033 static void write_and_save_comm(struct tep_format_field *field,
0034 struct tep_record *record,
0035 struct trace_seq *s, int pid)
0036 {
0037 const char *comm;
0038 int len;
0039
0040 comm = (char *)(record->data + field->offset);
0041 len = s->len;
0042 trace_seq_printf(s, "%.*s",
0043 field->size, comm);
0044
0045
0046 trace_seq_terminate(s);
0047 comm = &s->buffer[len];
0048
0049
0050 tep_register_comm(field->event->tep, comm, pid);
0051 }
0052
0053 static int sched_wakeup_handler(struct trace_seq *s,
0054 struct tep_record *record,
0055 struct tep_event *event, void *context)
0056 {
0057 struct tep_format_field *field;
0058 unsigned long long val;
0059
0060 if (tep_get_field_val(s, event, "pid", record, &val, 1))
0061 return trace_seq_putc(s, '!');
0062
0063 field = tep_find_any_field(event, "comm");
0064 if (field) {
0065 write_and_save_comm(field, record, s, val);
0066 trace_seq_putc(s, ':');
0067 }
0068 trace_seq_printf(s, "%lld", val);
0069
0070 if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0)
0071 trace_seq_printf(s, " [%lld]", val);
0072
0073 if (tep_get_field_val(s, event, "success", record, &val, 1) == 0)
0074 trace_seq_printf(s, " success=%lld", val);
0075
0076 if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
0077 trace_seq_printf(s, " CPU:%03llu", val);
0078
0079 return 0;
0080 }
0081
0082 static int sched_switch_handler(struct trace_seq *s,
0083 struct tep_record *record,
0084 struct tep_event *event, void *context)
0085 {
0086 struct tep_format_field *field;
0087 unsigned long long val;
0088
0089 if (tep_get_field_val(s, event, "prev_pid", record, &val, 1))
0090 return trace_seq_putc(s, '!');
0091
0092 field = tep_find_any_field(event, "prev_comm");
0093 if (field) {
0094 write_and_save_comm(field, record, s, val);
0095 trace_seq_putc(s, ':');
0096 }
0097 trace_seq_printf(s, "%lld ", val);
0098
0099 if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
0100 trace_seq_printf(s, "[%d] ", (int) val);
0101
0102 if (tep_get_field_val(s, event, "prev_state", record, &val, 0) == 0)
0103 write_state(s, val);
0104
0105 trace_seq_puts(s, " ==> ");
0106
0107 if (tep_get_field_val(s, event, "next_pid", record, &val, 1))
0108 return trace_seq_putc(s, '!');
0109
0110 field = tep_find_any_field(event, "next_comm");
0111 if (field) {
0112 write_and_save_comm(field, record, s, val);
0113 trace_seq_putc(s, ':');
0114 }
0115 trace_seq_printf(s, "%lld", val);
0116
0117 if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
0118 trace_seq_printf(s, " [%d]", (int) val);
0119
0120 return 0;
0121 }
0122
0123 int TEP_PLUGIN_LOADER(struct tep_handle *tep)
0124 {
0125 tep_register_event_handler(tep, -1, "sched", "sched_switch",
0126 sched_switch_handler, NULL);
0127
0128 tep_register_event_handler(tep, -1, "sched", "sched_wakeup",
0129 sched_wakeup_handler, NULL);
0130
0131 tep_register_event_handler(tep, -1, "sched", "sched_wakeup_new",
0132 sched_wakeup_handler, NULL);
0133 return 0;
0134 }
0135
0136 void TEP_PLUGIN_UNLOADER(struct tep_handle *tep)
0137 {
0138 tep_unregister_event_handler(tep, -1, "sched", "sched_switch",
0139 sched_switch_handler, NULL);
0140
0141 tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup",
0142 sched_wakeup_handler, NULL);
0143
0144 tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup_new",
0145 sched_wakeup_handler, NULL);
0146 }