From 8743690d339401db862834d50f9b6bbd1268271f Mon Sep 17 00:00:00 2001 From: pmf Date: Tue, 31 Jul 2007 19:46:13 +0000 Subject: [PATCH] make first working version of irq resource drawing needs more work git-svn-id: http://ltt.polymtl.ca/svn@2562 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/lttv/lttv/state.c | 5 + ltt/branches/poly/lttv/lttv/state.h | 1 + .../lttv/modules/gui/resourceview/drawing.c | 9 +- .../lttv/modules/gui/resourceview/drawing.h | 8 + .../modules/gui/resourceview/eventhooks.c | 241 +++++++++++++++++- .../modules/gui/resourceview/processlist.h | 11 +- 6 files changed, 266 insertions(+), 9 deletions(-) diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index 4ef1e641..823bbe78 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -2059,6 +2059,7 @@ static gboolean irq_entry(void *hook_data, void *call_data) cpu_push_mode(s->cpu_state, LTTV_CPU_IRQ); /* update irq status */ + s->cpu_state->last_irq = irq; irq_push_mode(&ts->irq_states[irq], LTTV_IRQ_BUSY); return FALSE; @@ -2077,12 +2078,16 @@ static gboolean soft_irq_exit(void *hook_data, void *call_data) static gboolean irq_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; pop_state(s, LTTV_STATE_IRQ); /* update cpu status */ cpu_pop_mode(s->cpu_state); + /* update irq status */ + irq_pop_mode(&ts->irq_states[s->cpu_state->last_irq]); + return FALSE; } diff --git a/ltt/branches/poly/lttv/lttv/state.h b/ltt/branches/poly/lttv/lttv/state.h index eef1c7a5..be2e0b1c 100644 --- a/ltt/branches/poly/lttv/lttv/state.h +++ b/ltt/branches/poly/lttv/lttv/state.h @@ -293,6 +293,7 @@ GType lttv_traceset_state_get_type (void); typedef struct _LttvCPUState { GArray *mode_stack; + guint last_irq; } LttvCPUState; typedef struct _LttvIRQState { diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c index 251ccaca..ab9de32c 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c @@ -93,6 +93,12 @@ GdkColor drawing_colors_cpu[NUM_COLORS_CPU] = { 0, 0xFF00, 0xFF00, 0x0100 }, /* COL_CPU_TRAP */ }; +GdkColor drawing_colors_irq[NUM_COLORS_IRQ] = +{ /* Pixel, R, G, B */ + { 0, 0x0000, 0x0000, 0x0000 }, /* COL_IRQ_UNKNOWN */ + { 0, 0xBBBB, 0xBBBB, 0xBBBB }, /* COL_IRQ_IDLE */ + { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_IRQ_BUSY */ +}; /***************************************************************************** * drawing functions * @@ -1126,8 +1132,7 @@ void drawing_destroy(Drawing_t *drawing) gdk_colormap_free_colors(colormap, drawing_colors, NUM_COLORS); gdk_colormap_free_colors(colormap, drawing_colors_cpu, NUM_COLORS_CPU); - - + gdk_colormap_free_colors(colormap, drawing_colors_irq, NUM_COLORS_IRQ); // Do not unref here, Drawing_t destroyed by it's widget. //g_object_unref( G_OBJECT(drawing->drawing_area)); diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h index 1c468327..6928f8dd 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.h @@ -59,8 +59,16 @@ typedef enum _draw_color_cpu { NUM_COLORS_CPU } draw_color_cpu; +typedef enum _draw_color_irq { + COL_IRQ_UNKNOWN, + COL_IRQ_IDLE, + COL_IRQ_BUSY, + NUM_COLORS_IRQ +} draw_color_irq; + extern GdkColor drawing_colors[NUM_COLORS]; extern GdkColor drawing_colors_cpu[NUM_COLORS_CPU]; +extern GdkColor drawing_colors_irq[NUM_COLORS_IRQ]; /* This part of the viewer does : * Draw horizontal lines, getting graphic context as arg. diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c index d4040a5f..892a9ba8 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c @@ -338,6 +338,21 @@ static void cpu_set_line_color(PropertiesLine *prop_line, LttvCPUState *s) } } +static void irq_set_line_color(PropertiesLine *prop_line, LttvIRQState *s) +{ + GQuark present_state = ((GQuark*)s->mode_stack->data)[s->mode_stack->len-1]; + + if(present_state == LTTV_IRQ_UNKNOWN) { + prop_line->color = drawing_colors_irq[COL_IRQ_UNKNOWN]; + } + else if(present_state == LTTV_IRQ_IDLE) { + prop_line->color = drawing_colors_irq[COL_IRQ_IDLE]; + } + else if(present_state == LTTV_IRQ_BUSY) { + prop_line->color = drawing_colors_irq[COL_IRQ_BUSY]; + } +} + /* before_schedchange_hook * * This function basically draw lines and icons. Two types of lines are drawn : @@ -357,6 +372,14 @@ static void cpu_set_line_color(PropertiesLine *prop_line, LttvCPUState *s) int before_schedchange_hook(void *hook_data, void *call_data) +{ + before_schedchange_hook_cpu(hook_data, call_data); +// before_schedchange_hook_irq(hook_data, call_data); + + return 0; +} + +int before_schedchange_hook_cpu(void *hook_data, void *call_data) { LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; EventsRequest *events_request = (EventsRequest*)thf->hook_data; @@ -923,6 +946,8 @@ int before_execmode_hook(void *hook_data, void *call_data) GQuark cpuq; + before_execmode_hook_irq(hook_data, call_data); + /* 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. @@ -1099,6 +1124,217 @@ int before_execmode_hook(void *hook_data, void *call_data) return 0; } +int before_execmode_hook_irq(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 resourceq; + + /* 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 */ + + guint64 irq; + guint cpu = tfs->cpu; + + LttFacility *ev_facility = ltt_event_facility(e); + if(ltt_facility_name(ev_facility) != LTT_FACILITY_KERNEL) + return 0; + guint8 ev_id_entry = ltt_eventtype_id(ltt_facility_eventtype_get_by_name(ev_facility, LTT_EVENT_IRQ_ENTRY)); + guint8 ev_id_exit = ltt_eventtype_id(ltt_facility_eventtype_get_by_name(ev_facility, LTT_EVENT_IRQ_EXIT)); + if(ltt_facility_name(ev_facility) == LTT_FACILITY_KERNEL && + ev_id_entry == ltt_event_eventtype_id(e)) { + irq = ltt_event_get_long_unsigned(e, thf->f1); + } + else if(ltt_facility_name(ev_facility) == LTT_FACILITY_KERNEL && + ev_id_exit == ltt_event_eventtype_id(e)) { + irq = ts->cpu_states[cpu].last_irq; + } + else { + return 0; + } + + { + gchar *irqstr; + irqstr = g_strdup_printf("IRQ %u", irq); + resourceq = g_quark_from_string(irqstr); + g_free(irqstr); + } + guint trace_num = ts->parent.index; + +// 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, resourceq, 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; + resourcelist_add(process_list, + drawing, + trace_num, + resourceq, //process->name, + 1, //irq + irq, + &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; + prop_line.line_width = STATE_LINE_WIDTH; + prop_line.style = GDK_LINE_SOLID; + prop_line.y = MIDDLE; + irq_set_line_color(&prop_line, &ts->irq_states[irq]); + 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 * * Draw lines for process event. @@ -2577,7 +2813,10 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) prop_line.line_width = STATE_LINE_WIDTH; prop_line.style = GDK_LINE_SOLID; prop_line.y = MIDDLE; - cpu_set_line_color(&prop_line, &ts->cpu_states[process_info->id]); + if(process_info->type == 0) + cpu_set_line_color(&prop_line, &ts->cpu_states[process_info->id]); + else if(process_info->type == 1) + irq_set_line_color(&prop_line, &ts->irq_states[process_info->id]); draw_line((void*)&prop_line, (void*)&draw_context); } diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h index 6c2704d8..a68df007 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h @@ -52,7 +52,7 @@ typedef struct _ResourceInfo { GQuark name; guint trace_num; guint type; - guint id; + guint64 id; } ResourceInfo; typedef struct _HashedResourceData { @@ -118,11 +118,10 @@ void processlist_clear(ProcessList *process_list); // out : success (0) and height /* CPU num is only used for PID 0 */ -int processlist_add(ProcessList *process_list, Drawing_t * drawing, - guint pid, guint tgid, guint cpu, guint ppid, - LttTime *birth, guint trace_num, GQuark name, GQuark brand, guint *height, - ResourceInfo **process_info, - HashedResourceData **hashed_process_data); +int resourcelist_add( ProcessList *process_list, Drawing_t *drawing, guint trace_num, + GQuark name, guint type, guint id, guint *height, ResourceInfo **pm_resource_info, + HashedResourceData **pm_hashed_resource_data); + // out : success (0) and height int processlist_remove(ProcessList *process_list, guint pid, guint cpu, LttTime *birth, guint trace_num); -- 2.34.1