From 598026baa39b5672b77d46e70a1434f975d52486 Mon Sep 17 00:00:00 2001 From: pmf Date: Tue, 31 Jul 2007 19:46:13 +0000 Subject: [PATCH] start adding IRQ mode for cpu resource git-svn-id: http://ltt.polymtl.ca/svn@2559 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/lttv/lttv/state.c | 13 +- ltt/branches/poly/lttv/lttv/state.h | 3 +- .../lttv/modules/gui/resourceview/drawing.c | 37 +- .../lttv/modules/gui/resourceview/drawing.h | 6 +- .../modules/gui/resourceview/eventhooks.c | 417 +++++++++--------- 5 files changed, 241 insertions(+), 235 deletions(-) diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index ff388014..e12272a0 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -130,7 +130,8 @@ LttvProcessType LttvCPUMode LTTV_CPU_UNKNOWN, LTTV_CPU_IDLE, - LTTV_CPU_BUSY; + LTTV_CPU_BUSY, + LTTV_CPU_IRQ; static GQuark LTTV_STATE_TRACEFILES, @@ -1984,6 +1985,11 @@ static gboolean irq_entry(void *hook_data, void *call_data) /* Do something with the info about being in user or system mode when int? */ push_state(s, LTTV_STATE_IRQ, submode); + + /* update cpu status */ + s->cpu_state->previous_state = s->cpu_state->present_state; + s->cpu_state->present_state = LTTV_CPU_IRQ; + return FALSE; } @@ -2002,6 +2008,10 @@ static gboolean irq_exit(void *hook_data, void *call_data) LttvTracefileState *s = (LttvTracefileState *)call_data; pop_state(s, LTTV_STATE_IRQ); + + /* update cpu status */ + s->cpu_state->present_state = s->cpu_state->previous_state; + return FALSE; } @@ -3531,6 +3541,7 @@ static void module_init() LTTV_CPU_UNKNOWN = g_quark_from_string("unknown"); LTTV_CPU_IDLE = g_quark_from_string("idle"); LTTV_CPU_BUSY = g_quark_from_string("busy"); + LTTV_CPU_IRQ = g_quark_from_string("irq"); } static void module_destroy() diff --git a/ltt/branches/poly/lttv/lttv/state.h b/ltt/branches/poly/lttv/lttv/state.h index 50b13332..5f22b356 100644 --- a/ltt/branches/poly/lttv/lttv/state.h +++ b/ltt/branches/poly/lttv/lttv/state.h @@ -202,7 +202,8 @@ typedef GQuark LttvCPUMode; extern LttvCPUMode LTTV_CPU_UNKNOWN, LTTV_CPU_IDLE, - LTTV_CPU_BUSY; + LTTV_CPU_BUSY, + LTTV_CPU_IRQ; typedef struct _LttvExecutionState { LttvExecutionMode t; diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c index 927ef90a..30a6f8eb 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c @@ -86,9 +86,10 @@ GdkColor drawing_colors[NUM_COLORS] = GdkColor drawing_colors_cpu[NUM_COLORS_CPU] = { /* Pixel, R, G, B */ - { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_IDLE */ - { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_BUSY */ - { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_UNKNOWN */ + { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_CPU_UNKNOWN */ + { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_CPU_IDLE */ + { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_CPU_BUSY */ + { 0, 0xFFFF, 0x0000, 0x0000 }, /* COL_CPU_IRQ */ }; @@ -250,21 +251,21 @@ void drawing_data_request(Drawing_t *drawing, // &g_array_index(hooks, LttvTraceHook, before_hn++)); // if(ret) before_hn--; // -// ret = lttv_trace_find_hook(ts->parent.t, -// LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY, -// LTT_FIELD_IRQ_ID, 0, 0, -// before_execmode_hook, -// events_request, -// &g_array_index(hooks, LttvTraceHook, before_hn++)); -// if(ret) before_hn--; -// -// ret = lttv_trace_find_hook(ts->parent.t, -// LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT, -// 0, 0, 0, -// before_execmode_hook, -// events_request, -// &g_array_index(hooks, LttvTraceHook, before_hn++)); -// if(ret) before_hn--; + ret = lttv_trace_find_hook(ts->parent.t, + LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY, + LTT_FIELD_IRQ_ID, 0, 0, + before_execmode_hook, + events_request, + &g_array_index(hooks, LttvTraceHook, before_hn++)); + if(ret) before_hn--; + + ret = lttv_trace_find_hook(ts->parent.t, + LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT, + 0, 0, 0, + before_execmode_hook, + events_request, + &g_array_index(hooks, LttvTraceHook, before_hn++)); + if(ret) before_hn--; // // ret = lttv_trace_find_hook(ts->parent.t, // LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY, diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h index 98ad6445..b5c6f600 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h @@ -51,10 +51,12 @@ typedef enum _draw_color { NUM_COLORS } draw_color; typedef enum _draw_color_cpu { + COL_CPU_UNKNOWN, COL_CPU_IDLE, COL_CPU_BUSY, - COL_CPU_UNKNOWN, - NUM_COLORS_CPU } draw_color_cpu; + COL_CPU_IRQ, + NUM_COLORS_CPU +} draw_color_cpu; extern GdkColor drawing_colors[NUM_COLORS]; extern GdkColor drawing_colors_cpu[NUM_COLORS_CPU]; diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c index d8b1ea79..03ef6f0b 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c @@ -317,6 +317,18 @@ static inline PropertiesLine prepare_s_e_line(LttvProcessState *process) } +static void set_line_color_cpu(PropertiesLine *prop_line, GQuark present_state) +{ + if(present_state == LTTV_CPU_IDLE) { + prop_line->color = drawing_colors_cpu[COL_CPU_IDLE]; + } + else if(present_state == LTTV_CPU_BUSY) { + prop_line->color = drawing_colors_cpu[COL_CPU_BUSY]; + } + else if(present_state == LTTV_CPU_IRQ) { + prop_line->color = drawing_colors_cpu[COL_CPU_IRQ]; + } +} /* before_schedchange_hook * @@ -370,6 +382,8 @@ int before_schedchange_hook(void *hook_data, void *call_data) // return 0; // } + exit(0); + tfc->target_pid = pid_out; // if(!filter || !filter->head || // lttv_filter_tree_parse(filter->head,e,tfc->tf, @@ -527,14 +541,7 @@ int before_schedchange_hook(void *hook_data, void *call_data) prop_line.line_width = STATE_LINE_WIDTH; prop_line.style = GDK_LINE_SOLID; prop_line.y = MIDDLE; - //if(pid_out == 0) { - if(tfs->cpu_state->present_state == LTTV_CPU_IDLE) { - prop_line.color = drawing_colors_cpu[COL_CPU_IDLE]; - } - else { - prop_line.color = drawing_colors_cpu[COL_CPU_BUSY]; - } - + cpu_set_line_color(&prop_line, tfs->cpu_state->present_state); draw_line((void*)&prop_line, (void*)&draw_context); } @@ -892,197 +899,195 @@ int after_schedchange_hook(void *hook_data, void *call_data) * process. */ -//int before_execmode_hook(void *hook_data, void *call_data) -//{ -// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; -// EventsRequest *events_request = (EventsRequest*)thf->hook_data; -// ControlFlowData *control_flow_data = events_request->viewer_data; -// -// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; -// -// LttvTracefileState *tfs = (LttvTracefileState *)call_data; -// -// LttvTraceState *ts = (LttvTraceState *)tfc->t_context; -// -// LttEvent *e; -// e = ltt_tracefile_get_event(tfc->tf); -// -// LttvFilter *filter = control_flow_data->filter; -// if(filter != NULL && filter->head != NULL) -// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, -// tfc->t_context->t,tfc,NULL,NULL)) -// return FALSE; -// -// LttTime evtime = ltt_event_time(e); -// -// /* we are in a execmode, before the state update. We must draw the -// * items corresponding to the state before it changes : now is the right -// * time to do it. -// */ -// /* For the pid */ -// //LttvProcessState *process = tfs->process; -// guint cpu = tfs->cpu; -// guint trace_num = ts->parent.index; -// LttvProcessState *process = ts->running_process[cpu]; -// g_assert(process != NULL); -// +int before_execmode_hook(void *hook_data, void *call_data) +{ + LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; + EventsRequest *events_request = (EventsRequest*)thf->hook_data; + ControlFlowData *control_flow_data = events_request->viewer_data; + + LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; + + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)tfc->t_context; + + LttEvent *e; + e = ltt_tracefile_get_event(tfc->tf); + + LttTime evtime = ltt_event_time(e); + + GQuark cpuq; + + /* we are in a execmode, before the state update. We must draw the + * items corresponding to the state before it changes : now is the right + * time to do it. + */ + /* For the pid */ + //LttvProcessState *process = tfs->process; + guint cpu = tfs->cpu; + { + gchar *cpustr; + cpustr = g_strdup_printf("CPU%u", cpu); + cpuq = g_quark_from_string(cpustr); + g_free(cpustr); + } + guint trace_num = ts->parent.index; + LttvProcessState *process = ts->running_process[cpu]; + g_assert(process != NULL); + // guint pid = process->pid; -// -// /* Well, the process_out existed : we must get it in the process hash -// * or add it, and draw its items. -// */ -// /* Add process to process list (if not present) */ -// guint pl_height = 0; -// HashedResourceData *hashed_process_data = NULL; -// ProcessList *process_list = control_flow_data->process_list; -// LttTime birth = process->creation_time; -// -// if(likely(process_list->current_hash_data[trace_num][cpu] != NULL)) { -// hashed_process_data = process_list->current_hash_data[trace_num][cpu]; -// } else { -// hashed_process_data = processlist_get_process_data(process_list, "CPU0"); -//// hashed_process_data = processlist_get_process_data(process_list, -//// pid, -//// process->cpu, -//// &birth, -//// trace_num); -// if(unlikely(hashed_process_data == NULL)) -// { -// g_assert(pid == 0 || pid != process->ppid); -// ResourceInfo *process_info; -// /* Process not present */ -// Drawing_t *drawing = control_flow_data->drawing; -// processlist_add(process_list, -// drawing, -// pid, -// process->tgid, -// process->cpu, -// process->ppid, -// &birth, -// trace_num, -// process->name, -// process->brand, -// &pl_height, -// &process_info, -// &hashed_process_data); -// gtk_widget_set_size_request(drawing->drawing_area, -// -1, -// pl_height); -// gtk_widget_queue_draw(drawing->drawing_area); -// } -// /* Set the current process */ -// process_list->current_hash_data[trace_num][process->cpu] = -// hashed_process_data; -// } -// -// /* Now, the process is in the state hash and our own process hash. -// * We definitely can draw the items related to the ending state. -// */ -// -// if(likely(ltt_time_compare(hashed_process_data->next_good_time, -// evtime) > 0)) -// { -// if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { -// TimeWindow time_window = -// lttvwindow_get_time_window(control_flow_data->tab); -// -//#ifdef EXTRA_CHECK -// if(ltt_time_compare(evtime, time_window.start_time) == -1 -// || ltt_time_compare(evtime, time_window.end_time) == 1) -// return; -//#endif //EXTRA_CHECK -// Drawing_t *drawing = control_flow_data->drawing; -// guint width = drawing->width; -// guint x; -// convert_time_to_pixels( -// time_window, -// evtime, -// width, -// &x); -// -// /* Draw collision indicator */ -// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); -// gdk_draw_point(hashed_process_data->pixmap, -// drawing->gc, -// x, -// COLLISION_POSITION(hashed_process_data->height)); -// hashed_process_data->x.middle_marked = TRUE; -// } -// } else { -// TimeWindow time_window = -// lttvwindow_get_time_window(control_flow_data->tab); -// -//#ifdef EXTRA_CHECK -// if(ltt_time_compare(evtime, time_window.start_time) == -1 -// || ltt_time_compare(evtime, time_window.end_time) == 1) -// return; -//#endif //EXTRA_CHECK -// Drawing_t *drawing = control_flow_data->drawing; -// guint width = drawing->width; -// guint x; -// -// convert_time_to_pixels( -// time_window, -// evtime, -// width, -// &x); -// -// -// /* Jump over draw if we are at the same x position */ -// if(unlikely(x == hashed_process_data->x.middle && -// hashed_process_data->x.middle_used)) -// { -// if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { -// /* Draw collision indicator */ -// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); -// gdk_draw_point(hashed_process_data->pixmap, -// drawing->gc, -// x, -// COLLISION_POSITION(hashed_process_data->height)); -// hashed_process_data->x.middle_marked = TRUE; -// } -// /* jump */ -// } else { -// -// DrawContext draw_context; -// /* Now create the drawing context that will be used to draw -// * items related to the last state. */ -// draw_context.drawable = hashed_process_data->pixmap; -// draw_context.gc = drawing->gc; -// draw_context.pango_layout = drawing->pango_layout; -// draw_context.drawinfo.start.x = hashed_process_data->x.middle; -// draw_context.drawinfo.end.x = x; -// -// draw_context.drawinfo.y.over = 1; -// draw_context.drawinfo.y.middle = (hashed_process_data->height/2); -// draw_context.drawinfo.y.under = hashed_process_data->height; -// -// draw_context.drawinfo.start.offset.over = 0; -// draw_context.drawinfo.start.offset.middle = 0; -// draw_context.drawinfo.start.offset.under = 0; -// draw_context.drawinfo.end.offset.over = 0; -// draw_context.drawinfo.end.offset.middle = 0; -// draw_context.drawinfo.end.offset.under = 0; -// -// { -// /* Draw the line */ -// PropertiesLine prop_line = prepare_s_e_line(process); -// draw_line((void*)&prop_line, (void*)&draw_context); -// -// } -// /* become the last x position */ -// hashed_process_data->x.middle = x; -// hashed_process_data->x.middle_used = TRUE; -// hashed_process_data->x.middle_marked = FALSE; -// -// /* Calculate the next good time */ -// convert_pixels_to_time(width, x+1, time_window, -// &hashed_process_data->next_good_time); -// } -// } -// -// return 0; -//} + + /* Well, the process_out existed : we must get it in the process hash + * or add it, and draw its items. + */ + /* Add process to process list (if not present) */ + guint pl_height = 0; + HashedResourceData *hashed_process_data = NULL; + ProcessList *process_list = control_flow_data->process_list; + LttTime birth = process->creation_time; + + if(likely(process_list->current_hash_data[trace_num][cpu] != NULL)) { + hashed_process_data = process_list->current_hash_data[trace_num][cpu]; + } else { + hashed_process_data = processlist_get_process_data(process_list, cpuq, trace_num); +// hashed_process_data = processlist_get_process_data(process_list, +// pid, +// process->cpu, +// &birth, +// trace_num); + if(unlikely(hashed_process_data == NULL)) + { + //g_assert(pid == 0 || pid != process->ppid); + ResourceInfo *process_info; + /* Process not present */ + Drawing_t *drawing = control_flow_data->drawing; + ressourcelist_add(process_list, + drawing, + trace_num, + cpuq, //process->name, + 0, //cpu + cpu, + &pl_height, + &process_info, + &hashed_process_data); + gtk_widget_set_size_request(drawing->drawing_area, + -1, + pl_height); + gtk_widget_queue_draw(drawing->drawing_area); + } + /* Set the current process */ + process_list->current_hash_data[trace_num][process->cpu] = + hashed_process_data; + } + + /* Now, the process is in the state hash and our own process hash. + * We definitely can draw the items related to the ending state. + */ + + if(likely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) > 0)) + { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { + TimeWindow time_window = + lttvwindow_get_time_window(control_flow_data->tab); + +#ifdef EXTRA_CHECK + if(ltt_time_compare(evtime, time_window.start_time) == -1 + || ltt_time_compare(evtime, time_window.end_time) == 1) + return; +#endif //EXTRA_CHECK + Drawing_t *drawing = control_flow_data->drawing; + guint width = drawing->width; + guint x; + convert_time_to_pixels( + time_window, + evtime, + width, + &x); + + /* Draw collision indicator */ + gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); + gdk_draw_point(hashed_process_data->pixmap, + drawing->gc, + x, + COLLISION_POSITION(hashed_process_data->height)); + hashed_process_data->x.middle_marked = TRUE; + } + } else { + TimeWindow time_window = + lttvwindow_get_time_window(control_flow_data->tab); + +#ifdef EXTRA_CHECK + if(ltt_time_compare(evtime, time_window.start_time) == -1 + || ltt_time_compare(evtime, time_window.end_time) == 1) + return; +#endif //EXTRA_CHECK + Drawing_t *drawing = control_flow_data->drawing; + guint width = drawing->width; + guint x; + + convert_time_to_pixels( + time_window, + evtime, + width, + &x); + + + /* Jump over draw if we are at the same x position */ + if(unlikely(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used)) + { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { + /* Draw collision indicator */ + gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); + gdk_draw_point(hashed_process_data->pixmap, + drawing->gc, + x, + COLLISION_POSITION(hashed_process_data->height)); + hashed_process_data->x.middle_marked = TRUE; + } + /* jump */ + } else { + + DrawContext draw_context; + /* Now create the drawing context that will be used to draw + * items related to the last state. */ + draw_context.drawable = hashed_process_data->pixmap; + draw_context.gc = drawing->gc; + draw_context.pango_layout = drawing->pango_layout; + draw_context.drawinfo.start.x = hashed_process_data->x.middle; + draw_context.drawinfo.end.x = x; + + draw_context.drawinfo.y.over = 1; + draw_context.drawinfo.y.middle = (hashed_process_data->height/2); + draw_context.drawinfo.y.under = hashed_process_data->height; + + draw_context.drawinfo.start.offset.over = 0; + draw_context.drawinfo.start.offset.middle = 0; + draw_context.drawinfo.start.offset.under = 0; + draw_context.drawinfo.end.offset.over = 0; + draw_context.drawinfo.end.offset.middle = 0; + draw_context.drawinfo.end.offset.under = 0; + + { + /* Draw the line */ + PropertiesLine prop_line; + cpu_set_line_color(&prop_line, tfs->cpu_state->present_state); + printf("current state: %s\n", g_quark_to_string(tfs->cpu_state->present_state)); + draw_line((void*)&prop_line, (void*)&draw_context); + } + /* become the last x position */ + hashed_process_data->x.middle = x; + hashed_process_data->x.middle_used = TRUE; + hashed_process_data->x.middle_marked = FALSE; + + /* Calculate the next good time */ + convert_pixels_to_time(width, x+1, time_window, + &hashed_process_data->next_good_time); + } + } + + return 0; +} /* before_process_exit_hook * @@ -2558,25 +2563,11 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) draw_context.drawinfo.start.x = hashed_process_data->x.middle; /* Draw the line */ if(dodraw) { -// PropertiesLine prop_line = prepare_s_e_line(process); PropertiesLine prop_line; prop_line.line_width = STATE_LINE_WIDTH; prop_line.style = GDK_LINE_SOLID; prop_line.y = MIDDLE; -/* if(pid_out == 0) { - prop_line.color = drawing_colors_cpu[COL_IDLE]; - } - else { - prop_line.color = drawing_colors_cpu[COL_BUSY]; - } -*/ - //prop_line.color = drawing_colors_cpu[COL_CPU_UNKNOWN]; - if(ts->cpu_states[process_info->id].present_state == LTTV_CPU_IDLE) { - prop_line.color = drawing_colors_cpu[COL_CPU_IDLE]; - } - else { - prop_line.color = drawing_colors_cpu[COL_CPU_BUSY]; - } + cpu_set_line_color(&prop_line, ts->cpu_states[process_info->id].present_state); draw_line((void*)&prop_line, (void*)&draw_context); } -- 2.34.1