aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rt-graph.c9
-rw-r--r--rt-graph.h6
-rw-r--r--rt-plot-task.c170
-rw-r--r--trace-graph.c2
4 files changed, 119 insertions, 68 deletions
diff --git a/rt-graph.c b/rt-graph.c
index 5f4d0b0..dda243c 100644
--- a/rt-graph.c
+++ b/rt-graph.c
@@ -57,9 +57,9 @@ static struct format_field* add_ts_hash(struct ts_list **events, gint eid, gint
57 * @epid: set to the event's task PID 57 * @epid: set to the event's task PID
58 * @rt_ts: set to the event's real-time timestamp 58 * @rt_ts: set to the event's real-time timestamp
59 */ 59 */
60void rt_graph_check_any(struct rt_graph_info *rtinfo, 60int rt_graph_check_any(struct rt_graph_info *rtinfo,
61 struct pevent *pevent, struct record *record, 61 struct pevent *pevent, struct record *record,
62 gint *epid, unsigned long long *ts) 62 gint *epid, unsigned long long *ts)
63{ 63{
64 guint key, eid; 64 guint key, eid;
65 struct format_field *field; 65 struct format_field *field;
@@ -76,6 +76,7 @@ void rt_graph_check_any(struct rt_graph_info *rtinfo,
76 76
77 dprintf(3, "Read (%d) record for task %d at %llu\n", 77 dprintf(3, "Read (%d) record for task %d at %llu\n",
78 eid, *epid, *ts); 78 eid, *epid, *ts);
79 return 1;
79} 80}
80 81
81/** 82/**
@@ -347,7 +348,7 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo,
347} 348}
348 349
349/** 350/**
350 * rt_graph_check_task_release - check for litmus_task_release record 351 * rt_graph_check_task_resume - check for litmus_task_resume record
351 * Return 1 and @pid if the record matches 352 * Return 1 and @pid if the record matches
352 */ 353 */
353int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, 354int rt_graph_check_task_resume(struct rt_graph_info *rtinfo,
diff --git a/rt-graph.h b/rt-graph.h
index 17247f6..eeae270 100644
--- a/rt-graph.h
+++ b/rt-graph.h
@@ -63,9 +63,9 @@ struct ts_list {
63}; 63};
64 64
65/* Event parsers */ 65/* Event parsers */
66void rt_graph_check_any(struct rt_graph_info *rtinfo, 66int rt_graph_check_any(struct rt_graph_info *rtinfo,
67 struct pevent *pevent, struct record *record, 67 struct pevent *pevent, struct record *record,
68 gint *epid, unsigned long long *ts); 68 gint *pid, unsigned long long *ts);
69int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent, 69int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent,
70 struct record *record, gint *pid, 70 struct record *record, gint *pid,
71 unsigned long long *wcet, 71 unsigned long long *wcet,
diff --git a/rt-plot-task.c b/rt-plot-task.c
index 8ecbdbb..0b10d91 100644
--- a/rt-plot-task.c
+++ b/rt-plot-task.c
@@ -110,39 +110,23 @@ static gboolean record_matches_pid(struct graph_info *ginfo,
110 struct record *record, 110 struct record *record,
111 int match_pid) 111 int match_pid)
112{ 112{
113 guint eid, pid; 113 gint dint, pid = 0, match = 0;
114 unsigned long long val; 114 unsigned long long dull;
115 struct format_field *pid_field = NULL; 115 struct rt_graph_info *rtg_info = &ginfo->rtinfo;
116 struct rt_graph_info *rtinfo = &ginfo->rtinfo; 116
117 117 /* Must use check_* in case record has not been found yet,
118 eid = pevent_data_type(ginfo->pevent, record); 118 * this macro was the best of many terrible options
119 if (eid == rtinfo->task_param_id) 119 */
120 pid_field = rtinfo->param_pid_field; 120#define MARGS rtg_info, ginfo->pevent, record, &pid
121 else if (eid == rtinfo->switch_to_id) 121 match = rt_graph_check_switch_to(MARGS, &dint, &dull) ||
122 pid_field = rtinfo->switch_to_pid_field; 122 rt_graph_check_switch_away(MARGS, &dint, &dull) ||
123 else if (eid == rtinfo->switch_away_id) 123 rt_graph_check_task_release(MARGS, &dint, &dull, &dull) ||
124 pid_field = rtinfo->switch_away_pid_field; 124 rt_graph_check_task_completion(MARGS, &dint, &dull) ||
125 else if (eid == rtinfo->task_release_id) 125 rt_graph_check_task_block(MARGS, &dull) ||
126 pid_field = rtinfo->release_pid_field; 126 rt_graph_check_task_resume(MARGS, &dull) ||
127 else if (eid == rtinfo->task_completion_id) 127 rt_graph_check_any(MARGS, &dull);
128 pid_field = rtinfo->completion_pid_field; 128#undef MARGS
129 else if (eid == rtinfo->task_block_id) 129 return match && pid == match_pid;
130 pid_field = rtinfo->block_pid_field;
131 else if (eid == rtinfo->task_resume_id)
132 pid_field = rtinfo->resume_pid_field;
133
134 if (pid_field) {
135 pevent_read_number_field(rtinfo->param_pid_field,
136 record->data, &val);
137 pid = val;
138 } else {
139 pid = pevent_data_pid(ginfo->pevent, record);
140 }
141
142 if (pid == match_pid)
143 return TRUE;
144 else
145 return FALSE;
146} 130}
147 131
148struct record* 132struct record*
@@ -240,9 +224,6 @@ static int try_completion(struct graph_info *ginfo,
240 info->completion = TRUE; 224 info->completion = TRUE;
241 info->ctime = ts; 225 info->ctime = ts;
242 info->clabel = rtt_info->label; 226 info->clabel = rtt_info->label;
243 info->line = TRUE;
244 info->lcolor = hash_pid(record->cpu);
245 info->ltime = ts;
246 ret = 1; 227 ret = 1;
247 } 228 }
248 return ret; 229 return ret;
@@ -361,6 +342,65 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info,
361 return ret; 342 return ret;
362} 343}
363 344
345/*
346 * Return information for @time, returns @job, @release, @deadline, and @record.
347 * @job: Job number at this time
348 * @release: Job's release time
349 * @deadline: Job's deadline
350 * @record: Matching record
351 */
352static int get_time_info(struct graph_info *ginfo,
353 struct rt_task_info *rtt_info,
354 unsigned long long time,
355 int *out_job,
356 unsigned long long *out_release,
357 unsigned long long *out_deadline,
358 struct record **out_record)
359
360{
361 int pid, job, match, found_job = 0;
362 unsigned long long release, deadline;
363 struct record *record, *last_record;
364 struct rt_graph_info *rtg_info = &ginfo->rtinfo;
365
366 /* Seek CPUs to first record after this time */
367 *out_record = find_record(ginfo, rtt_info->base.pid, time);
368 if (!*out_record)
369 goto out;
370
371 last_record = *out_record;
372 last_record->ref_count++;
373
374 /* Read backwards for a release record */
375 while ((record = tracecmd_read_prev(ginfo->handle, last_record))) {
376 match = rt_graph_check_task_release(rtg_info, ginfo->pevent,
377 record, &pid, &job,
378 &release, &deadline);
379 free_record(last_record);
380 last_record = record;
381 if (match && pid == rtt_info->base.pid && release <= time) {
382 found_job = TRUE;
383 break;
384 }
385 }
386 free_record(last_record);
387
388 if (found_job) {
389 *out_job = job;
390 *out_release = release;
391 *out_deadline = deadline;
392 }
393 out:
394 return found_job;
395}
396
397static inline int in_res(struct graph_info *ginfo, unsigned long long time,
398 unsigned long target)
399{
400 return time > target - 2/ginfo->resolution &&
401 time < target + 2/ginfo->resolution;
402}
403
364static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, 404static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
365 struct record *record, struct plot_info *info) 405 struct record *record, struct plot_info *info)
366{ 406{
@@ -455,36 +495,46 @@ static int rt_task_plot_display_info(struct graph_info *ginfo,
455 struct trace_seq *s, 495 struct trace_seq *s,
456 unsigned long long time) 496 unsigned long long time)
457{ 497{
458 int type; 498 const char *comm;
499 int show_dead, show_rel, pid, job, eid;
459 struct record *record; 500 struct record *record;
460 struct event_format *event; 501 struct event_format *event;
461 unsigned long sec, usec; 502 unsigned long usec, sec;
503 unsigned long long release, deadline, rts;
462 struct rt_task_info *rtt_info = plot->private; 504 struct rt_task_info *rtt_info = plot->private;
463 505
464 record = find_record(ginfo, rtt_info->base.pid, time); 506 get_time_info(ginfo, rtt_info, time,
465 if (!record) 507 &job, &release, &deadline, &record);
466 return 0; 508 show_rel = in_res(ginfo, release, time);
509 show_dead = in_res(ginfo, deadline, time);
467 510
468 /* Display only if the record's time is close enough */ 511 /* Show real-time data about time */
469 if (get_rts(ginfo, record) > time - 2/ginfo->resolution && 512 pid = rtt_info->base.pid;
470 get_rts(ginfo, record) < time + 2/ginfo->resolution) { 513 comm = pevent_data_comm_from_pid(ginfo->pevent, pid);
471 514 trace_seq_printf(s, "%s - %d:%d\n", comm, pid, job);
472 type = pevent_data_type(ginfo->pevent, record); 515 if (show_rel)
473 event = pevent_data_event_from_type(ginfo->pevent, type); 516 trace_seq_printf(s, "RELEASE\n");
474 if (event) { 517 if (show_dead)
475 trace_seq_puts(s, event->name); 518 trace_seq_printf(s, "DEADLINE\n");
476 trace_seq_putc(s, '\n');
477 pevent_event_info(s, event, record);
478 trace_seq_putc(s, '\n');
479 } else
480 trace_seq_printf(s, "UNKNOWN EVENT %d\n", type);
481 }
482 519
483 /* Display a timestamp always */ 520 if (record) {
484 convert_nano(get_rts(ginfo, record), &sec, &usec); 521 rts = get_rts(ginfo, record);
485 trace_seq_printf(s, "%lu.%06lu CPU: %03d", 522 if (in_res(ginfo, rts, time)) {
486 sec, usec, record->cpu); 523 eid = pevent_data_type(ginfo->pevent, record);
487 free_record(record); 524 event = pevent_data_event_from_type(ginfo->pevent, eid);
525 if (event) {
526 trace_seq_puts(s, event->name);
527 trace_seq_putc(s, '\n');
528 pevent_event_info(s, event, record);
529 trace_seq_putc(s, '\n');
530 } else
531 trace_seq_printf(s, "UNKNOWN EVENT %d\n", eid);
532 }
533 convert_nano(get_rts(ginfo, record), &sec, &usec);
534 trace_seq_printf(s, "%lu.%06lu CPU: %03d",
535 sec, usec, record->cpu);
536 free_record(record);
537 }
488 538
489 return 1; 539 return 1;
490} 540}
diff --git a/trace-graph.c b/trace-graph.c
index 2cf7a95..f94ad50 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -76,7 +76,7 @@ static int convert_time_to_x(struct graph_info *ginfo, guint64 time)
76 return 0; 76 return 0;
77 return (time - ginfo->view_start_time) * ginfo->resolution; 77 return (time - ginfo->view_start_time) * ginfo->resolution;
78} 78}
79 79r
80static guint64 convert_x_to_time(struct graph_info *ginfo, gint x) 80static guint64 convert_x_to_time(struct graph_info *ginfo, gint x)
81{ 81{
82 double d = x; 82 double d = x;