diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-12-15 18:56:11 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-12-17 22:50:39 -0500 |
commit | bedeaf452495fcbccb82f23ecf81aa4c41e4f3ab (patch) | |
tree | e825f6053bef0c863589172af2513f1597633224 /trace-graph.c | |
parent | b7f179695496dc25b72175a3fcaf4163c8ee9027 (diff) |
Add check_sched_switch()
Add code to look for sched_switch events to be able to box in
the events based on the tasks running.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'trace-graph.c')
-rw-r--r-- | trace-graph.c | 102 |
1 files changed, 94 insertions, 8 deletions
diff --git a/trace-graph.c b/trace-graph.c index 2d58c36..54ea341 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
@@ -41,6 +41,9 @@ | |||
41 | #define CPU_TOP(cpu) (CPU_MIDDLE(cpu) - 10) | 41 | #define CPU_TOP(cpu) (CPU_MIDDLE(cpu) - 10) |
42 | #define CPU_BOTTOM(cpu) (CPU_MIDDLE(cpu) + 10) | 42 | #define CPU_BOTTOM(cpu) (CPU_MIDDLE(cpu) + 10) |
43 | 43 | ||
44 | static gint ftrace_sched_switch_id = -1; | ||
45 | static gint event_sched_switch_id = -1; | ||
46 | |||
44 | static void convert_nano(unsigned long long time, unsigned long *sec, | 47 | static void convert_nano(unsigned long long time, unsigned long *sec, |
45 | unsigned long *usec) | 48 | unsigned long *usec) |
46 | { | 49 | { |
@@ -196,6 +199,58 @@ static void print_rec_info(struct record *record, struct pevent *pevent, int cpu | |||
196 | 199 | ||
197 | #define CPU_BOARDER 5 | 200 | #define CPU_BOARDER 5 |
198 | 201 | ||
202 | static int check_sched_switch(struct graph_info *ginfo, | ||
203 | struct record *record, | ||
204 | gint *pid, const char **comm) | ||
205 | { | ||
206 | static struct format_field *event_pid_field; | ||
207 | static struct format_field *event_comm_field; | ||
208 | static struct format_field *ftrace_pid_field; | ||
209 | static struct format_field *ftrace_comm_field; | ||
210 | unsigned long long val; | ||
211 | struct event *event; | ||
212 | gint id; | ||
213 | |||
214 | if (event_sched_switch_id < 0) { | ||
215 | event = pevent_find_event_by_name(ginfo->pevent, | ||
216 | "ftrace", "context_switch"); | ||
217 | if (event) { | ||
218 | ftrace_sched_switch_id = event->id; | ||
219 | ftrace_pid_field = pevent_find_field(event, "next_pid"); | ||
220 | ftrace_comm_field = pevent_find_field(event, "next_comm"); | ||
221 | } | ||
222 | |||
223 | event = pevent_find_event_by_name(ginfo->pevent, | ||
224 | "sched", "sched_switch"); | ||
225 | if (!event) | ||
226 | die("can't find event sched_switch!"); | ||
227 | event_sched_switch_id = event->id; | ||
228 | event_pid_field = pevent_find_field(event, "next_pid"); | ||
229 | event_comm_field = pevent_find_field(event, "next_comm"); | ||
230 | } | ||
231 | |||
232 | id = pevent_data_type(ginfo->pevent, record); | ||
233 | if (id == event_sched_switch_id) { | ||
234 | pevent_read_number_field(event_pid_field, record->data, &val); | ||
235 | if (comm) | ||
236 | *comm = record->data + event_comm_field->offset; | ||
237 | if (pid) | ||
238 | *pid = val; | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | if (id == ftrace_sched_switch_id) { | ||
243 | pevent_read_number_field(ftrace_pid_field, record->data, &val); | ||
244 | if (comm) | ||
245 | *comm = record->data + ftrace_comm_field->offset; | ||
246 | if (pid) | ||
247 | *pid = val; | ||
248 | return 1; | ||
249 | } | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
199 | static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) | 254 | static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) |
200 | { | 255 | { |
201 | PangoLayout *layout; | 256 | PangoLayout *layout; |
@@ -211,6 +266,7 @@ static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) | |||
211 | gint width, height; | 266 | gint width, height; |
212 | GdkPixmap *pix; | 267 | GdkPixmap *pix; |
213 | static GdkGC *pix_bg; | 268 | static GdkGC *pix_bg; |
269 | guint64 offset = 0; | ||
214 | 270 | ||
215 | if (!pix_bg) { | 271 | if (!pix_bg) { |
216 | GdkColor color; | 272 | GdkColor color; |
@@ -234,21 +290,32 @@ static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) | |||
234 | printf("start=%zu end=%zu time=%lu\n", ginfo->start_time, ginfo->end_time, time); | 290 | printf("start=%zu end=%zu time=%lu\n", ginfo->start_time, ginfo->end_time, time); |
235 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); | 291 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, time); |
236 | do { | 292 | do { |
237 | if (record) | 293 | if (record) { |
238 | free(record); | 294 | offset = record->offset; |
295 | free_record(record); | ||
296 | } | ||
239 | record = tracecmd_read_data(ginfo->handle, cpu); | 297 | record = tracecmd_read_data(ginfo->handle, cpu); |
240 | } while (record && record->ts <= (time - 1 / ginfo->resolution)); | 298 | } while (record && record->ts <= (time - 1 / ginfo->resolution)); |
241 | 299 | ||
242 | if (record) { | 300 | if (record) { |
243 | 301 | ||
244 | pid = pevent_data_pid(ginfo->pevent, record); | 302 | if (record->ts > (time + 1 / ginfo->resolution) && offset) { |
245 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); | 303 | printf("old ts = %llu!\n", record->ts); |
304 | free_record(record); | ||
305 | record = tracecmd_read_at(ginfo->handle, offset, NULL); | ||
306 | } | ||
307 | |||
308 | if (!check_sched_switch(ginfo, record, &pid, &comm)) { | ||
309 | pid = pevent_data_pid(ginfo->pevent, record); | ||
310 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); | ||
311 | } | ||
246 | 312 | ||
247 | printf("record->ts=%llu time=%zu-%zu\n", | 313 | printf("record->ts=%llu time=%zu-%zu\n", |
248 | record->ts, time, time+(gint)(5/ginfo->resolution)); | 314 | record->ts, time, time-(gint)(1/ginfo->resolution)); |
249 | print_rec_info(record, pevent, cpu); | 315 | print_rec_info(record, pevent, cpu); |
250 | 316 | ||
251 | if (record->ts < time + 1/ginfo->resolution) { | 317 | if (record->ts > time - 2/ginfo->resolution && |
318 | record->ts < time + 2/ginfo->resolution) { | ||
252 | convert_nano(record->ts, &sec, &usec); | 319 | convert_nano(record->ts, &sec, &usec); |
253 | 320 | ||
254 | type = pevent_data_type(pevent, record); | 321 | type = pevent_data_type(pevent, record); |
@@ -402,6 +469,8 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
402 | struct record *record; | 469 | struct record *record; |
403 | static GdkGC *gc; | 470 | static GdkGC *gc; |
404 | guint64 ts; | 471 | guint64 ts; |
472 | gint last_pid = 0; | ||
473 | gint last_x = 0; | ||
405 | gint pid; | 474 | gint pid; |
406 | gint x; | 475 | gint x; |
407 | 476 | ||
@@ -416,6 +485,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
416 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, ts); | 485 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, ts); |
417 | 486 | ||
418 | while ((record = tracecmd_read_data(ginfo->handle, cpu))) { | 487 | while ((record = tracecmd_read_data(ginfo->handle, cpu))) { |
488 | |||
419 | if (record->ts > ginfo->view_end_time) | 489 | if (record->ts > ginfo->view_end_time) |
420 | break; | 490 | break; |
421 | 491 | ||
@@ -423,7 +493,23 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
423 | 493 | ||
424 | x = (gint)((gdouble)ts * ginfo->resolution); | 494 | x = (gint)((gdouble)ts * ginfo->resolution); |
425 | 495 | ||
426 | pid = pevent_data_pid(ginfo->pevent, record); | 496 | |
497 | if (!check_sched_switch(ginfo, record, &pid, NULL)) | ||
498 | pid = pevent_data_pid(ginfo->pevent, record); | ||
499 | |||
500 | if (last_pid != pid) { | ||
501 | if (last_pid) { | ||
502 | gdk_draw_line(ginfo->curr_pixmap, gc, | ||
503 | last_x, CPU_TOP(cpu), | ||
504 | x, CPU_TOP(cpu)); | ||
505 | gdk_draw_line(ginfo->curr_pixmap, gc, | ||
506 | last_x, CPU_BOTTOM(cpu), | ||
507 | x, CPU_BOTTOM(cpu)); | ||
508 | } | ||
509 | |||
510 | last_x = x; | ||
511 | last_pid = pid; | ||
512 | } | ||
427 | 513 | ||
428 | set_color_by_pid(ginfo->draw, gc, pid); | 514 | set_color_by_pid(ginfo->draw, gc, pid); |
429 | 515 | ||