From 471b1045226249deacf12ad419b24d962bded880 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 6 Mar 2012 16:10:41 -0500 Subject: rt-graph: real-time plots now draw other events Vertical lines mark events which were run either with the tasks pid or ran on the task's cpu while it is executing. --- parse-events.h | 1 + rt-graph.c | 172 +++++++++++++++++++++++++++++++++--------------- rt-graph.h | 46 ++++++++----- rt-plot-task.c | 201 ++++++++++++++++++++++++++++++--------------------------- rt-plot-task.h | 6 ++ 5 files changed, 265 insertions(+), 161 deletions(-) diff --git a/parse-events.h b/parse-events.h index 67e7886..56cef4a 100644 --- a/parse-events.h +++ b/parse-events.h @@ -406,6 +406,7 @@ struct pevent { /* cache */ struct event_format *last_event; + }; /* Can be overridden */ diff --git a/rt-graph.c b/rt-graph.c index 06fb6ab..5b8c759 100644 --- a/rt-graph.c +++ b/rt-graph.c @@ -1,7 +1,7 @@ #include "rt-graph.h" #include "trace-hash.h" -#define DEBUG_LEVEL 1 +#define DEBUG_LEVEL 4 #if DEBUG_LEVEL > 0 #define dprintf(l, x...) \ do { \ @@ -12,6 +12,72 @@ #define dprintf(l, x...) do { if (0) printf(x); } while (0) #endif +static guint get_event_hash_key(gint eid) +{ + return trace_hash(eid) % TS_HASH_SIZE; +} + +struct format_field* find_ts_hash(struct ts_list **events, + gint key, gint eid) +{ + struct ts_list *list; + for (list = events[key]; list; list = list->next) { + if (list->eid == eid) + return list->ts_field; + } + return NULL; +} + +/* + * Return format field for @eid, caching its location if this is the first try + */ +static struct format_field* add_ts_hash(struct ts_list **events, gint eid, gint key, + struct pevent *pevent, struct record *record) +{ + struct ts_list *list; + struct format_field *field; + struct event_format *event; + + event = pevent_find_event(pevent, eid); + if (!event) + die("Could not find event %d for record!\n", eid); + field = pevent_find_field(event, RT_TS_FIELD); + + list = malloc_or_die(sizeof(*list)); + list->eid = eid; + list->next = events[key]; + list->ts_field = field; + events[key] = list; + + return field; +} + +/** + * rt_graph_check_any - parse timestamp of any record + * @epid: set to the event's task PID + * @rt_ts: set to the event's real-time timestamp + */ +void rt_graph_check_any(struct rt_graph_info *rtinfo, + struct pevent *pevent, struct record *record, + gint *epid, unsigned long long *ts) +{ + guint key, eid; + struct format_field *field; + + eid = pevent_data_type(pevent, record); + key = get_event_hash_key(eid); + field = find_ts_hash(rtinfo->events, key, eid); + + if (!field) + field = add_ts_hash(rtinfo->events, eid, key, pevent, record); + + *epid = pevent_data_pid(pevent, record); + pevent_read_number_field(field, record->data, ts); + + dprintf(3, "Read (%d) record for task %d at %llu\n", + eid, *epid, *ts); +} + /** * rt_graph_check_task_param - check for litmus_task_param record * Return 1 and @pid, @wcet, and @period if the record matches @@ -63,88 +129,88 @@ int rt_graph_check_task_param(struct rt_graph_info *rtinfo, } /** - * rt_graph_check_task_switch_to - check for litmus_task_switch_to record - * Return 1 and @pid, @job, and @when if the record matches + * rt_graph_check_switch_to - check for litmus_switch_to record + * Return 1 and @pid, @job, and @ts if the record matches */ -int rt_graph_check_task_switch_to(struct rt_graph_info *rtinfo, +int rt_graph_check_switch_to(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, gint *pid, gint *job, - unsigned long long *when) + unsigned long long *ts) { struct event_format *event; unsigned long long val; gint id; int ret = 0; - if (rtinfo->task_switch_to_id < 0) { + if (rtinfo->switch_to_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", - "litmus_task_switch_to"); + "litmus_switch_to"); if (!event) goto out; - rtinfo->task_switch_to_id = event->id; - dprintf(2, "Found task_switch_to id %d\n", event->id); + rtinfo->switch_to_id = event->id; + dprintf(2, "Found switch_to id %d\n", event->id); rtinfo->switch_to_pid_field = pevent_find_field(event, "pid"); rtinfo->switch_to_job_field = pevent_find_field(event, "job"); - rtinfo->switch_to_when_field = pevent_find_field(event, "when"); + rtinfo->switch_to_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_switch_to_id) { + if (id == rtinfo->switch_to_id) { pevent_read_number_field(rtinfo->switch_to_pid_field, record->data, &val); *pid = val; pevent_read_number_field(rtinfo->switch_to_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->switch_to_when_field, - record->data, when); + pevent_read_number_field(rtinfo->switch_to_ts_field, + record->data, ts); ret = 1; - dprintf(3, "Read task_switch_to (%d) record for job %d:%d, " - "when: %llu\n", id, *pid, *job, *when); + dprintf(3, "Read switch_to (%d) record for job %d:%d, " + "ts: %llu\n", id, *pid, *job, *ts); } out: return ret; } /** - * rt_graph_check_task_switch_away - check for litmus_task_switch_away record - * Return 1 and @pid, @job, and @when if the record matches + * rt_graph_check_switch_away - check for litmus_switch_away record + * Return 1 and @pid, @job, and @ts if the record matches */ -int rt_graph_check_task_switch_away(struct rt_graph_info *rtinfo, +int rt_graph_check_switch_away(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, gint *pid, gint *job, - unsigned long long *when) + unsigned long long *ts) { struct event_format *event; unsigned long long val; gint id; int ret = 0; - if (rtinfo->task_switch_away_id < 0) { + if (rtinfo->switch_away_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", - "litmus_task_switch_away"); + "litmus_switch_away"); if (!event) goto out; - rtinfo->task_switch_away_id = event->id; - dprintf(2, "Found task_switch_away id %d\n", event->id); + rtinfo->switch_away_id = event->id; + dprintf(2, "Found switch_away id %d\n", event->id); rtinfo->switch_away_pid_field = pevent_find_field(event, "pid"); rtinfo->switch_away_job_field = pevent_find_field(event, "job"); - rtinfo->switch_away_when_field = pevent_find_field(event, "when"); + rtinfo->switch_away_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_switch_away_id) { + if (id == rtinfo->switch_away_id) { pevent_read_number_field(rtinfo->switch_away_pid_field, record->data, &val); *pid = val; pevent_read_number_field(rtinfo->switch_away_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->switch_away_when_field, - record->data, when); + pevent_read_number_field(rtinfo->switch_away_ts_field, + record->data, ts); ret = 1; - dprintf(3, "Read task_switch_away (%d) record for job %d:%d, " - "when: %llu\n", id, *pid, *job, *when); + dprintf(3, "Read switch_away (%d) record for job %d:%d, " + "ts: %llu\n", id, *pid, *job, *ts); } out: return ret; @@ -156,7 +222,8 @@ int rt_graph_check_task_switch_away(struct rt_graph_info *rtinfo, */ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, - gint *pid, gint *job, unsigned long long *release, + gint *pid, gint *job, + unsigned long long *release, unsigned long long *deadline) { struct event_format *event; @@ -191,7 +258,8 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, record->data, deadline); ret = 1; dprintf(3, "Read task_release (%d) record for job %d:%d, " - "dead: %llu\n", id, *pid, *job, *deadline); + "release: %llu, dead: %llu\n", id, *pid, *job, *release, + *deadline); } out: return ret; @@ -203,7 +271,7 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, */ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, - gint *pid, gint *job, unsigned long long *when) + gint *pid, gint *job, unsigned long long *ts) { struct event_format *event; unsigned long long val; @@ -219,7 +287,7 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, dprintf(2, "Found task_completion id %d\n", event->id); rtinfo->completion_pid_field = pevent_find_field(event, "pid"); rtinfo->completion_job_field = pevent_find_field(event, "job"); - rtinfo->completion_when_field = pevent_find_field(event, "when"); + rtinfo->completion_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); @@ -230,11 +298,11 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, pevent_read_number_field(rtinfo->completion_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->completion_when_field, - record->data, when); + pevent_read_number_field(rtinfo->completion_ts_field, + record->data, ts); ret = 1; - dprintf(3, "Read task_completion (%d) record for job %d:%d\n", - id, *pid, *job); + dprintf(3, "Read task_completion (%d) record for job %d:%d " + "ts: %llu\n", id, *pid, *job, *ts); } out: return ret; @@ -246,7 +314,7 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, */ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, - gint *pid, unsigned long long *when) + gint *pid, unsigned long long *ts) { struct event_format *event; unsigned long long val; @@ -261,7 +329,7 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, dprintf(2, "Found task_block id %d\n", event->id); rtinfo->task_block_id = event->id; rtinfo->block_pid_field = pevent_find_field(event, "pid"); - rtinfo->block_when_field = pevent_find_field(event, "when"); + rtinfo->block_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); @@ -269,8 +337,8 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, pevent_read_number_field(rtinfo->block_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->block_when_field, - record->data, when); + pevent_read_number_field(rtinfo->block_ts_field, + record->data, ts); ret = 1; dprintf(3, "Read task_block (%d) record for task %d\n", id, *pid); @@ -285,7 +353,7 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, */ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, - gint *pid, unsigned long long *when) + gint *pid, unsigned long long *ts) { struct event_format *event; unsigned long long val; @@ -300,7 +368,7 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, dprintf(2, "Found task_resume id %d\n", event->id); rtinfo->task_resume_id = event->id; rtinfo->resume_pid_field = pevent_find_field(event, "pid"); - rtinfo->resume_when_field = pevent_find_field(event, "when"); + rtinfo->resume_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); @@ -308,8 +376,8 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, pevent_read_number_field(rtinfo->resume_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->resume_when_field, - record->data, when); + pevent_read_number_field(rtinfo->resume_ts_field, + record->data, ts); ret = 1; dprintf(3, "Read task_resume (%d) record for task %d\n", id, *pid); @@ -325,8 +393,8 @@ void init_rt_event_cache(struct rt_graph_info *rtinfo) { dprintf(1, "Initializing RT event cache\n"); rtinfo->task_param_id = -1; - rtinfo->task_switch_to_id = -1; - rtinfo->task_switch_away = -1; + rtinfo->switch_to_id = -1; + rtinfo->switch_away_id = -1; rtinfo->task_release_id = -1; rtinfo->task_completion_id = -1; rtinfo->task_block_id = -1; @@ -338,11 +406,11 @@ void init_rt_event_cache(struct rt_graph_info *rtinfo) rtinfo->switch_to_pid_field = NULL; rtinfo->switch_to_job_field = NULL; - rtinfo->switch_to_when_field = NULL; + rtinfo->switch_to_ts_field = NULL; rtinfo->switch_away_pid_field = NULL; rtinfo->switch_away_job_field = NULL; - rtinfo->switch_away_when_field = NULL; + rtinfo->switch_away_ts_field = NULL; rtinfo->release_pid_field = NULL; rtinfo->release_job_field = NULL; @@ -351,11 +419,11 @@ void init_rt_event_cache(struct rt_graph_info *rtinfo) rtinfo->completion_pid_field = NULL; rtinfo->completion_job_field = NULL; - rtinfo->completion_when_field = NULL; + rtinfo->completion_ts_field = NULL; rtinfo->block_pid_field = NULL; - rtinfo->block_when_field = NULL; + rtinfo->block_ts_field = NULL; rtinfo->resume_pid_field = NULL; - rtinfo->resume_when_field = NULL; + rtinfo->resume_ts_field = NULL; } diff --git a/rt-graph.h b/rt-graph.h index 8fbe6f3..be9aa44 100644 --- a/rt-graph.h +++ b/rt-graph.h @@ -6,6 +6,10 @@ #include "trace-cmd.h" #include "rt-plot-task.h" +#define RT_TS_FIELD "__rt_ts" +#define TS_HASH_SIZE 6 +struct ts_list; + struct rt_graph_info { /* List of all real-time tasks */ @@ -19,15 +23,15 @@ struct rt_graph_info { struct format_field *param_wcet_field; struct format_field *param_period_field; - gint task_switch_to_id; + gint switch_to_id; struct format_field *switch_to_pid_field; struct format_field *switch_to_job_field; - struct format_field *switch_to_when_field; + struct format_field *switch_to_ts_field; - gint task_switch_away_id; - struct format_field *switch_to_pid_field; - struct format_field *switch_to_job_field; - struct format_field *switch_to_when_field; + gint switch_away_id; + struct format_field *switch_away_pid_field; + struct format_field *switch_away_job_field; + struct format_field *switch_away_ts_field; gint task_release_id; struct format_field *release_pid_field; @@ -38,28 +42,40 @@ struct rt_graph_info { gint task_completion_id; struct format_field *completion_pid_field; struct format_field *completion_job_field; - struct format_field *completion_when_field; + struct format_field *completion_ts_field; gint task_block_id; struct format_field *block_pid_field; - struct format_field *block_when_field; + struct format_field *block_ts_field; gint task_resume_id; struct format_field *resume_pid_field; - struct format_field *resume_when_field; + struct format_field *resume_ts_field; + + /* Cache of ts fields for new events */ + struct ts_list *events[TS_HASH_SIZE]; +}; + +struct ts_list { + struct ts_list *next; + gint eid; + struct format_field *ts_field; }; /* Event parsers */ +void rt_graph_check_any(struct rt_graph_info *rtinfo, + struct pevent *pevent, struct record *record, + gint *epid, unsigned long long *ts); int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, gint *pid, unsigned long long *wcet, unsigned long long *period); -int rt_graph_check_task_switch_to(struct rt_graph_info *rtinfo, struct pevent *pevent, - struct record *record, gint *pid, gint *job, - unsigned long long *when); -int rt_graph_check_task_switch_away(struct rt_graph_info *rtinfo, struct pevent *pevent, - struct record *record, gint *pid, gint *job, - unsigned long long *when); +int rt_graph_check_switch_to(struct rt_graph_info *rtinfo, struct pevent *pevent, + struct record *record, gint *pid, gint *job, + unsigned long long *when); +int rt_graph_check_switch_away(struct rt_graph_info *rtinfo, struct pevent *pevent, + struct record *record, gint *pid, gint *job, + unsigned long long *when); int rt_graph_check_task_release(struct rt_graph_info *rtinfo, struct pevent *pevent, struct record *record, gint *pid, gint *job, unsigned long long *release, diff --git a/rt-plot-task.c b/rt-plot-task.c index d1af3d6..8be1888 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c @@ -2,26 +2,30 @@ #define LLABEL 30 +#define DEBUG_LEVEL 4 +#if DEBUG_LEVEL > 0 +#define dprintf(l, x...) \ + do { \ + if (l <= DEBUG_LEVEL) \ + printf(x); \ + } while (0) +#else +#define dprintf(l, x...) do { if (0) printf(x); } while (0) +#endif + /* Ok to do it this way as long as it remains single threaded */ static void update_job(struct rt_task_info *rtt_info, int job) { if (job < rtt_info->last_job) { die("Inconsistent job state for %d:%d -> %d\n", rtt_info->base.pid, rtt_info->last_job, job); - } - if (job > rtt_info->last_job) { + } else if (job > rtt_info->last_job) { rtt_info->last_job = job; snprintf(rtt_info->label, LLABEL, "%d:%d", rtt_info->base.pid, rtt_info->last_job); } } -static inline void create_job_label(char *label, int pid, int job) -{ - label = malloc_or_die(20); - snprintf(label, 20, "%d:%d", pid, job); -} - static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, struct record *record, struct plot_info *info) { @@ -35,10 +39,10 @@ static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, match = rt_graph_check_task_param(&ginfo->rtinfo, ginfo->pevent, record, &pid, &wcet, &period); if (match && pid == rtt_info->base.pid) { + update_job(rtt_info, 0); rtt_info->wcet = wcet; rtt_info->period = period; rtt_info->params_found = TRUE; - update_job(rtt_info, 0); ret = 1; } out: @@ -56,6 +60,7 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, record, &pid, &job, &release, &deadline); if (match && pid == rtt_info->base.pid) { + update_job(rtt_info, job); info->release = TRUE; info->rtime = release; info->rlabel = rtt_info->label; @@ -64,7 +69,6 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, info->dtime = deadline; info->dlabel = rtt_info->label; - update_job(rtt_info, job); ret = 1; } return ret; @@ -75,15 +79,15 @@ static int try_completion(struct graph_info *ginfo, struct record *record, struct plot_info *info) { int pid, job, match, ret = 0; - unsigned long long when; + unsigned long long ts; match = rt_graph_check_task_completion(&ginfo->rtinfo, ginfo->pevent, - record, &pid, &job, &when); + record, &pid, &job, &ts); if (match && pid == rtt_info->base.pid) { + update_job(rtt_info, job); info->completion = TRUE; - info->ctime = when; + info->ctime = ts; info->clabel = rtt_info->label; - update_job(rtt_info, job); ret = 1; } return ret; @@ -93,12 +97,12 @@ static int try_block(struct graph_info *ginfo, struct rt_task_info *rtt_info, struct record *record, struct plot_info *info) { int pid, match, ret = 0; - unsigned long long when; + unsigned long long ts; match = rt_graph_check_task_block(&ginfo->rtinfo, ginfo->pevent, - record, &pid, &when); + record, &pid, &ts); if (match && pid == rtt_info->base.pid) { - rtt_info->block_time = when; + rtt_info->block_time = ts; ret = 1; } return ret; @@ -108,92 +112,106 @@ static int try_resume(struct graph_info *ginfo, struct rt_task_info *rtt_info, struct record *record, struct plot_info *info) { int pid, match, ret = 0; - unsigned long long when; + unsigned long long ts; match = rt_graph_check_task_resume(&ginfo->rtinfo, ginfo->pevent, - record, &pid, &when); + record, &pid, &ts); if (match && pid == rtt_info->base.pid) { - rtt_info->block_time = when; info->box = TRUE; info->bcolor = 0x0; info->bfill = TRUE; info->bthin = TRUE; info->bstart = rtt_info->block_time; - info->bend = when; + info->bend = ts; - rtt_info->block_time = -1; + rtt_info->block_time = 0ULL; ret = 1; } return ret; } -static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, - struct record *record, struct plot_info *info) +static unsigned long long +try_switch_away(struct graph_info *ginfo, struct rt_task_info *rtt_info, + struct record *record, struct plot_info *info) { - int pid, is_sched, is_wakeup, rec_pid, sched_pid, match, ret = 0; - struct task_plot_info *task_info = &rtt_info->base; + int job, pid, match, ret = 0; + unsigned long long ts; + + match = rt_graph_check_switch_away(&ginfo->rtinfo, ginfo->pevent, + record, &pid, &job, &ts); + if (match && pid == rtt_info->base.pid) { + update_job(rtt_info, job); + + if (rtt_info->run_time && rtt_info->run_time < ts) { + dprintf(3, "Box for %d:%d, %llu to %llu on CPU %d\n", + rtt_info->base.pid, rtt_info->last_job, + rtt_info->run_time, ts, rtt_info->last_cpu); + info->box = TRUE; + info->bcolor = hash_cpu(rtt_info->last_cpu); + info->bfill = TRUE; + info->bstart = rtt_info->run_time; + info->bend = ts; + info->blabel = rtt_info->label; + } + + rtt_info->run_time = 0ULL; + rtt_info->last_cpu = -1; - pid = task_info->pid; - match = record_matches_pid(ginfo, record, pid, &rec_pid, - &sched_pid, &is_sched, &is_wakeup); - if (match) { - info->line = TRUE; - info->lcolor = hash_pid(rec_pid); - info->ltime = record->ts; ret = 1; + } + return ret; +} - update_last_task_record(ginfo, task_info, record); +static int try_switch_to(struct graph_info *ginfo, struct rt_task_info *rtt_info, + struct record *record, struct plot_info *info) +{ + int job, pid, match, ret = 0; + unsigned long long ts; - if (is_wakeup) { - /* Another task is running on this CPU now */ - info->ltime = hash_pid(rec_pid); - if (task_info->last_cpu == record->cpu) { - info->box = TRUE; - info->bcolor = hash_cpu(task_info->last_cpu); - info->bstart = task_info->last_time; - info->bend = record->ts; - task_info->last_cpu = -1; - } - goto out; - } + match = rt_graph_check_switch_to(&ginfo->rtinfo, ginfo->pevent, + record, &pid, &job, &ts); + if (match && pid == rtt_info->base.pid) { + update_job(rtt_info, job); - if (task_info->last_cpu != record->cpu) { - /* Switched cpus */ - if (task_info->last_cpu >= 0) { - info->box = TRUE; - info->bcolor = hash_cpu(task_info->last_cpu); - info->bstart = task_info->last_time; - info->bend = record->ts; - } - task_info->last_time = record->ts; - } + rtt_info->run_time = ts; + rtt_info->last_cpu = record->cpu; - task_info->last_cpu = record->cpu; - if (is_sched) { - if (rec_pid != pid) { - /* Scheduled in */ - task_info->last_cpu = record->cpu; - task_info->last_time = record->ts; - } else if (!info->box) { - /* Scheduled out */ - info->box = TRUE; - info->bcolor = hash_cpu(task_info->last_cpu); - info->bstart = task_info->last_time; - info->bend = record->ts; - task_info->last_cpu = -1; - } - } + info->line = TRUE; + info->lcolor = hash_pid(record->cpu); + info->ltime = ts; + + dprintf(3, "Switching to %d:%d at %llu on CPU %d\n", + rtt_info->base.pid, rtt_info->last_job, + ts, rtt_info->last_cpu); + + ret = 1; } - out: - if (info->box) { - info->blabel = rtt_info->label; + return ret; +} + +static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, + struct record *record, struct plot_info *info) +{ + int pid, epid, ret = 0; + unsigned long long ts; + struct task_plot_info *task_info = &rtt_info->base; + + pid = task_info->pid; + rt_graph_check_any(&ginfo->rtinfo, ginfo->pevent, record, &epid, &ts); + + if (pid == epid || record->cpu == rtt_info->last_cpu) { + info->line = TRUE; + info->lcolor = hash_pid(record->cpu); + info->ltime = ts; + ret = 1; } + return ret; } -int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, - struct record *record, struct plot_info *info) +static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, + struct record *record, struct plot_info *info) { struct rt_task_info *rtt_info = plot->private; struct task_plot_info *task_info = &rtt_info->base; @@ -215,11 +233,13 @@ int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, return 0; } - match = try_param(ginfo, rtt_info, record, info) || - try_release(ginfo, rtt_info, record, info) || - try_completion(ginfo, rtt_info, record, info) || - try_block(ginfo, rtt_info, record, info) || - try_resume(ginfo, rtt_info, record, info) || + match = try_param(ginfo, rtt_info, record, info) || + try_switch_away(ginfo, rtt_info, record, info) || + try_switch_to(ginfo, rtt_info, record, info) || + try_release(ginfo, rtt_info, record, info) || + try_completion(ginfo, rtt_info, record, info) || + try_block(ginfo, rtt_info, record, info) || + try_resume(ginfo, rtt_info, record, info) || try_other(ginfo, rtt_info, record, info); /* This record is neither on our CPU nor related to us, useless */ @@ -238,24 +258,15 @@ int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, free_record(task_info->last_records[cpu]); task_info->last_records[cpu] = record; } - - /* We were on a CPU, now scheduled out */ - if (task_info->last_cpu >= 0) { - info->box = TRUE; - info->bcolor = hash_cpu(task_info->last_cpu); - info->bstart = task_info->last_time; - info->bend = record->ts; - task_info->last_cpu = -1; - } } else { update_last_task_record(ginfo, task_info, record); } - out: + return 1; } -void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot, - unsigned long long time) +static void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot, + unsigned long long time) { struct rt_task_info *rtt_info = plot->private; @@ -263,13 +274,15 @@ void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot, rtt_info->wcet = 0ULL; rtt_info->period = 0ULL; + rtt_info->run_time = 0ULL; rtt_info->block_time = 0ULL; + rtt_info->last_cpu = -1; rtt_info->last_job = -1; rtt_info->params_found = FALSE; update_job(rtt_info, 0); } -void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) +static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) { struct rt_task_info *rtt_info = plot->private; free(rtt_info->label); diff --git a/rt-plot-task.h b/rt-plot-task.h index a11d347..40971fd 100644 --- a/rt-plot-task.h +++ b/rt-plot-task.h @@ -5,10 +5,16 @@ struct rt_task_info { struct task_plot_info base; + unsigned long long wcet; unsigned long long period; + + unsigned long long run_time; unsigned long long block_time; + int last_job; + int last_cpu; + gboolean params_found; char *label; }; -- cgit v1.2.2