From e15cf27a6fb6f8498def2a4e036483fd7089a530 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 8 Mar 2012 01:37:03 -0500 Subject: rt-graph: input to real-time plots is processed using real-time timestamps Each plot processes only the records which fit within the time window displayed. When passing records into a real-time plot, kernelshark will now decide if a record is within the current time window using real-time timestamps, instead of the old ftrace timestamps. This change also enables infinite zooming into the real-time plots. --- kernel-shark.c | 6 +- rt-graph.c | 223 ++++++++++++++-------------- rt-graph.h | 4 + rt-plot-task.c | 438 ++++++++++++++++++++++++++++++++++--------------------- rt-plot-task.h | 5 +- trace-graph.c | 107 ++++++++++---- trace-graph.h | 2 +- trace-plot-cpu.c | 2 +- 8 files changed, 476 insertions(+), 311 deletions(-) diff --git a/kernel-shark.c b/kernel-shark.c index b24e3b6..1aaf149 100644 --- a/kernel-shark.c +++ b/kernel-shark.c @@ -1272,15 +1272,15 @@ plot_rt_tasks_clicked (gpointer data) { struct shark_info *info = data; struct graph_info *ginfo = info->ginfo; - struct rt_graph_info *rtinfo; + struct rt_graph_info *rtg_info; gint *selected; gint *tasks; if (!ginfo->handle) return; - rtinfo = &ginfo->rtinfo; - tasks = task_list_pids(rtinfo->tasks); + rtg_info = &ginfo->rtg_info; + tasks = task_list_pids(rtg_info->tasks); rt_plot_task_plotted(ginfo, &selected); trace_task_dialog(ginfo->handle, tasks, selected, diff --git a/rt-graph.c b/rt-graph.c index d6b1847..ecb24cb 100644 --- a/rt-graph.c +++ b/rt-graph.c @@ -1,7 +1,7 @@ #include "trace-graph.h" #include "trace-hash.h" -#define DEBUG_LEVEL 4 +#define DEBUG_LEVEL 0 #if DEBUG_LEVEL > 0 #define dprintf(l, x...) \ do { \ @@ -61,7 +61,7 @@ add_ts_hash(struct ts_list **events, gint eid, gint key, * @epid: set to the event's task PID * @rt_ts: set to the event's real-time timestamp */ -int rt_graph_check_any(struct rt_graph_info *rtinfo, +int rt_graph_check_any(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *epid, gint *out_eid, unsigned long long *ts) { @@ -70,10 +70,10 @@ int rt_graph_check_any(struct rt_graph_info *rtinfo, eid = pevent_data_type(pevent, record); key = get_event_hash_key(eid); - field = find_ts_hash(rtinfo->events, key, eid); + field = find_ts_hash(rtg_info->events, key, eid); if (!field) - field = add_ts_hash(rtinfo->events, eid, key, pevent, record); + field = add_ts_hash(rtg_info->events, eid, key, pevent, record); *epid = pevent_data_pid(pevent, record); pevent_read_number_field(field, record->data, ts); @@ -88,7 +88,7 @@ int rt_graph_check_any(struct rt_graph_info *rtinfo, * rt_graph_check_task_param - check for litmus_task_param record * Return 1 and @pid, @wcet, and @period if the record matches */ -int rt_graph_check_task_param(struct rt_graph_info *rtinfo, +int rt_graph_check_task_param(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, unsigned long long *wcet, unsigned long long *period) @@ -102,32 +102,35 @@ int rt_graph_check_task_param(struct rt_graph_info *rtinfo, * after the pevent has "seen" its first litmus_task_param * event. */ - if (rtinfo->task_param_id < 0) { + if (rtg_info->task_param_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_task_param"); if (!event) goto out; - rtinfo->task_param_id = event->id; + rtg_info->task_param_id = event->id; dprintf(2, "Found task_param id %d\n", event->id); - rtinfo->param_pid_field = pevent_find_field(event, "pid"); - rtinfo->param_wcet_field = pevent_find_field(event, "wcet"); - rtinfo->param_period_field = pevent_find_field(event, "period"); + rtg_info->param_pid_field = pevent_find_field(event, "pid"); + rtg_info->param_wcet_field = pevent_find_field(event, "wcet"); + rtg_info->param_period_field = pevent_find_field(event, "period"); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_param_id) { - pevent_read_number_field(rtinfo->param_pid_field, + if (id == rtg_info->task_param_id) { + pevent_read_number_field(rtg_info->param_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->param_wcet_field, + pevent_read_number_field(rtg_info->param_wcet_field, record->data, wcet); - pevent_read_number_field(rtinfo->param_period_field, + pevent_read_number_field(rtg_info->param_period_field, record->data, period); ret = 1; dprintf(3, "Read task_param (%d) record for task %d " "(%llu, %llu)\n", id, *pid, *wcet, *period); - add_task_hash(rtinfo->tasks, *pid); + add_task_hash(rtg_info->tasks, *pid); + + if (*period > rtg_info->max_period) + rtg_info->max_period = *period; } out: return ret; @@ -137,7 +140,7 @@ int rt_graph_check_task_param(struct rt_graph_info *rtinfo, * 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_switch_to(struct rt_graph_info *rtinfo, +int rt_graph_check_switch_to(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, gint *job, unsigned long long *ts) @@ -147,27 +150,27 @@ int rt_graph_check_switch_to(struct rt_graph_info *rtinfo, gint id; int ret = 0; - if (rtinfo->switch_to_id < 0) { + if (rtg_info->switch_to_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_switch_to"); if (!event) goto out; - rtinfo->switch_to_id = event->id; + rtg_info->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_ts_field = pevent_find_field(event, RT_TS_FIELD); + rtg_info->switch_to_pid_field = pevent_find_field(event, "pid"); + rtg_info->switch_to_job_field = pevent_find_field(event, "job"); + rtg_info->switch_to_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->switch_to_id) { - pevent_read_number_field(rtinfo->switch_to_pid_field, + if (id == rtg_info->switch_to_id) { + pevent_read_number_field(rtg_info->switch_to_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->switch_to_job_field, + pevent_read_number_field(rtg_info->switch_to_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->switch_to_ts_field, + pevent_read_number_field(rtg_info->switch_to_ts_field, record->data, ts); ret = 1; dprintf(3, "Read switch_to (%d) record for job %d:%d, " @@ -181,7 +184,7 @@ int rt_graph_check_switch_to(struct rt_graph_info *rtinfo, * 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_switch_away(struct rt_graph_info *rtinfo, +int rt_graph_check_switch_away(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, gint *job, unsigned long long *ts) @@ -191,27 +194,27 @@ int rt_graph_check_switch_away(struct rt_graph_info *rtinfo, gint id; int ret = 0; - if (rtinfo->switch_away_id < 0) { + if (rtg_info->switch_away_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_switch_away"); if (!event) goto out; - rtinfo->switch_away_id = event->id; + rtg_info->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_ts_field = pevent_find_field(event, RT_TS_FIELD); + rtg_info->switch_away_pid_field = pevent_find_field(event, "pid"); + rtg_info->switch_away_job_field = pevent_find_field(event, "job"); + rtg_info->switch_away_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->switch_away_id) { - pevent_read_number_field(rtinfo->switch_away_pid_field, + if (id == rtg_info->switch_away_id) { + pevent_read_number_field(rtg_info->switch_away_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->switch_away_job_field, + pevent_read_number_field(rtg_info->switch_away_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->switch_away_ts_field, + pevent_read_number_field(rtg_info->switch_away_ts_field, record->data, ts); ret = 1; dprintf(3, "Read switch_away (%d) record for job %d:%d, " @@ -225,7 +228,7 @@ int rt_graph_check_switch_away(struct rt_graph_info *rtinfo, * rt_graph_check_task_release - check for litmus_task_release record * Return 1 and @pid, @job, @release, and @deadline if the record matches */ -int rt_graph_check_task_release(struct rt_graph_info *rtinfo, +int rt_graph_check_task_release(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, gint *job, unsigned long long *release, @@ -236,30 +239,30 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, gint id; int ret = 0; - if (rtinfo->task_release_id < 0) { + if (rtg_info->task_release_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_task_release"); if (!event) goto out; - rtinfo->task_release_id = event->id; + rtg_info->task_release_id = event->id; dprintf(2, "Found task_release id %d\n", event->id); - rtinfo->release_pid_field = pevent_find_field(event, "pid"); - rtinfo->release_job_field = pevent_find_field(event, "job"); - rtinfo->release_release_field = pevent_find_field(event, "release"); - rtinfo->release_deadline_field = pevent_find_field(event, "deadline"); + rtg_info->release_pid_field = pevent_find_field(event, "pid"); + rtg_info->release_job_field = pevent_find_field(event, "job"); + rtg_info->release_release_field = pevent_find_field(event, "release"); + rtg_info->release_deadline_field = pevent_find_field(event, "deadline"); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_release_id) { - pevent_read_number_field(rtinfo->release_pid_field, + if (id == rtg_info->task_release_id) { + pevent_read_number_field(rtg_info->release_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->release_job_field, + pevent_read_number_field(rtg_info->release_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->release_release_field, + pevent_read_number_field(rtg_info->release_release_field, record->data, release); - pevent_read_number_field(rtinfo->release_deadline_field, + pevent_read_number_field(rtg_info->release_deadline_field, record->data, deadline); ret = 1; dprintf(3, "Read task_release (%d) record for job %d:%d, " @@ -274,7 +277,7 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, * rt_graph_check_task_completion - check for litmus_task_completion record * Return 1 and @pid, @job, and @ts if the record matches */ -int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, +int rt_graph_check_task_completion(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, gint *job, unsigned long long *ts) { @@ -283,27 +286,27 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, gint id; int ret = 0; - if (rtinfo->task_completion_id < 0) { + if (rtg_info->task_completion_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_task_completion"); if (!event) goto out; - rtinfo->task_completion_id = event->id; + rtg_info->task_completion_id = event->id; 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_ts_field = pevent_find_field(event, RT_TS_FIELD); + rtg_info->completion_pid_field = pevent_find_field(event, "pid"); + rtg_info->completion_job_field = pevent_find_field(event, "job"); + rtg_info->completion_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_completion_id) { - pevent_read_number_field(rtinfo->completion_pid_field, + if (id == rtg_info->task_completion_id) { + pevent_read_number_field(rtg_info->completion_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->completion_job_field, + pevent_read_number_field(rtg_info->completion_job_field, record->data, &val); *job = val; - pevent_read_number_field(rtinfo->completion_ts_field, + pevent_read_number_field(rtg_info->completion_ts_field, record->data, ts); ret = 1; dprintf(3, "Read task_completion (%d) record for job %d:%d " @@ -317,7 +320,7 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, * rt_graph_check_task_block - check for litmus_task_block record * Return 1, @pid, and @ts if the record matches */ -int rt_graph_check_task_block(struct rt_graph_info *rtinfo, +int rt_graph_check_task_block(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, unsigned long long *ts) { @@ -326,23 +329,23 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, gint id; int ret = 0; - if (rtinfo->task_block_id < 0) { + if (rtg_info->task_block_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_task_block"); if (!event) goto out; 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_ts_field = pevent_find_field(event, RT_TS_FIELD); + rtg_info->task_block_id = event->id; + rtg_info->block_pid_field = pevent_find_field(event, "pid"); + rtg_info->block_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_block_id) { - pevent_read_number_field(rtinfo->block_pid_field, + if (id == rtg_info->task_block_id) { + pevent_read_number_field(rtg_info->block_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->block_ts_field, + pevent_read_number_field(rtg_info->block_ts_field, record->data, ts); ret = 1; dprintf(3, "Read task_block (%d) record for task %d\n", @@ -356,7 +359,7 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, * rt_graph_check_task_resume - check for litmus_task_resume record * Return 1 and @pid if the record matches */ -int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, +int rt_graph_check_task_resume(struct rt_graph_info *rtg_info, struct pevent *pevent, struct record *record, gint *pid, unsigned long long *ts) { @@ -365,23 +368,23 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, gint id; int ret = 0; - if (rtinfo->task_resume_id < 0) { + if (rtg_info->task_resume_id < 0) { event = pevent_find_event_by_name(pevent, "litmus", "litmus_task_resume"); if (!event) goto out; 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_ts_field = pevent_find_field(event, RT_TS_FIELD); + rtg_info->task_resume_id = event->id; + rtg_info->resume_pid_field = pevent_find_field(event, "pid"); + rtg_info->resume_ts_field = pevent_find_field(event, RT_TS_FIELD); } id = pevent_data_type(pevent, record); - if (id == rtinfo->task_resume_id) { - pevent_read_number_field(rtinfo->resume_pid_field, + if (id == rtg_info->task_resume_id) { + pevent_read_number_field(rtg_info->resume_pid_field, record->data, &val); *pid = val; - pevent_read_number_field(rtinfo->resume_ts_field, + pevent_read_number_field(rtg_info->resume_ts_field, record->data, ts); ret = 1; dprintf(3, "Read task_resume (%d) record for task %d\n", @@ -394,43 +397,45 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, /** * init_rt_event_cache - reset cached field values */ -void init_rt_event_cache(struct rt_graph_info *rtinfo) +void init_rt_event_cache(struct rt_graph_info *rtg_info) { dprintf(1, "Initializing RT event cache\n"); - rtinfo->task_param_id = -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; - rtinfo->task_resume_id = -1; - - rtinfo->param_pid_field = NULL; - rtinfo->param_wcet_field = NULL; - rtinfo->param_period_field = NULL; - - rtinfo->switch_to_pid_field = NULL; - rtinfo->switch_to_job_field = NULL; - rtinfo->switch_to_ts_field = NULL; - - rtinfo->switch_away_pid_field = NULL; - rtinfo->switch_away_job_field = NULL; - rtinfo->switch_away_ts_field = NULL; - - rtinfo->release_pid_field = NULL; - rtinfo->release_job_field = NULL; - rtinfo->release_release_field = NULL; - rtinfo->release_deadline_field = NULL; - - rtinfo->completion_pid_field = NULL; - rtinfo->completion_job_field = NULL; - rtinfo->completion_ts_field = NULL; - - rtinfo->block_pid_field = NULL; - rtinfo->block_ts_field = NULL; - - rtinfo->resume_pid_field = NULL; - rtinfo->resume_ts_field = NULL; + rtg_info->task_param_id = -1; + rtg_info->switch_to_id = -1; + rtg_info->switch_away_id = -1; + rtg_info->task_release_id = -1; + rtg_info->task_completion_id = -1; + rtg_info->task_block_id = -1; + rtg_info->task_resume_id = -1; + + rtg_info->max_period = 0; + + rtg_info->param_pid_field = NULL; + rtg_info->param_wcet_field = NULL; + rtg_info->param_period_field = NULL; + + rtg_info->switch_to_pid_field = NULL; + rtg_info->switch_to_job_field = NULL; + rtg_info->switch_to_ts_field = NULL; + + rtg_info->switch_away_pid_field = NULL; + rtg_info->switch_away_job_field = NULL; + rtg_info->switch_away_ts_field = NULL; + + rtg_info->release_pid_field = NULL; + rtg_info->release_job_field = NULL; + rtg_info->release_release_field = NULL; + rtg_info->release_deadline_field = NULL; + + rtg_info->completion_pid_field = NULL; + rtg_info->completion_job_field = NULL; + rtg_info->completion_ts_field = NULL; + + rtg_info->block_pid_field = NULL; + rtg_info->block_ts_field = NULL; + + rtg_info->resume_pid_field = NULL; + rtg_info->resume_ts_field = NULL; } /** @@ -445,7 +450,7 @@ get_rts(struct graph_info *ginfo, struct record *record) gint epid, eid; unsigned long long ts; if (!record->cached_rts) { - rt_graph_check_any(&ginfo->rtinfo, ginfo->pevent, record, + rt_graph_check_any(&ginfo->rtg_info, ginfo->pevent, record, &epid, &eid, &ts); record->cached_rts = ts; } else diff --git a/rt-graph.h b/rt-graph.h index 1a6ef0c..052f184 100644 --- a/rt-graph.h +++ b/rt-graph.h @@ -6,6 +6,8 @@ #include "trace-cmd.h" #include "rt-plot-task.h" +#define NO_CPU -1 + #define RT_TS_FIELD "__rt_ts" #define TS_HASH_SIZE 12 struct ts_list; @@ -54,6 +56,8 @@ struct rt_graph_info { /* Cache of ts fields for non-litmus events */ struct ts_list *events[TS_HASH_SIZE]; + + unsigned long long max_period; }; struct ts_list { diff --git a/rt-plot-task.c b/rt-plot-task.c index f28b7b1..9e8ffe7 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c @@ -2,8 +2,9 @@ #include "trace-filter.h" #define LLABEL 30 +#define SEARCH_PERIODS 3 -#define DEBUG_LEVEL 4 +#define DEBUG_LEVEL 3 #if DEBUG_LEVEL > 0 #define dprintf(l, x...) \ do { \ @@ -14,35 +15,87 @@ #define dprintf(l, x...) do { if (0) printf(x); } while (0) #endif +/* + * Return 1 if @record is relevant to @match_pid. + */ static gboolean record_matches_pid(struct graph_info *ginfo, struct record *record, int match_pid) { gint dint, pid = 0, match; unsigned long long dull; - struct rt_graph_info *rtg_info = &ginfo->rtinfo; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; /* Must use check_* in case record has not been found yet, - * this macro was the best of many terrible options + * this macro was the best of many terrible options. */ -#define MARGS rtg_info, ginfo->pevent, record, &pid - match = rt_graph_check_switch_to(MARGS, &dint, &dull) || - rt_graph_check_switch_away(MARGS, &dint, &dull) || - rt_graph_check_task_release(MARGS, &dint, &dull, &dull) || - rt_graph_check_task_completion(MARGS, &dint, &dull) || - rt_graph_check_task_block(MARGS, &dull) || - rt_graph_check_task_resume(MARGS, &dull) || - rt_graph_check_any(MARGS, &dint, &dull); -#undef MARGS +#define ARG rtg_info, ginfo->pevent, record, &pid + match = rt_graph_check_switch_to(ARG, &dint, &dull) || + rt_graph_check_switch_away(ARG, &dint, &dull) || + rt_graph_check_task_release(ARG, &dint, &dull, &dull) || + rt_graph_check_task_completion(ARG, &dint, &dull) || + rt_graph_check_task_block(ARG, &dull) || + rt_graph_check_task_resume(ARG, &dull) || + rt_graph_check_any(ARG, &dint, &dull); +#undef ARG return pid == match_pid; } +/* + * Return the first record after @time (within a range) which draws a box. + */ +static struct record* +next_box_record(struct graph_info *ginfo, struct rt_task_info *rtt_info, + unsigned long long time, int *out_eid) +{ + struct record *record = NULL, *ret = NULL; + struct pevent *pevent; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; + unsigned long long dull, max_ts; + int match, pid, eid, dint, cpu; + + *out_eid = 0; + pevent = ginfo->pevent; + max_ts = ginfo->view_end_time + + SEARCH_PERIODS * rtg_info->max_period; + set_cpus_to_rts(ginfo, time); + do { + free_record(record); + record = tracecmd_read_next_data(ginfo->handle, &cpu); + if (!record || get_rts(ginfo, record) > max_ts) { + free_record(record); + goto out; + } + + /* Sorry mother */ +#define ARG rtg_info, pevent, record, &pid + match = rt_graph_check_switch_to(ARG, &dint, &dull) || + rt_graph_check_switch_away(ARG, &dint, &dull) || + rt_graph_check_task_block(ARG, &dull) || + rt_graph_check_task_resume(ARG, &dull); +#undef ARG + eid = (match) ? pevent_data_type(pevent, record) : 0; + + if (eid && pid == rtt_info->pid) { + ret = record; + *out_eid = eid; + goto out; + } + } while (get_rts(ginfo, record) < max_ts); + out: + return ret; +} + +/* + * Return first relevant record after @time. + * @display: If set, only considers records which are plotted in some way + */ static struct record* __find_record(struct graph_info *ginfo, gint pid, guint64 time, int display) { int next_cpu, match, eid, is_sa = 0; struct record *record = NULL; - struct rt_graph_info *rtg_info = &ginfo->rtinfo; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; set_cpus_to_rts(ginfo, time); do { @@ -73,10 +126,11 @@ find_display_record(struct graph_info *ginfo, gint pid, guint64 time) } /* - * Update current job in @rtt_info, ensuring monotonic increase + * Update current job in @rtt_info, ensuring monotonic increase. */ static int update_job(struct rt_task_info *rtt_info, int job) { + rtt_info->fresh = FALSE; if (job < rtt_info->last_job) { printf("Inconsistent job state for %d:%d -> %d\n", rtt_info->pid, rtt_info->last_job, job); @@ -89,6 +143,115 @@ static int update_job(struct rt_task_info *rtt_info, int job) return 1; } + + +/* + * Find the information for the last release of @rtt_info on @cpu before @time. + * @min_ts: the minimum time stamp to parse + * + * Returns release record and @out_job, @out_release, and @out_deadline if a + * release was found after @mints matching @time. + */ +static struct record* +get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, + int cpu, + unsigned long long min_ts, unsigned long long time, + int *out_job, + unsigned long long *out_release, + unsigned long long *out_deadline) +{ + int pid, job, match; + unsigned long long release, deadline; + struct record *last_record, *record, *ret = NULL; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; + + last_record = tracecmd_peek_data(ginfo->handle, cpu); + *out_job = *out_release = *out_deadline = 0; + if (!last_record) + return NULL; + last_record->ref_count++; + + while ((record = tracecmd_read_prev(ginfo->handle, last_record))) { + if (record->ts < min_ts) { + free_record(record); + goto out; + } + match = rt_graph_check_task_release(rtg_info, ginfo->pevent, + record, &pid, &job, + &release, &deadline); + free_record(last_record); + last_record = record; + if (match && (pid == rtt_info->pid) && release <= time) { + ret = record; + last_record = NULL; + *out_job = job; + *out_release = release; + *out_deadline = deadline; + break; + } + }; + out: + free_record(last_record); + return ret; +} + +/* + * Return information for @time, returns @job, @release, @deadline, and @record. + * @job: Job number at this time + * @release: Job's release time + * @deadline: Job's deadline + * @record: Matching record + */ +static int get_time_info(struct graph_info *ginfo, + struct rt_task_info *rtt_info, + unsigned long long time, + int *out_job, + unsigned long long *out_release, + unsigned long long *out_deadline, + struct record **out_record) + +{ + int cpu, job; + unsigned long long release, deadline, min_ts; + struct record *record; + struct offset_cache *offsets; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; + + /* Seek CPUs to first record after this time */ + *out_job = *out_release = *out_deadline = 0; + *out_record = find_record(ginfo, rtt_info->pid, time); + if (!*out_record) + return 0; + + /* This is not necessarily correct for sporadic, but will do for now */ + if (time < rtt_info->first_rels[2]) { + job = (time >= rtt_info->first_rels[1]) ? 2 : 1; + *out_job = job; + *out_release = rtt_info->first_rels[job - 1]; + *out_deadline = rtt_info->first_rels[job]; + goto out; + } + + min_ts = time - SEARCH_PERIODS * rtg_info->max_period; + *out_job = *out_release = *out_deadline = 0; + + offsets = save_offsets(ginfo); + for (cpu = 0; cpu < ginfo->cpus; cpu++) { + record = get_previous_release(ginfo, rtt_info, cpu, min_ts, + time, &job, &release, &deadline); + if (record && record->ts > min_ts) { + *out_job = job; + *out_release = release; + *out_deadline = deadline; + min_ts = record->ts; + } + free_record(record); + } + restore_offsets(ginfo, offsets); + out: + return 1; +} + static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, struct record *record, struct plot_info *info) { @@ -99,7 +262,7 @@ static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, if (rtt_info->params_found) goto out; - match = rt_graph_check_task_param(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_task_param(&ginfo->rtg_info, ginfo->pevent, record, &pid, &wcet, &period); if (match && pid == rtt_info->pid) { update_job(rtt_info, 0); @@ -108,6 +271,8 @@ static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, rtt_info->params_found = TRUE; ret = 1; rtt_info->first_rels[0] = get_rts(ginfo, record); + dprintf(3, "Params for %d (%llu, %llu)\n on %d", + pid, wcet, period, record->cpu); } out: return ret; @@ -120,7 +285,7 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, int pid, job, match, ret = 0; unsigned long long release, deadline; - match = rt_graph_check_task_release(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_task_release(&ginfo->rtg_info, ginfo->pevent, record, &pid, &job, &release, &deadline); if (match && pid == rtt_info->pid) { @@ -136,6 +301,9 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, if (job <= 3) rtt_info->first_rels[job - 1] = release; + dprintf(3, "Release for %d:%d on %d, rel: %llu, dead: %llu\n", + pid, job, record->cpu, release, deadline); + ret = 1; } return ret; @@ -148,13 +316,15 @@ static int try_completion(struct graph_info *ginfo, int pid, job, match, ret = 0; unsigned long long ts; - match = rt_graph_check_task_completion(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_task_completion(&ginfo->rtg_info, ginfo->pevent, record, &pid, &job, &ts); if (match && pid == rtt_info->pid) { update_job(rtt_info, job); info->completion = TRUE; info->ctime = ts; info->clabel = rtt_info->label; + dprintf(3, "Completion for %d:%d on %d at %llu\n", + pid, job, record->cpu, ts); ret = 1; } return ret; @@ -166,10 +336,14 @@ static int try_block(struct graph_info *ginfo, struct rt_task_info *rtt_info, int pid, match, ret = 0; unsigned long long ts; - match = rt_graph_check_task_block(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_task_block(&ginfo->rtg_info, ginfo->pevent, record, &pid, &ts); if (match && pid == rtt_info->pid) { + rtt_info->fresh = FALSE; rtt_info->block_time = ts; + rtt_info->block_cpu = NO_CPU; + dprintf(3, "Resume for %d on %d at %llu\n", + pid, record->cpu, ts); ret = 1; } return ret; @@ -181,7 +355,7 @@ static int try_resume(struct graph_info *ginfo, struct rt_task_info *rtt_info, int pid, match, ret = 0; unsigned long long ts; - match = rt_graph_check_task_resume(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_task_resume(&ginfo->rtg_info, ginfo->pevent, record, &pid, &ts); if (match && pid == rtt_info->pid) { /* info->box = TRUE; */ @@ -190,22 +364,26 @@ static int try_resume(struct graph_info *ginfo, struct rt_task_info *rtt_info, /* info->bthin = TRUE; */ /* info->bstart = rtt_info->block_time; */ /* info->bend = ts; */ + rtt_info->fresh = FALSE; rtt_info->block_time = 0ULL; + rtt_info->block_cpu = NO_CPU; + dprintf(3, "Resume for %d on %d at %llu\n", + pid, record->cpu, ts); ret = 1; } return ret; } -static unsigned long long +static int try_switch_away(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; - match = rt_graph_check_switch_away(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_switch_away(&ginfo->rtg_info, ginfo->pevent, record, &pid, &job, &ts); if (match && pid == rtt_info->pid) { update_job(rtt_info, job); @@ -213,18 +391,19 @@ try_switch_away(struct graph_info *ginfo, struct rt_task_info *rtt_info, 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->pid, rtt_info->last_job, - rtt_info->run_time, ts, rtt_info->last_cpu); + rtt_info->run_time, ts, record->cpu); info->box = TRUE; - info->bcolor = hash_cpu(rtt_info->last_cpu); + info->bcolor = hash_cpu(record->cpu); info->bfill = TRUE; info->bstart = rtt_info->run_time; info->bend = ts; info->blabel = rtt_info->label; } - dprintf(3, "Switch away at %llu\n", ts); + dprintf(3, "Switch away for %d:%d on %d at %llu\n", + pid, job, record->cpu, ts); rtt_info->run_time = 0ULL; - rtt_info->last_cpu = -1; + rtt_info->run_cpu = NO_CPU; ret = 1; } @@ -237,18 +416,14 @@ static int try_switch_to(struct graph_info *ginfo, struct rt_task_info *rtt_info int job, pid, match, ret = 0; unsigned long long ts; - match = rt_graph_check_switch_to(&ginfo->rtinfo, ginfo->pevent, + match = rt_graph_check_switch_to(&ginfo->rtg_info, ginfo->pevent, record, &pid, &job, &ts); if (match && pid == rtt_info->pid) { update_job(rtt_info, job); - rtt_info->run_time = ts; - rtt_info->last_cpu = record->cpu; - - dprintf(3, "Switching to %d:%d at %llu on CPU %d\n", - rtt_info->pid, rtt_info->last_job, - ts, rtt_info->last_cpu); - + rtt_info->run_cpu = record->cpu; + dprintf(3, "Switch to for %d:%d on %d at %llu\n", + pid, job, record->cpu, ts); ret = 1; } return ret; @@ -261,12 +436,12 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, unsigned long long ts; pid = rtt_info->pid; - rt_graph_check_any(&ginfo->rtinfo, ginfo->pevent, record, + rt_graph_check_any(&ginfo->rtg_info, ginfo->pevent, record, &epid, &eid, &ts); my_pid = (pid == epid); - my_cpu = (rtt_info->run_time && record->cpu == rtt_info->last_cpu); - not_sa = (eid != ginfo->rtinfo.switch_away_id); + my_cpu = (rtt_info->run_time && record->cpu == rtt_info->run_cpu); + not_sa = (eid != ginfo->rtg_info.switch_away_id); if (not_sa && (my_pid || my_cpu)) { info->line = TRUE; info->lcolor = hash_pid(record->cpu); @@ -277,117 +452,42 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, return ret; } -/* - * Find the information for the last release of @rtt_info on @cpu before @time. - * @min_ts: the minimum time stamp to parse - * - * Returns release record and @out_job, @out_release, and @out_deadline if a - * release was found after @mints matching @time. - */ -static struct record* -get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, - int cpu, - unsigned long long min_ts, unsigned long long time, - int *out_job, - unsigned long long *out_release, - unsigned long long *out_deadline) -{ - int pid, job, match; - unsigned long long release, deadline; - struct record *last_record, *record, *ret = NULL; - struct rt_graph_info *rtg_info = &ginfo->rtinfo; - - last_record = tracecmd_peek_data(ginfo->handle, cpu); - *out_job = *out_release = *out_deadline = 0; - if (!last_record) - return NULL; - last_record->ref_count++; - - while ((record = tracecmd_read_prev(ginfo->handle, last_record))) { - if (record->ts < min_ts) { - free_record(record); - goto out; - } - match = rt_graph_check_task_release(rtg_info, ginfo->pevent, - record, &pid, &job, - &release, &deadline); - free_record(last_record); - last_record = record; - if (match && (pid == rtt_info->pid) && release <= time) { - ret = record; - last_record = NULL; - *out_job = job; - *out_release = release; - *out_deadline = deadline; - break; - } - }; - out: - free_record(last_record); - return ret; -} - -/* - * Return information for @time, returns @job, @release, @deadline, and @record. - * @job: Job number at this time - * @release: Job's release time - * @deadline: Job's deadline - * @record: Matching record - */ -static int get_time_info(struct graph_info *ginfo, - struct rt_task_info *rtt_info, - unsigned long long time, - int *out_job, - unsigned long long *out_release, - unsigned long long *out_deadline, - struct record **out_record) - +static void do_plot_end(struct graph_info *ginfo, struct rt_task_info *rtt_info, + struct plot_info *info) { - int cpu, job; - unsigned long long release, deadline, min_ts; struct record *record; - struct offset_cache *offsets; - - /* Seek CPUs to first record after this time */ - *out_job = *out_release = *out_deadline = 0; - *out_record = find_record(ginfo, rtt_info->pid, time); - if (!*out_record) - return 0; - - /* This is not necessarily correct for sporadic, but will do for now */ - if (time < rtt_info->first_rels[2]) { - job = (time >= rtt_info->first_rels[1]) ? 2 : 1; - *out_job = job; - *out_release = rtt_info->first_rels[job - 1]; - *out_deadline = rtt_info->first_rels[job]; - goto out; - } - - min_ts = time - 2*rtt_info->wcet; - *out_job = *out_release = *out_deadline = 0; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; + int eid; - offsets = save_offsets(ginfo); - for (cpu = 0; cpu < ginfo->cpus; cpu++) { - record = get_previous_release(ginfo, rtt_info, cpu, min_ts, - time, &job, &release, &deadline); - if (record && record->ts > min_ts) { - *out_job = job; - *out_release = release; - *out_deadline = deadline; - min_ts = record->ts; + if (rtt_info->run_time && rtt_info->run_cpu != NO_CPU) { + /* A box was started, finish it */ + info->box = TRUE; + info->bcolor = hash_cpu(rtt_info->run_cpu); + info->bfill = TRUE; + info->bstart = rtt_info->run_time; + info->bend = ginfo->view_end_time; + info->blabel = rtt_info->label; + } else if (rtt_info->block_time && rtt_info->block_cpu != NO_CPU) { + /* Blocking happened */ + } else if (rtt_info->fresh) { + /* Nothing happened!*/ + record = next_box_record(ginfo, rtt_info, + ginfo->view_end_time, &eid); + + if (record) { + if (eid == rtg_info->switch_away_id) { + /* In a run */ + info->box = TRUE; + info->bcolor = hash_cpu(record->cpu); + info->bfill = TRUE; + info->bstart = ginfo->view_start_time; + info->bend = ginfo->view_end_time; + } else if (eid == rtg_info->task_resume_id) { + /* In a block */ + } + free_record(record); } - free_record(record); } - restore_offsets(ginfo, offsets); - out: - return 1; -} - -static inline int in_res(struct graph_info *ginfo, unsigned long long time, - unsigned long target) -{ - return time > target - 2/ginfo->resolution && - time < target + 2/ginfo->resolution; } static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, @@ -396,15 +496,11 @@ static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, struct rt_task_info *rtt_info = plot->private; int match; + dprintf(4,"%s\n", __FUNCTION__); + /* No more records, finish what we started */ if (!record) { - if (rtt_info->last_cpu >= 0 && - rtt_info->run_time) { - info->box = TRUE; - info->bstart = rtt_info->last_time; - info->bend = ginfo->view_end_time; - info->bcolor = hash_cpu(rtt_info->last_cpu); - } + do_plot_end(ginfo, rtt_info, info); return 0; } @@ -417,11 +513,6 @@ static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, try_resume(ginfo, rtt_info, record, info) || try_other(ginfo, rtt_info, record, info); - if (match) { - rtt_info->last_time = get_rts(ginfo, record); - rtt_info->last_cpu = record->cpu; - } - return match; } @@ -431,22 +522,26 @@ static void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot int i; struct rt_task_info *rtt_info = plot->private; + dprintf(4,"%s\n", __FUNCTION__); + 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->run_time = time; + rtt_info->block_time = time; + rtt_info->run_cpu = NO_CPU; + rtt_info->block_cpu = NO_CPU; rtt_info->params_found = FALSE; + rtt_info->fresh = TRUE; for (i = 0; i < 3; i++) rtt_info->first_rels[i] = 0ULL; - update_job(rtt_info, 0); + rtt_info->last_job = 0; } static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) { struct rt_task_info *rtt_info = plot->private; - printf("Destroying plot %d\n", rtt_info->pid); + dprintf(4,"%s\n", __FUNCTION__); free(rtt_info->label); task_plot_destroy(ginfo, plot); } @@ -462,6 +557,8 @@ static int rt_task_plot_display_last_event(struct graph_info *ginfo, struct offset_cache *offsets; struct rt_task_info *rtt_info = plot->private; + dprintf(4,"%s\n", __FUNCTION__); + offsets = save_offsets(ginfo); record = find_display_record(ginfo, rtt_info->pid, time); restore_offsets(ginfo, offsets); @@ -481,10 +578,17 @@ static int rt_task_plot_display_last_event(struct graph_info *ginfo, return 1; } +static inline int in_res(struct graph_info *ginfo, unsigned long long time, + unsigned long target) +{ + return time > target - 2/ginfo->resolution && + time < target + 2/ginfo->resolution; +} + static int rt_task_plot_display_info(struct graph_info *ginfo, - struct graph_plot *plot, - struct trace_seq *s, - unsigned long long time) + struct graph_plot *plot, + struct trace_seq *s, + unsigned long long time) { const char *comm; int pid, job, eid; @@ -495,6 +599,8 @@ static int rt_task_plot_display_info(struct graph_info *ginfo, struct rt_task_info *rtt_info = plot->private; struct offset_cache *offsets; + dprintf(4,"%s\n", __FUNCTION__); + offsets = save_offsets(ginfo); get_time_info(ginfo, rtt_info, time, &job, &release, &deadline, &record); @@ -535,6 +641,8 @@ static int rt_task_plot_match_time(struct graph_info *ginfo, struct rt_task_info *rtt_info = plot->private; int next_cpu, match, ret; + dprintf(4,"%s\n", __FUNCTION__); + set_cpus_to_rts(ginfo, time); do { @@ -600,14 +708,14 @@ void rt_plot_task_plotted(struct graph_info *ginfo, gint **plotted) void rt_plot_task(struct graph_info *ginfo, int pid, int pos) { - struct rt_graph_info *rtinfo = &ginfo->rtinfo; + struct rt_graph_info *rtg_info = &ginfo->rtg_info; struct rt_task_info *rtt_info; struct graph_plot *plot; const char *comm; char *plot_label; int len; - if (!find_task_list(rtinfo->tasks, pid)) + if (!find_task_list(rtg_info->tasks, pid)) die("Cannot create RT plot of non-RT task %d!\n", pid); rtt_info = malloc_or_die(sizeof(*rtt_info)); diff --git a/rt-plot-task.h b/rt-plot-task.h index d3464e9..9f031e9 100644 --- a/rt-plot-task.h +++ b/rt-plot-task.h @@ -10,17 +10,18 @@ struct rt_task_info { /* For drawing squares */ unsigned long long run_time; + int run_cpu; unsigned long long block_time; + int block_cpu; /* For managing state */ int last_job; - int last_cpu; - unsigned long long last_time; /* Used to get around bugs(ish) */ unsigned long long first_rels[3]; gboolean params_found; + gboolean fresh; char *label; }; diff --git a/trace-graph.c b/trace-graph.c index 2cf7a95..f3a5916 100644 --- a/trace-graph.c +++ b/trace-graph.c @@ -119,7 +119,7 @@ static void init_event_cache(struct graph_info *ginfo) */ ginfo->read_comms = TRUE; - init_rt_event_cache(&ginfo->rtinfo); + init_rt_event_cache(&ginfo->rtg_info); } struct filter_task_item * @@ -1719,16 +1719,86 @@ static void draw_plot(struct graph_info *ginfo, struct graph_plot *plot, plot->p1, plot->p2, ginfo->draw_width, width_16, font); } +static void draw_nonrt_plots(struct graph_info *ginfo) +{ + gint cpu, pid; + struct record *record; + struct plot_hash *hash; + struct plot_list *list; + + tracecmd_set_all_cpus_to_timestamp(ginfo->handle, + ginfo->view_start_time); + while ((record = tracecmd_read_next_data(ginfo->handle, &cpu))) { + if (record->ts < ginfo->view_start_time) { + free_record(record); + continue; + } + if (record->ts > ginfo->view_end_time) { + free_record(record); + break; + } + hash = trace_graph_plot_find_cpu(ginfo, cpu); + if (hash) { + for (list = hash->plots; list; list = list->next) { + if (list->plot->type == PLOT_TYPE_RT_TASK) + continue; + draw_plot(ginfo, list->plot, record); + } + } + pid = pevent_data_pid(ginfo->pevent, record); + hash = trace_graph_plot_find_task(ginfo, pid); + if (hash) { + for (list = hash->plots; list; list = list->next) { + if (list->plot->type == PLOT_TYPE_RT_TASK) + continue; + draw_plot(ginfo, list->plot, record); + } + } + for (list = ginfo->all_recs; list; list = list->next) { + if (list->plot->type == PLOT_TYPE_RT_TASK) + continue; + draw_plot(ginfo, list->plot, record); + } + free_record(record); + } +} + +static void draw_rt_plots(struct graph_info *ginfo) +{ + gint cpu; + struct record *record; + struct plot_list *list; + + set_cpus_to_rts(ginfo, ginfo->view_start_time); + while ((record = tracecmd_read_next_data(ginfo->handle, &cpu))) { + if (get_rts(ginfo, record) < ginfo->view_start_time) { + free_record(record); + continue; + } + if (get_rts(ginfo, record) > ginfo->view_end_time) { + free_record(record); + break; + } + for (list = ginfo->all_recs; list; list = list->next) { + if (list->plot->type != PLOT_TYPE_RT_TASK) + continue; + draw_plot(ginfo, list->plot, record); + } + free_record(record); + } +} + static void draw_plots(struct graph_info *ginfo, gint new_width) { struct plot_list *list; struct graph_plot *plot; struct record *record; struct plot_hash *hash; - gint pid; gint cpu; gint i; + printf("----Drawing plots----\n"); + /* Initialize plots */ for (i = 0; i < ginfo->plots; i++) { plot = ginfo->plot_array[i]; @@ -1748,13 +1818,11 @@ static void draw_plots(struct graph_info *ginfo, gint new_width) set_color(ginfo->draw, plot->gc, plot->last_color); } - tracecmd_set_all_cpus_to_timestamp(ginfo->handle, - ginfo->view_start_time); - trace_set_cursor(GDK_WATCH); - /* Shortcut if we don't have any task plots */ if (!ginfo->nr_task_hash && !ginfo->all_recs) { + tracecmd_set_all_cpus_to_timestamp(ginfo->handle, + ginfo->view_start_time); for (cpu = 0; cpu < ginfo->cpus; cpu++) { hash = trace_graph_plot_find_cpu(ginfo, cpu); if (!hash) @@ -1777,30 +1845,8 @@ static void draw_plots(struct graph_info *ginfo, gint new_width) goto out; } - while ((record = tracecmd_read_next_data(ginfo->handle, &cpu))) { - if (record->ts < ginfo->view_start_time) { - free_record(record); - continue; - } - if (record->ts > ginfo->view_end_time) { - free_record(record); - break; - } - hash = trace_graph_plot_find_cpu(ginfo, cpu); - if (hash) { - for (list = hash->plots; list; list = list->next) - draw_plot(ginfo, list->plot, record); - } - pid = pevent_data_pid(ginfo->pevent, record); - hash = trace_graph_plot_find_task(ginfo, pid); - if (hash) { - for (list = hash->plots; list; list = list->next) - draw_plot(ginfo, list->plot, record); - } - for (list = ginfo->all_recs; list; list = list->next) - draw_plot(ginfo, list->plot, record); - free_record(record); - } + draw_nonrt_plots(ginfo); + draw_rt_plots(ginfo); out: for (i = 0; i < ginfo->plots; i++) { @@ -2376,6 +2422,7 @@ void trace_graph_refresh(struct graph_info *ginfo) ginfo->draw_height = PLOT_SPACE(ginfo->plots); gtk_widget_set_size_request(ginfo->draw, ginfo->draw_width, ginfo->draw_height); update_label_window(ginfo); + printf("----Redrawing graph----\n"); redraw_graph(ginfo); } diff --git a/trace-graph.h b/trace-graph.h index 1cb77b9..788c77d 100644 --- a/trace-graph.h +++ b/trace-graph.h @@ -246,7 +246,7 @@ struct graph_info { struct format_field *wakeup_new_pid_field; struct format_field *wakeup_new_success_field; - struct rt_graph_info rtinfo; + struct rt_graph_info rtg_info; gboolean read_comms; /* Read all comms on first load */ diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c index 00f07af..28baaa5 100644 --- a/trace-plot-cpu.c +++ b/trace-plot-cpu.c @@ -89,7 +89,7 @@ static int filter_record(struct graph_info *ginfo, /* Load real-time records */ - rt_graph_check_task_param(&ginfo->rtinfo, ginfo->pevent, record, + rt_graph_check_task_param(&ginfo->rtg_info, ginfo->pevent, record, &rpid, &wcet, &period); if (trace_graph_check_sched_switch(ginfo, record, sched_pid, &comm)) { -- cgit v1.2.2