aboutsummaryrefslogtreecommitdiffstats
path: root/trace-graph.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-15 18:56:11 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-17 22:50:39 -0500
commitbedeaf452495fcbccb82f23ecf81aa4c41e4f3ab (patch)
treee825f6053bef0c863589172af2513f1597633224 /trace-graph.c
parentb7f179695496dc25b72175a3fcaf4163c8ee9027 (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.c102
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
44static gint ftrace_sched_switch_id = -1;
45static gint event_sched_switch_id = -1;
46
44static void convert_nano(unsigned long long time, unsigned long *sec, 47static 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
202static 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
199static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y) 254static 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