From f69435260fd14ef8d9ba13774da0fcba4b5d212c Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 5 Mar 2012 00:50:01 -0500 Subject: Initial work generating event caches --- Makefile | 3 +- rt-graph.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rt-graph.h | 45 ++++++++++++ trace-graph.h | 3 + 4 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 rt-graph.c create mode 100644 rt-graph.h diff --git a/Makefile b/Makefile index edf3402..c97cab7 100644 --- a/Makefile +++ b/Makefile @@ -300,10 +300,11 @@ TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-lis trace-stack.o trace-options.o TRACE_VIEW_OBJS = trace-view.o trace-view-store.o TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o trace-plot-task.o +RT_GRAPH_OBJS = rt-graph.o TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS) TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) \ - trace-capture.o kernel-shark.o + $(RT_GRAPH_OBJS) trace-capture.o kernel-shark.o PEVENT_LIB_OBJS = parse-events.o trace-seq.o parse-filter.o parse-utils.o TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \ diff --git a/rt-graph.c b/rt-graph.c new file mode 100644 index 0000000..6eab52f --- /dev/null +++ b/rt-graph.c @@ -0,0 +1,216 @@ +#include "rt-graph.h" + +/** + * 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, + struct pevent *pevent, struct record *record, + gint *pid, unsigned long long *wcet, + unsigned long long *period) +{ + struct event_format *event; + unsigned long long val; + gint id; + int ret = 0; + + /* Attempt to update record cache. It can only be updated + * after the pevent has "seen" its first litmus_task_param + * event. + */ + if (rtinfo->task_param_id < 0) { + event = pevent_find_event_by_name(pevent, "litmus", + "litmus_task_param"); + if (!event) + return 0; + rtinfo->task_param_id = 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"); + } + + id = pevent_data_type(pevent, record); + if (id == rtinfo->task_param_id) { + pevent_read_number_field(rtinfo->param_pid_field, + record->data, &val); + *pid = val; + pevent_read_number_field(rtinfo->param_wcet_field, + record->data, wcet); + pevent_read_number_field(rtinfo->param_period_field, + record->data, period); + ret = 1; + } + + return ret; +} + +/** + * rt_graph_check_task_release - check for litmus_task_release record + * Return 1 and @pid, @job, and @deadline if the record matches + */ +int rt_graph_check_task_release(struct rt_graph_info *rtinfo, + struct pevent *pevent, struct record *record, + gint *pid, gint *job, + unsigned long long *deadline) +{ + struct event_format *event; + unsigned long long val; + gint id; + int ret = 0; + + if (rtinfo->task_release_id < 0) { + event = pevent_find_event_by_name(pevent, "litmus", + "litmus_task_release"); + if (!event) + return 0; + rtinfo->task_release_id = event->id; + rtinfo->release_pid_field = pevent_find_field(event, "pid"); + rtinfo->release_job_field = pevent_find_field(event, "job"); + rtinfo->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, + record->data, &val); + *pid = val; + pevent_read_number_field(rtinfo->release_job_field, + record->data, &val); + *job = val; + pevent_read_number_field(rtinfo->release_deadline_field, + record->data, deadline); + ret = 1; + } + + return ret; +} + +/** + * rt_graph_check_task_completion - check for litmus_task_completion record + * Return 1 and @pid, @job if the record matches + */ +int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, + struct pevent *pevent, struct record *record, + gint *pid, gint *job) +{ + struct event_format *event; + unsigned long long val; + gint id; + int ret = 0; + + if (rtinfo->task_param_id < 0) { + event = pevent_find_event_by_name(pevent, "litmus", + "litmus_task_completion"); + if (!event) + return 0; + rtinfo->task_completion_id = event->id; + rtinfo->completion_pid_field = pevent_find_field(event, "pid"); + rtinfo->completion_job_field = pevent_find_field(event, "job"); + } + + id = pevent_data_type(pevent, record); + if (id == rtinfo->task_completion_id) { + pevent_read_number_field(rtinfo->completion_pid_field, + record->data, &val); + *pid = val; + pevent_read_number_field(rtinfo->completion_job_field, + record->data, &val); + *job = val; + ret = 1; + } + + return ret; +} + +/** + * rt_graph_check_task_block - check for litmus_task_block record + * Return 1 and @pid if the record matches + */ +int rt_graph_check_task_block(struct rt_graph_info *rtinfo, + struct pevent *pevent, struct record *record, + gint *pid) +{ + struct event_format *event; + unsigned long long val; + gint id; + int ret = 0; + + if (rtinfo->task_block_id < 0) { + event = pevent_find_event_by_name(pevent, "litmus", + "litmus_task_block"); + if (!event) + return 0; + rtinfo->task_block_id = event->id; + rtinfo->block_pid_field = pevent_find_field(event, "pid"); + } + + id = pevent_data_type(pevent, record); + if (id == rtinfo->task_block_id) { + pevent_read_number_field(rtinfo->block_pid_field, + record->data, &val); + *pid = val; + ret = 1; + } + + return ret; +} + +/** + * rt_graph_check_task_release - check for litmus_task_release record + * Return 1 and @pid if the record matches + */ +int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, + struct pevent *pevent, struct record *record, + gint *pid) +{ + struct event_format *event; + unsigned long long val; + gint id; + int ret = 0; + + if (rtinfo->task_resume_id < 0) { + event = pevent_find_event_by_name(pevent, "litmus", + "litmus_task_resume"); + if (!event) + return 0; + rtinfo->task_resume_id = event->id; + rtinfo->resume_pid_field = pevent_find_field(event, "pid"); + } + + id = pevent_data_type(pevent, record); + if (id == rtinfo->task_resume_id) { + pevent_read_number_field(rtinfo->resume_pid_field, + record->data, &val); + *pid = val; + ret = 1; + } + + return ret; +} + +/** + * init_rt_event_cache - reset cached field values + */ +void init_rt_event_cache(struct rt_graph_info *rtinfo) +{ + print("hello"); + rtinfo->task_param_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->release_pid_field = NULL; + rtinfo->release_job_field = NULL; + rtinfo->release_deadline_field = NULL; + + rtinfo->completion_pid_field = NULL; + rtinfo->completion_job_field = NULL; + + rtinfo->block_pid_field = NULL; + rtinfo->resume_pid_field = NULL; +} diff --git a/rt-graph.h b/rt-graph.h new file mode 100644 index 0000000..0ea921a --- /dev/null +++ b/rt-graph.h @@ -0,0 +1,45 @@ +#ifndef _RT_GRAPH_H +#define _RT_GRAPH_H + +#include +#include "trace-cmd.h" + +struct rt_graph_info { + + /* Cache of event fields so that they don't need to be located + * during each access. + */ + gint task_param_id; + struct format_field *param_pid_field; + struct format_field *param_wcet_field; + struct format_field *param_period_field; + gint task_release_id; + struct format_field *release_pid_field; + struct format_field *release_job_field; + struct format_field *release_deadline_field; + gint task_completion_id; + struct format_field *completion_pid_field; + struct format_field *completion_job_field; + gint task_block_id; + struct format_field *block_pid_field; + gint task_resume_id; + struct format_field *resume_pid_field; + +}; + +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_release(struct rt_graph_info *rtinfo, struct pevent *pevent, + struct record *record, gint *pid, gint *job, + unsigned long long *deadline); +int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, struct pevent *pevent, + struct record *record, gint *pid, gint *job); +int rt_graph_check_task_block(struct rt_graph_info *rtinfo, struct pevent *pevent, + struct record *record, gint *pid); +int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, struct pevent *pevent, + struct record *record, gint *pid); +void init_rt_event_cache(struct rt_graph_info *rtinfo); + +#endif diff --git a/trace-graph.h b/trace-graph.h index 3344894..c3ae5a3 100644 --- a/trace-graph.h +++ b/trace-graph.h @@ -25,6 +25,7 @@ #include "trace-cmd.h" #include "trace-hash.h" #include "trace-xml.h" +#include "rt-graph.h" struct graph_info; @@ -229,6 +230,8 @@ struct graph_info { struct format_field *wakeup_new_pid_field; struct format_field *wakeup_new_success_field; + struct rt_graph_info rt_info; + gboolean read_comms; /* Read all comms on first load */ struct filter_task *task_filter; -- cgit v1.2.2