From 15bbd1e788af29d06b3fb64cefd0e2e3cdd64a8b Mon Sep 17 00:00:00 2001 From: Jonathan Herman Date: Thu, 23 Aug 2012 15:09:39 -0400 Subject: Add -c option to ignore records before system release. --- kernel-shark.c | 8 ++++++- rt-graph.c | 42 +++++++++++++++++++++++++++++++++++ rt-graph.h | 9 +++++++- trace-graph.c | 69 +++++++++++++++++++++++++++++----------------------------- 4 files changed, 91 insertions(+), 37 deletions(-) diff --git a/kernel-shark.c b/kernel-shark.c index 924bcc8..d921040 100644 --- a/kernel-shark.c +++ b/kernel-shark.c @@ -65,6 +65,7 @@ void usage(char *prog) printf(" -h Display this help message\n"); printf(" -v Display version and exit\n"); printf(" -i input_file, default is %s\n", default_input_file); + printf(" -c Ignore records before system release\n"); } static gboolean display_warnings; @@ -1826,13 +1827,15 @@ void kernel_shark(int argc, char **argv) GtkWidget *statusbar; int ret; int c; + int clean; g_thread_init(NULL); gdk_threads_init(); gtk_init(&argc, &argv); - while ((c = getopt(argc, argv, "hvi:")) != -1) { + clean = 0; + while ((c = getopt(argc, argv, "hcvi:")) != -1) { switch(c) { case 'h': usage(basename(argv[0])); @@ -1845,6 +1848,8 @@ void kernel_shark(int argc, char **argv) case 'i': input_file = optarg; break; + case 'c': + clean = 1; default: /* assume the other options are for gtk */ break; @@ -2396,6 +2401,7 @@ void kernel_shark(int argc, char **argv) info->graph_cbs.filter = ks_graph_filter; info->ginfo = trace_graph_create_with_callbacks(handle, &info->graph_cbs); + info->ginfo->rtg_info.clean_records = clean; widget = trace_graph_get_window(info->ginfo); gtk_paned_add1(GTK_PANED(vpaned), widget); gtk_widget_show(widget); diff --git a/rt-graph.c b/rt-graph.c index 74a6aab..d9a3f82 100644 --- a/rt-graph.c +++ b/rt-graph.c @@ -523,6 +523,43 @@ int rt_graph_check_task_resume(struct graph_info *ginfo, return ret; } + +/** + * rt_graph_check_sys_release - check for system release record + * Return 1 and @when if the record matches + */ +int rt_graph_check_sys_release(struct graph_info *ginfo, + struct record *record, + unsigned long long *rel) +{ + struct rt_graph_info *rtg_info = &ginfo->rtg_info; + struct pevent *pevent = ginfo->pevent; + struct event_format *event; + gint id; + int ret = 0; + + if (rtg_info->sys_release_id < 0) { + event = pevent_find_event_by_name(pevent, "litmus", + "litmus_sys_release"); + if (!event) + goto out; + rtg_info->sys_release_id = event->id; + dprintf(2, "Found sys_release id %d\n", event->id); + STORE_FIELD(rtg_info, event, sys_release, rel); + } + + id = pevent_data_type(pevent, record); + if (id == rtg_info->sys_release_id) { + LOAD_LONG(rtg_info, record, sys_release, rel, rel); + + ret = 1; + dprintf(3, "Read sys_release (%d) record, rel: %llu\n", id, *rel); + } + out: + return ret; +} + + /** * rt_graph_check_container_param - check for litmus_container_param record * Return 1, @cid, and @name if the record matches @@ -876,6 +913,9 @@ void init_rt_event_cache(struct rt_graph_info *rtg_info) memset(rtg_info, 0, sizeof(*rtg_info)); + rtg_info->clean_records = 0; + rtg_info->start_time = 0ULL; + rtg_info->task_param_id = -1; rtg_info->switch_to_id = -1; rtg_info->switch_away_id = -1; @@ -884,7 +924,9 @@ void init_rt_event_cache(struct rt_graph_info *rtg_info) rtg_info->task_block_id = -1; rtg_info->task_resume_id = -1; + rtg_info->sys_release_id = -1; rtg_info->container_param_id = -1; + rtg_info->server_param_id = -1; rtg_info->server_switch_to_id = -1; rtg_info->server_switch_away_id = -1; diff --git a/rt-graph.h b/rt-graph.h index 853ffc6..2b77c6e 100644 --- a/rt-graph.h +++ b/rt-graph.h @@ -21,6 +21,9 @@ struct ts_list; struct vcpu_list; struct rt_graph_info { + /* For ignoring records before system release */ + gboolean clean_records; + long long start_time; /* List of all real-time tasks */ struct task_list *tasks[TASK_HASH_SIZE]; @@ -62,6 +65,9 @@ struct rt_graph_info { struct format_field *resume_pid_field; struct format_field *resume_lid_field; + gint sys_release_id; + struct format_field *sys_release_rel_field; + gint container_param_id; struct format_field *cparam_cid_field; struct format_field *cparam_name_field; @@ -102,7 +108,6 @@ struct rt_graph_info { struct format_field *sresume_sid_field; struct format_field *sresume_lid_field; - /* Cache of ts fields for non-litmus events */ struct ts_list *events[TS_HASH_SIZE]; @@ -202,6 +207,8 @@ int rt_graph_check_server_block(struct graph_info *ginfo, unsigned long long *when); int rt_graph_check_server_resume(struct graph_info *ginfo, struct record *record, gint *pid, gint *lid, unsigned long long *when); +int rt_graph_check_sys_release(struct graph_info *ginfo, struct record *record, + unsigned long long *when); void init_rt_event_cache(struct rt_graph_info *rtinfo); unsigned long long get_rts(struct graph_info *ginfo, diff --git a/trace-graph.c b/trace-graph.c index c0f88c9..f9bd4af 100644 --- a/trace-graph.c +++ b/trace-graph.c @@ -1859,30 +1859,57 @@ 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_hashed_plots(struct graph_info *ginfo) { gint cpu, pid; + gboolean started; struct record *record; struct plot_hash *hash; struct plot_list *list; + set_cpus_to_rts(ginfo, ginfo->view_start_time); - 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) { + if (get_rts(ginfo, record) < ginfo->view_start_time) { free_record(record); continue; } - if (record->ts > ginfo->view_end_time) { + if (get_rts(ginfo, record) > ginfo->view_end_time) { free_record(record); break; } + + // TODO: hack to clean up until first release, make unhacky + if (ginfo->rtg_info.clean_records && + ginfo->rtg_info.start_time == 0) { + unsigned long long dull, rel = 0; + char *dchar; + int dint; + + // These methods add to the lists of tasks / containers + // in the system whenever a new param record is found. + // Skipping these records would be very bad, so parse + // them here if we are cleaning. Otherwise, draw_plot + // will take care of this +#define ARG ginfo,record, &pid + rt_graph_check_task_param(ARG, &dull, &dull); + rt_graph_check_container_param(ARG, &dchar); + rt_graph_check_server_param(ARG, &dint, &dull, &dull); +#undef ARG + if (rt_graph_check_sys_release(ginfo, record, &rel)) { + dull = rel - .1 * (ginfo->view_end_time - rel);; + ginfo->rtg_info.start_time = dull; + ginfo->view_start_time = dull; + } + + free_record(record); + continue; + } + hash = trace_graph_plot_find_cpu(ginfo, cpu); if (hash) { for (list = hash->plots; list; list = list->next) { - /* if (list->plot->time != TIME_TYPE_FT) */ - /* continue; */ draw_plot(ginfo, list->plot, record); } } @@ -1890,14 +1917,10 @@ static void draw_hashed_plots(struct graph_info *ginfo) hash = trace_graph_plot_find_task(ginfo, pid); if (hash) { for (list = hash->plots; list; list = list->next) { - /* if (list->plot->time != TIME_TYPE_FT) */ - /* continue; */ draw_plot(ginfo, list->plot, record); } } for (list = ginfo->all_recs; list; list = list->next) { - /* if (list->plot->time != TIME_TYPE_FT) */ - /* continue; */ // TODO: hacky assumption that everything else can be // reached via previous hashes // Should be an additional hashed list where things are @@ -1912,30 +1935,6 @@ static void draw_hashed_plots(struct graph_info *ginfo) } } -/* 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->time != TIME_TYPE_RT) */ -/* continue; */ -/* draw_plot(ginfo, list->plot, record); */ -/* } */ -/* free_record(record); */ -/* } */ -/* } */ static void draw_plots(struct graph_info *ginfo, gint new_width) { @@ -2341,7 +2340,7 @@ configure_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) gtk_widget_set_size_request(widget, ginfo->draw_width, ginfo->draw_height); // TODO: don't do this, compare widget to figure out if we should redraw - if (tries != 1 && tries != 2) + if (tries != 2) redraw_pixmap_backend(ginfo); ++tries; -- cgit v1.2.2