From 67f729732d629426de5a04965a81f6f0848af053 Mon Sep 17 00:00:00 2001 From: pmf Date: Tue, 27 Nov 2007 16:42:15 +0000 Subject: [PATCH] resourceview: redesign resource handling in a tree fashion git-svn-id: http://ltt.polymtl.ca/svn@2757 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/lttv/lttv/state.h | 7 +- .../poly/lttv/modules/gui/resourceview/cfv.c | 2 +- .../poly/lttv/modules/gui/resourceview/cfv.h | 6 +- .../lttv/modules/gui/resourceview/drawing.c | 16 +- .../modules/gui/resourceview/eventhooks.c | 1241 +++++------------ .../modules/gui/resourceview/processlist.c | 803 +++++------ .../modules/gui/resourceview/processlist.h | 97 +- 7 files changed, 844 insertions(+), 1328 deletions(-) diff --git a/ltt/branches/poly/lttv/lttv/state.h b/ltt/branches/poly/lttv/lttv/state.h index 79b1f2f0..c3bdf138 100644 --- a/ltt/branches/poly/lttv/lttv/state.h +++ b/ltt/branches/poly/lttv/lttv/state.h @@ -411,6 +411,11 @@ static inline guint lttv_state_get_target_pid(LttvTracefileState *tfs) #define HDR_QUARKS 9 #define HDR_QUARK 10 -#define MKDEV(ma,mi) ((ma)<<8 | (mi)) +/* Device number manipulation macros from kernel source */ +#define MINORBITS 20 +#define MINORMASK ((1U << MINORBITS) - 1) +#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) +#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) +#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) #endif // STATE_H diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.c b/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.c index 8638682f..cd185eda 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.c @@ -232,7 +232,7 @@ resourceview(LttvPluginTab *ptab) g_object_set_data( G_OBJECT(drawing_area), - "control_flow_data", + "resourceview_data", control_flow_data); g_control_flow_data_list = g_slist_append( diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.h b/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.h index 5c2276e4..46bc8043 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.h +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/cfv.h @@ -24,7 +24,6 @@ #include #include #include -#include "processlist.h" #include extern GQuark LTT_NAME_CPU; @@ -39,6 +38,11 @@ typedef struct _Drawing_t Drawing_t; typedef struct _ControlFlowData ControlFlowData; #endif //TYPE_CONTROLFLOWDATA_DEFINED +#ifndef TYPE_PROCESSLIST_DEFINED +#define TYPE_PROCESSLIST_DEFINED +typedef struct _ProcessList ProcessList; +#endif //TYPE_PROCESSLIST_DEFINED + struct _ControlFlowData { GtkWidget *top_widget; diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c index 519e69ae..243ee37b 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/drawing.c @@ -138,7 +138,7 @@ void drawing_data_request(Drawing_t *drawing, ControlFlowData *control_flow_data = drawing->control_flow_data; // (ControlFlowData*)g_object_get_data( - // G_OBJECT(drawing->drawing_area), "control_flow_data"); + // G_OBJECT(drawing->drawing_area), "resourceview_data"); LttTime start, time_end; LttTime window_end = time_window.end_time; @@ -453,7 +453,7 @@ void drawing_data_request(Drawing_t *drawing, static void set_last_start(gpointer key, gpointer value, gpointer user_data) { - ResourceInfo *process_info = (ResourceInfo*)key; + //ResourceInfo *process_info = (ResourceInfo*)key; HashedResourceData *hashed_process_data = (HashedResourceData*)value; guint x = (guint)user_data; @@ -473,6 +473,8 @@ static void set_last_start(gpointer key, gpointer value, gpointer user_data) void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState *tss) { + int i; + g_debug("Begin of data request"); ControlFlowData *cfd = events_request->viewer_data; LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tss); @@ -490,8 +492,10 @@ void drawing_data_request_begin(EventsRequest *events_request, LttvTracesetState width, &x); - g_hash_table_foreach(cfd->process_list->process_hash, set_last_start, - (gpointer)x); + for(i=0; iprocess_list->restypes[i].hash_table, set_last_start, + (gpointer)x); + } } @@ -673,7 +677,7 @@ expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer user_data ) ControlFlowData *control_flow_data = (ControlFlowData*)g_object_get_data( G_OBJECT(widget), - "control_flow_data"); + "resourceview_data"); #if 0 if(unlikely(drawing->gc == NULL)) { drawing->gc = gdk_gc_new(drawing->drawing_area->window); @@ -800,7 +804,7 @@ button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data ControlFlowData *control_flow_data = (ControlFlowData*)g_object_get_data( G_OBJECT(widget), - "control_flow_data"); + "resourceview_data"); Drawing_t *drawing = control_flow_data->drawing; TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab); diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c index 2c7d1e0c..4fa5db7b 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c @@ -91,20 +91,20 @@ extern GSList *g_legend_list; static gint background_ready(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData *)hook_data; + ControlFlowData *resourceview_data = (ControlFlowData *)hook_data; LttvTrace *trace = (LttvTrace*)call_data; - control_flow_data->background_info_waiting--; + resourceview_data->background_info_waiting--; - if(control_flow_data->background_info_waiting == 0) { + if(resourceview_data->background_info_waiting == 0) { g_message("control flow viewer : background computation data ready."); - drawing_clear(control_flow_data->drawing); - processlist_clear(control_flow_data->process_list); + drawing_clear(resourceview_data->drawing); + processlist_clear(resourceview_data->process_list); gtk_widget_set_size_request( - control_flow_data->drawing->drawing_area, - -1, processlist_get_height(control_flow_data->process_list)); - redraw_notify(control_flow_data, NULL); + resourceview_data->drawing->drawing_area, + -1, processlist_get_height(resourceview_data->process_list)); + redraw_notify(resourceview_data, NULL); } return 0; @@ -114,10 +114,10 @@ static gint background_ready(void *hook_data, void *call_data) /* Request background computation. Verify if it is in progress or ready first. * Only for each trace in the tab's traceset. */ -static void request_background_data(ControlFlowData *control_flow_data) +static void request_background_data(ControlFlowData *resourceview_data) { LttvTracesetContext * tsc = - lttvwindow_get_traceset_context(control_flow_data->tab); + lttvwindow_get_traceset_context(resourceview_data->tab); gint num_traces = lttv_traceset_number(tsc->ts); gint i; LttvTrace *trace; @@ -125,9 +125,9 @@ static void request_background_data(ControlFlowData *control_flow_data) LttvHooks *background_ready_hook = lttv_hooks_new(); - lttv_hooks_add(background_ready_hook, background_ready, control_flow_data, + lttv_hooks_add(background_ready_hook, background_ready, resourceview_data, LTTV_PRIO_DEFAULT); - control_flow_data->background_info_waiting = 0; + resourceview_data->background_info_waiting = 0; for(i=0;its, i); @@ -144,21 +144,21 @@ static void request_background_data(ControlFlowData *control_flow_data) */ if(!lttvwindowtraces_background_request_find(trace, "state")) lttvwindowtraces_background_request_queue( - main_window_get_widget(control_flow_data->tab), trace, "state"); - lttvwindowtraces_background_notify_queue(control_flow_data, + main_window_get_widget(resourceview_data->tab), trace, "state"); + lttvwindowtraces_background_notify_queue(resourceview_data, trace, ltt_time_infinite, NULL, background_ready_hook); - control_flow_data->background_info_waiting++; + resourceview_data->background_info_waiting++; } else { /* in progress */ - lttvwindowtraces_background_notify_current(control_flow_data, + lttvwindowtraces_background_notify_current(resourceview_data, trace, ltt_time_infinite, NULL, background_ready_hook); - control_flow_data->background_info_waiting++; + resourceview_data->background_info_waiting++; } } else { /* Data ready. By its nature, this viewer doesn't need to have @@ -166,15 +166,12 @@ static void request_background_data(ControlFlowData *control_flow_data) * request is always linked with a redraw. */ } - } lttv_hooks_destroy(background_ready_hook); } - - /** * Event Viewer's constructor hook * @@ -189,31 +186,31 @@ h_resourceview(LttvPlugin *plugin) LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin); Tab *tab = ptab->tab; g_info("h_guicontrolflow, %p", tab); - ControlFlowData *control_flow_data = resourceview(ptab); + ControlFlowData *resourceview_data = resourceview(ptab); - control_flow_data->tab = tab; + resourceview_data->tab = tab; // Unreg done in the GuiControlFlow_Destructor lttvwindow_register_traceset_notify(tab, traceset_notify, - control_flow_data); + resourceview_data); lttvwindow_register_time_window_notify(tab, update_time_window_hook, - control_flow_data); + resourceview_data); lttvwindow_register_current_time_notify(tab, update_current_time_hook, - control_flow_data); + resourceview_data); lttvwindow_register_redraw_notify(tab, redraw_notify, - control_flow_data); + resourceview_data); lttvwindow_register_continue_notify(tab, continue_notify, - control_flow_data); - request_background_data(control_flow_data); + resourceview_data); + request_background_data(resourceview_data); - return guicontrolflow_get_widget(control_flow_data) ; + return guicontrolflow_get_widget(resourceview_data) ; } @@ -246,9 +243,6 @@ h_legend(LttvPlugin *plugin) GtkWidget *pixmap = create_pixmap(GTK_WIDGET(legend), "lttv-color-list.png"); - // GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixmap( - // GDK_PIXMAP(pixmap), NULL)); - gtk_container_add(GTK_CONTAINER(legend), GTK_WIDGET(pixmap)); gtk_widget_show(GTK_WIDGET(pixmap)); @@ -261,7 +255,7 @@ h_legend(LttvPlugin *plugin) int event_selected_hook(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; + ControlFlowData *resourceview_data = (ControlFlowData*) hook_data; guint *event_number = (guint*) call_data; g_debug("DEBUG : event selected by main window : %u", *event_number); @@ -269,53 +263,6 @@ int event_selected_hook(void *hook_data, void *call_data) return 0; } -/* Function that selects the color of status&exemode line */ -static inline PropertiesLine prepare_s_e_line(LttvProcessState *process) -{ - PropertiesLine prop_line; - prop_line.line_width = STATE_LINE_WIDTH; - prop_line.style = GDK_LINE_SOLID; - prop_line.y = MIDDLE; - - if(process->state->s == LTTV_STATE_RUN) { - if(process->state->t == LTTV_STATE_USER_MODE) - prop_line.color = drawing_colors[COL_RUN_USER_MODE]; - else if(process->state->t == LTTV_STATE_SYSCALL) - prop_line.color = drawing_colors[COL_RUN_SYSCALL]; - else if(process->state->t == LTTV_STATE_TRAP) - prop_line.color = drawing_colors[COL_RUN_TRAP]; - else if(process->state->t == LTTV_STATE_IRQ) - prop_line.color = drawing_colors[COL_RUN_IRQ]; - else if(process->state->t == LTTV_STATE_SOFT_IRQ) - prop_line.color = drawing_colors[COL_RUN_SOFT_IRQ]; - else if(process->state->t == LTTV_STATE_MODE_UNKNOWN) - prop_line.color = drawing_colors[COL_MODE_UNKNOWN]; - else - g_assert(FALSE); /* RUNNING MODE UNKNOWN */ - } else if(process->state->s == LTTV_STATE_WAIT) { - /* We don't show if we wait while in user mode, trap, irq or syscall */ - prop_line.color = drawing_colors[COL_WAIT]; - } else if(process->state->s == LTTV_STATE_WAIT_CPU) { - /* We don't show if we wait for CPU while in user mode, trap, irq - * or syscall */ - prop_line.color = drawing_colors[COL_WAIT_CPU]; - } else if(process->state->s == LTTV_STATE_ZOMBIE) { - prop_line.color = drawing_colors[COL_ZOMBIE]; - } else if(process->state->s == LTTV_STATE_WAIT_FORK) { - prop_line.color = drawing_colors[COL_WAIT_FORK]; - } else if(process->state->s == LTTV_STATE_EXIT) { - prop_line.color = drawing_colors[COL_EXIT]; - } else if(process->state->s == LTTV_STATE_UNNAMED) { - prop_line.color = drawing_colors[COL_UNNAMED]; - } else { - g_critical("unknown state : %s", g_quark_to_string(process->state->s)); - g_assert(FALSE); /* UNKNOWN STATE */ - } - - return prop_line; - -} - static void cpu_set_line_color(PropertiesLine *prop_line, LttvCPUState *s) { GQuark present_state; @@ -404,7 +351,7 @@ int before_schedchange_hook(void *hook_data, void *call_data) { LttvTraceHook *th = (LttvTraceHook*)hook_data; EventsRequest *events_request = (EventsRequest*)th->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; @@ -416,9 +363,7 @@ int before_schedchange_hook(void *hook_data, void *call_data) gint target_pid_saved = tfc->target_pid; LttTime evtime = ltt_event_time(e); - LttvFilter *filter = control_flow_data->filter; - - GQuark cpuq; + LttvFilter *filter = resourceview_data->filter; /* we are in a schedchange, before the state update. We must draw the * items corresponding to the state before it changes : now is the right @@ -429,377 +374,133 @@ int before_schedchange_hook(void *hook_data, void *call_data) guint pid_in; pid_out = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 0)); pid_in = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 1)); +// TODO: can't we reenable this? pmf // if(pid_in != 0 && pid_out != 0) { // /* not a transition to/from idle */ // return 0; // } tfc->target_pid = pid_out; -// if(!filter || !filter->head || -// lttv_filter_tree_parse(filter->head,e,tfc->tf, -// tfc->t_context->t,tfc,NULL,NULL)) { - /* For the pid_out */ - /* First, check if the current process is in the state computation - * process list. If it is there, that means we must add it right now and - * draw items from the beginning of the read for it. If it is not - * present, it's a new process and it was not present : it will - * be added after the state update. */ - 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]; - /* unknown state, bad current pid */ -// if(process->pid != pid_out) -// process = lttv_state_find_process(ts, -// tfs->cpu, pid_out); - -// if(process != NULL) { - /* 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; - - hashed_process_data = processlist_get_process_data(process_list, cpuq, trace_num); -// hashed_process_data = processlist_get_process_data(process_list, -// pid_out, -// process->cpu, -// &birth, -// trace_num); - if(hashed_process_data == NULL) - { -// g_assert(pid_out == 0 || pid_out != process->ppid); - /* Process not present */ - ResourceInfo *process_info; - Drawing_t *drawing = control_flow_data->drawing; - resourcelist_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); + guint cpu = tfs->cpu; - } + guint trace_num = ts->parent.index; + /* Add process to process list (if not present) */ + guint pl_height = 0; + HashedResourceData *hashed_process_data = NULL; + ProcessList *process_list = resourceview_data->process_list; - /* 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(ltt_time_compare(hashed_process_data->next_good_time, - evtime) > 0) - { - if(hashed_process_data->x.middle_marked == FALSE) { - - TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + hashed_process_data = resourcelist_obtain_cpu(resourceview_data, trace_num, cpu); + + /* 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(ltt_time_compare(hashed_process_data->next_good_time, + evtime) > 0) + { + if(hashed_process_data->x.middle_marked == FALSE) { + + TimeWindow time_window = + lttvwindow_get_time_window(resourceview_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; + 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); + Drawing_t *drawing = resourceview_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(resourceview_data->tab); #ifdef EXTRA_CHECK - if(ltt_time_compare(evtime, time_window.start_time) == -1 + if(ltt_time_compare(evtime, time_window.start_time) == -1 || ltt_time_compare(evtime, time_window.end_time) == 1) - return; + 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(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used) - { - if(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); - PropertiesLine prop_line; - prop_line.line_width = STATE_LINE_WIDTH; - prop_line.style = GDK_LINE_SOLID; - prop_line.y = MIDDLE; - cpu_set_line_color(&prop_line, tfs->cpu_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; + Drawing_t *drawing = resourceview_data->drawing; + guint width = drawing->width; + guint x; + convert_time_to_pixels( + time_window, + evtime, + width, + &x); - /* Calculate the next good time */ - convert_pixels_to_time(width, x+1, time_window, - &hashed_process_data->next_good_time); - } + /* Jump over draw if we are at the same x position */ + if(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used) + { + if(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; } -// } -// } - -// tfc->target_pid = pid_in; -// if(!filter || !filter->head || -// lttv_filter_tree_parse(filter->head,e,tfc->tf, -// tfc->t_context->t,tfc,NULL,NULL)) { -// /* For the pid_in */ -// /* First, check if the current process is in the state computation -// * process list. If it is there, that means we must add it right now and -// * draw items from the beginning of the read for it. If it is not -// * present, it's a new process and it was not present : it will -// * be added after the state update. */ -// LttvProcessState *process; -// process = lttv_state_find_process(ts, -// tfs->cpu, pid_in); -// guint trace_num = ts->parent.index; -// -// if(process != NULL) { -// /* Well, the process 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; -// -// hashed_process_data = processlist_get_process_data(process_list, cpuq); -//// hashed_process_data = processlist_get_process_data(process_list, -//// pid_in, -//// tfs->cpu, -//// &birth, -//// trace_num); -// if(hashed_process_data == NULL) -// { -// g_assert(pid_in == 0 || pid_in != process->ppid); -// /* Process not present */ -// ResourceInfo *process_info; -// Drawing_t *drawing = control_flow_data->drawing; -// resourcelist_add(process_list, -// drawing, -//// pid_in, -//// process->tgid, -//// tfs->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); -// -// } -// //We could set the current process and hash here, but will be done -// //by after schedchange hook -// -// /* 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(ltt_time_compare(hashed_process_data->next_good_time, -// evtime) > 0) -// { -// if(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(x == hashed_process_data->x.middle && -// hashed_process_data->x.middle_used) -// { -// if(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); -// } -// } -// } else -// g_warning("Cannot find pin_in in schedchange %u", pid_in); -// } -// tfc->target_pid = target_pid_saved; - return 0; + /* 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; - /* Text dump */ -#ifdef DONTSHOW - GString *string = g_string_new("");; - gboolean field_names = TRUE, state = TRUE; + { + /* Draw the line */ + //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; + cpu_set_line_color(&prop_line, tfs->cpu_state); + draw_line((void*)&prop_line, (void*)&draw_context); - lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs); - g_string_append_printf(string,"\n"); + } + /* 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; - if(state) { - g_string_append_printf(string, " %s", - g_quark_to_string(tfs->process->state->s)); + /* Calculate the next good time */ + convert_pixels_to_time(width, x+1, time_window, + &hashed_process_data->next_good_time); + } } - g_info("%s",string->str); - - g_string_free(string, TRUE); - - /* End of text dump */ -#endif //DONTSHOW - + return 0; } /* after_schedchange_hook @@ -816,18 +517,15 @@ int after_schedchange_hook(void *hook_data, void *call_data) { LttvTraceHook *th = (LttvTraceHook*)hook_data; EventsRequest *events_request = (EventsRequest*)th->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; - + ControlFlowData *resourceview_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; + LttvFilter *filter = resourceview_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)) @@ -835,15 +533,13 @@ int after_schedchange_hook(void *hook_data, void *call_data) LttTime evtime = ltt_event_time(e); - GQuark cpuq; - /* Add process to process list (if not present) */ LttvProcessState *process_in; LttTime birth; guint pl_height = 0; HashedResourceData *hashed_process_data_in = NULL; - ProcessList *process_list = control_flow_data->process_list; + ProcessList *process_list = resourceview_data->process_list; guint pid_in; { @@ -857,12 +553,6 @@ int after_schedchange_hook(void *hook_data, void *call_data) //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in); //process_in = 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; process_in = ts->running_process[cpu]; /* It should exist, because we are after the state update. */ @@ -871,32 +561,9 @@ int after_schedchange_hook(void *hook_data, void *call_data) #endif //EXTRA_CHECK birth = process_in->creation_time; - hashed_process_data_in = processlist_get_process_data(process_list, cpuq, trace_num); -// hashed_process_data_in = processlist_get_process_data(process_list, -// pid_in, -// process_in->cpu, -// &birth, -// trace_num); - if(hashed_process_data_in == NULL) - { - g_assert(pid_in == 0 || pid_in != process_in->ppid); - ResourceInfo *process_info; - Drawing_t *drawing = control_flow_data->drawing; - /* Process not present */ - resourcelist_add(process_list, - drawing, - trace_num, - cpuq, - 0, - cpu, - &pl_height, - &process_info, - &hashed_process_data_in); - gtk_widget_set_size_request(drawing->drawing_area, - -1, - pl_height); - gtk_widget_queue_draw(drawing->drawing_area); - } + //hashed_process_data_in = processlist_get_process_data(process_list, cpuq, trace_num); + hashed_process_data_in = resourcelist_obtain_cpu(resourceview_data, trace_num, cpu); + /* Set the current process */ process_list->current_hash_data[trace_num][process_in->cpu] = hashed_process_data_in; @@ -905,14 +572,14 @@ int after_schedchange_hook(void *hook_data, void *call_data) evtime) <= 0) { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint new_x; @@ -952,7 +619,7 @@ int before_execmode_hook(void *hook_data, void *call_data) { LttvTraceHook *th = (LttvTraceHook*)hook_data; EventsRequest *events_request = (EventsRequest*)th->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; @@ -964,8 +631,6 @@ int before_execmode_hook(void *hook_data, void *call_data) LttTime evtime = ltt_event_time(e); - GQuark cpuq; - before_execmode_hook_irq(hook_data, call_data); /* we are in a execmode, before the state update. We must draw the @@ -973,58 +638,27 @@ int before_execmode_hook(void *hook_data, void *call_data) * 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; + ProcessList *process_list = resourceview_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; - resourcelist_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); - } + hashed_process_data = resourcelist_obtain_cpu(resourceview_data, trace_num, cpu); + /* Set the current process */ process_list->current_hash_data[trace_num][process->cpu] = hashed_process_data; @@ -1039,14 +673,14 @@ int before_execmode_hook(void *hook_data, void *call_data) { if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint x; convert_time_to_pixels( @@ -1066,14 +700,14 @@ int before_execmode_hook(void *hook_data, void *call_data) } else { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint x; @@ -1148,7 +782,7 @@ int before_execmode_hook_irq(void *hook_data, void *call_data) { LttvTraceHook *th = (LttvTraceHook*)hook_data; EventsRequest *events_request = (EventsRequest*)th->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; @@ -1162,8 +796,6 @@ int before_execmode_hook_irq(void *hook_data, void *call_data) LttTrace *trace = tfc->t_context->t; - 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. @@ -1185,58 +817,17 @@ int before_execmode_hook_irq(void *hook_data, void *call_data) return 0; } - { - gchar *irqstr; - irqstr = g_strdup_printf("IRQ %llu [%s]", irq, g_quark_to_string(ts->irq_names[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; -// } + ProcessList *process_list = resourceview_data->process_list; + + hashed_process_data = resourcelist_obtain_irq(resourceview_data, trace_num, irq); /* Now, the process is in the state hash and our own process hash. * We definitely can draw the items related to the ending state. @@ -1247,14 +838,14 @@ int before_execmode_hook_irq(void *hook_data, void *call_data) { if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint x; convert_time_to_pixels( @@ -1274,14 +865,14 @@ int before_execmode_hook_irq(void *hook_data, void *call_data) } else { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint x; @@ -1356,7 +947,7 @@ int before_bdev_event_hook(void *hook_data, void *call_data) { LttvTraceHook *th = (LttvTraceHook*)hook_data; EventsRequest *events_request = (EventsRequest*)th->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; @@ -1368,8 +959,6 @@ int before_bdev_event_hook(void *hook_data, void *call_data) 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. @@ -1382,58 +971,32 @@ int before_bdev_event_hook(void *hook_data, void *call_data) guint oper = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 2)); gint devcode_gint = MKDEV(major,minor); - { - gchar *resourcestr; - resourcestr = g_strdup_printf("Blockdev (%u,%u)", major, minor); - resourceq = g_quark_from_string(resourcestr); - g_free(resourcestr); - } guint trace_num = ts->parent.index; LttvBdevState *bdev = g_hash_table_lookup(ts->bdev_states, &devcode_gint); /* the result of the lookup might be NULL. that's ok, the rest of the function should understand it was not found and that its state is unknown */ -// 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; + ProcessList *process_list = resourceview_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 = resourcelist_obtain_bdev(resourceview_data, trace_num, devcode_gint); + ////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, - 2, //block dev - devcode_gint, /* MKDEV(major,minor) */ - &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; @@ -1448,14 +1011,14 @@ int before_bdev_event_hook(void *hook_data, void *call_data) { if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint x; convert_time_to_pixels( @@ -1475,14 +1038,14 @@ int before_bdev_event_hook(void *hook_data, void *call_data) } else { TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_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; + Drawing_t *drawing = resourceview_data->drawing; guint width = drawing->width; guint x; @@ -1555,9 +1118,9 @@ int before_bdev_event_hook(void *hook_data, void *call_data) gint update_time_window_hook(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; - Drawing_t *drawing = control_flow_data->drawing; - ProcessList *process_list = control_flow_data->process_list; + ControlFlowData *resourceview_data = (ControlFlowData*) hook_data; + Drawing_t *drawing = resourceview_data->drawing; + ProcessList *process_list = resourceview_data->process_list; const TimeWindowNotifyData *time_window_nofify_data = ((const TimeWindowNotifyData *)call_data); @@ -1568,7 +1131,7 @@ gint update_time_window_hook(void *hook_data, void *call_data) time_window_nofify_data->new_time_window; /* Update the ruler */ - drawing_update_ruler(control_flow_data->drawing, + drawing_update_ruler(resourceview_data->drawing, new_time_window); @@ -1611,7 +1174,7 @@ gint update_time_window_hook(void *hook_data, void *call_data) g_info("scrolling near right"); /* Scroll right, keep right part of the screen */ guint x = 0; - guint width = control_flow_data->drawing->width; + guint width = resourceview_data->drawing->width; convert_time_to_pixels( *old_time_window, *ns, @@ -1621,48 +1184,41 @@ gint update_time_window_hook(void *hook_data, void *call_data) /* Copy old data to new location */ copy_pixmap_region(process_list, NULL, - control_flow_data->drawing->drawing_area->style->black_gc, + resourceview_data->drawing->drawing_area->style->black_gc, NULL, x, 0, 0, 0, - control_flow_data->drawing->width-x+SAFETY, -1); + resourceview_data->drawing->width-x+SAFETY, -1); if(drawing->damage_begin == drawing->damage_end) - drawing->damage_begin = control_flow_data->drawing->width-x; + drawing->damage_begin = resourceview_data->drawing->width-x; else drawing->damage_begin = 0; - drawing->damage_end = control_flow_data->drawing->width; + drawing->damage_end = resourceview_data->drawing->width; /* Clear the data request background, but not SAFETY */ rectangle_pixmap(process_list, - control_flow_data->drawing->drawing_area->style->black_gc, + resourceview_data->drawing->drawing_area->style->black_gc, TRUE, drawing->damage_begin+SAFETY, 0, drawing->damage_end - drawing->damage_begin, // do not overlap -1); gtk_widget_queue_draw(drawing->drawing_area); - //gtk_widget_queue_draw_area (drawing->drawing_area, - // 0,0, - // control_flow_data->drawing->width, - // control_flow_data->drawing->height); /* Get new data for the rest. */ - drawing_data_request(control_flow_data->drawing, + drawing_data_request(resourceview_data->drawing, drawing->damage_begin, 0, drawing->damage_end - drawing->damage_begin, - control_flow_data->drawing->height); + resourceview_data->drawing->height); } else { - //if(nsdrawing->width; + guint width = resourceview_data->drawing->width; convert_time_to_pixels( *new_time_window, *os, @@ -1672,7 +1228,7 @@ gint update_time_window_hook(void *hook_data, void *call_data) /* Copy old data to new location */ copy_pixmap_region (process_list, NULL, - control_flow_data->drawing->drawing_area->style->black_gc, + resourceview_data->drawing->drawing_area->style->black_gc, NULL, 0, 0, x, 0, @@ -1682,29 +1238,24 @@ gint update_time_window_hook(void *hook_data, void *call_data) drawing->damage_end = x; else drawing->damage_end = - control_flow_data->drawing->width; + resourceview_data->drawing->width; drawing->damage_begin = 0; rectangle_pixmap (process_list, - control_flow_data->drawing->drawing_area->style->black_gc, + resourceview_data->drawing->drawing_area->style->black_gc, TRUE, drawing->damage_begin, 0, drawing->damage_end - drawing->damage_begin, // do not overlap -1); gtk_widget_queue_draw(drawing->drawing_area); - //gtk_widget_queue_draw_area (drawing->drawing_area, - // 0,0, - // control_flow_data->drawing->width, - // control_flow_data->drawing->height); - /* Get new data for the rest. */ - drawing_data_request(control_flow_data->drawing, + drawing_data_request(resourceview_data->drawing, drawing->damage_begin, 0, drawing->damage_end - drawing->damage_begin, - control_flow_data->drawing->height); + resourceview_data->drawing->height); } else { if(ltt_time_compare(*ns,*os) == 0) @@ -1716,25 +1267,21 @@ gint update_time_window_hook(void *hook_data, void *call_data) rectangle_pixmap (process_list, - control_flow_data->drawing->drawing_area->style->black_gc, + resourceview_data->drawing->drawing_area->style->black_gc, TRUE, 0, 0, - control_flow_data->drawing->width+SAFETY, // do not overlap + resourceview_data->drawing->width+SAFETY, // do not overlap -1); - //gtk_widget_queue_draw_area (drawing->drawing_area, - // 0,0, - // control_flow_data->drawing->width, - // control_flow_data->drawing->height); gtk_widget_queue_draw(drawing->drawing_area); drawing->damage_begin = 0; - drawing->damage_end = control_flow_data->drawing->width; + drawing->damage_end = resourceview_data->drawing->width; - drawing_data_request(control_flow_data->drawing, + drawing_data_request(resourceview_data->drawing, 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); + resourceview_data->drawing->width, + resourceview_data->drawing->height); } } @@ -1744,29 +1291,25 @@ gint update_time_window_hook(void *hook_data, void *call_data) g_info("zoom"); rectangle_pixmap (process_list, - control_flow_data->drawing->drawing_area->style->black_gc, + resourceview_data->drawing->drawing_area->style->black_gc, TRUE, 0, 0, - control_flow_data->drawing->width+SAFETY, // do not overlap + resourceview_data->drawing->width+SAFETY, // do not overlap -1); - //gtk_widget_queue_draw_area (drawing->drawing_area, - // 0,0, - // control_flow_data->drawing->width, - // control_flow_data->drawing->height); gtk_widget_queue_draw(drawing->drawing_area); drawing->damage_begin = 0; - drawing->damage_end = control_flow_data->drawing->width; + drawing->damage_end = resourceview_data->drawing->width; - drawing_data_request(control_flow_data->drawing, + drawing_data_request(resourceview_data->drawing, 0, 0, - control_flow_data->drawing->width, - control_flow_data->drawing->height); + resourceview_data->drawing->width, + resourceview_data->drawing->height); } /* Update directly when scrolling */ - gdk_window_process_updates(control_flow_data->drawing->drawing_area->window, + gdk_window_process_updates(resourceview_data->drawing->drawing_area->window, TRUE); return 0; @@ -1774,8 +1317,8 @@ gint update_time_window_hook(void *hook_data, void *call_data) gint traceset_notify(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; - Drawing_t *drawing = control_flow_data->drawing; + ControlFlowData *resourceview_data = (ControlFlowData*) hook_data; + Drawing_t *drawing = resourceview_data->drawing; if(unlikely(drawing->gc == NULL)) { return FALSE; @@ -1784,35 +1327,35 @@ gint traceset_notify(void *hook_data, void *call_data) return FALSE; } - drawing_clear(control_flow_data->drawing); - processlist_clear(control_flow_data->process_list); + drawing_clear(resourceview_data->drawing); + processlist_clear(resourceview_data->process_list); gtk_widget_set_size_request( - control_flow_data->drawing->drawing_area, - -1, processlist_get_height(control_flow_data->process_list)); - redraw_notify(control_flow_data, NULL); + resourceview_data->drawing->drawing_area, + -1, processlist_get_height(resourceview_data->process_list)); + redraw_notify(resourceview_data, NULL); - request_background_data(control_flow_data); + request_background_data(resourceview_data); return FALSE; } gint redraw_notify(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; - Drawing_t *drawing = control_flow_data->drawing; + ControlFlowData *resourceview_data = (ControlFlowData*) hook_data; + Drawing_t *drawing = resourceview_data->drawing; GtkWidget *widget = drawing->drawing_area; drawing->damage_begin = 0; drawing->damage_end = drawing->width; /* fun feature, to be separated someday... */ - drawing_clear(control_flow_data->drawing); - processlist_clear(control_flow_data->process_list); + drawing_clear(resourceview_data->drawing); + processlist_clear(resourceview_data->process_list); gtk_widget_set_size_request( - control_flow_data->drawing->drawing_area, - -1, processlist_get_height(control_flow_data->process_list)); + resourceview_data->drawing->drawing_area, + -1, processlist_get_height(resourceview_data->process_list)); // Clear the images - rectangle_pixmap (control_flow_data->process_list, + rectangle_pixmap (resourceview_data->process_list, widget->style->black_gc, TRUE, 0, 0, @@ -1830,10 +1373,6 @@ gint redraw_notify(void *hook_data, void *call_data) drawing->height); } - //gtk_widget_queue_draw_area(drawing->drawing_area, - // 0,0, - // drawing->width, - // drawing->height); return FALSE; } @@ -1841,10 +1380,8 @@ gint redraw_notify(void *hook_data, void *call_data) gint continue_notify(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; - Drawing_t *drawing = control_flow_data->drawing; - - //g_assert(widget->allocation.width == drawing->damage_end); + ControlFlowData *resourceview_data = (ControlFlowData*) hook_data; + Drawing_t *drawing = resourceview_data->drawing; if(drawing->damage_begin < drawing->damage_end) { @@ -1861,13 +1398,13 @@ gint continue_notify(void *hook_data, void *call_data) gint update_current_time_hook(void *hook_data, void *call_data) { - ControlFlowData *control_flow_data = (ControlFlowData*)hook_data; - Drawing_t *drawing = control_flow_data->drawing; + ControlFlowData *resourceview_data = (ControlFlowData*)hook_data; + Drawing_t *drawing = resourceview_data->drawing; LttTime current_time = *((LttTime*)call_data); TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + lttvwindow_get_time_window(resourceview_data->tab); LttTime time_begin = time_window.start_time; LttTime width = time_window.time_width; @@ -1880,15 +1417,13 @@ gint update_current_time_hook(void *hook_data, void *call_data) LttTime time_end = ltt_time_add(time_begin, width); LttvTracesetContext * tsc = - lttvwindow_get_traceset_context(control_flow_data->tab); + lttvwindow_get_traceset_context(resourceview_data->tab); LttTime trace_start = tsc->time_span.start_time; LttTime trace_end = tsc->time_span.end_time; g_info("New current time HOOK : %lu, %lu", current_time.tv_sec, current_time.tv_nsec); - - /* If current time is inside time interval, just move the highlight * bar */ @@ -1915,7 +1450,7 @@ gint update_current_time_hook(void *hook_data, void *call_data) new_time_window.time_width_double = ltt_time_to_double(width); new_time_window.end_time = ltt_time_add(time_begin, width); - lttvwindow_report_time_window(control_flow_data->tab, new_time_window); + lttvwindow_report_time_window(resourceview_data->tab, new_time_window); } else if(ltt_time_compare(current_time, time_end) > 0) { @@ -1931,13 +1466,13 @@ gint update_current_time_hook(void *hook_data, void *call_data) new_time_window.time_width_double = ltt_time_to_double(width); new_time_window.end_time = ltt_time_add(time_begin, width); - lttvwindow_report_time_window(control_flow_data->tab, new_time_window); + lttvwindow_report_time_window(resourceview_data->tab, new_time_window); } - gtk_widget_queue_draw(control_flow_data->drawing->drawing_area); + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); /* Update directly when scrolling */ - gdk_window_process_updates(control_flow_data->drawing->drawing_area->window, + gdk_window_process_updates(resourceview_data->drawing->drawing_area->window, TRUE); return 0; @@ -1954,12 +1489,12 @@ typedef struct _ClosureData { void draw_closure(gpointer key, gpointer value, gpointer user_data) { - ResourceInfo *process_info = (ResourceInfo*)key; + ResourceUniqueNumeric *process_info = (ResourceUniqueNumeric*)key; HashedResourceData *hashed_process_data = (HashedResourceData*)value; ClosureData *closure_data = (ClosureData*)user_data; EventsRequest *events_request = closure_data->events_request; - ControlFlowData *control_flow_data = events_request->viewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracesetState *tss = closure_data->tss; LttvTracesetContext *tsc = (LttvTracesetContext*)tss; @@ -1968,6 +1503,9 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) gboolean dodraw = TRUE; + if(hashed_process_data->type == RV_RESOURCE_MACHINE) + return; + { /* For the process */ /* First, check if the current process is in the state computation @@ -1981,152 +1519,119 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) LttvTraceContext *tc = tsc->traces[process_info->trace_num]; LttvTraceState *ts = (LttvTraceState*)tc; -#if 0 - //FIXME : optimize data structures. - LttvTracefileState *tfs; - LttvTracefileContext *tfc; - guint i; - for(i=0;itracefiles->len;i++) { - tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, i); - if(ltt_tracefile_name(tfc->tf) == LTT_NAME_CPU - && tfs->cpu == process_info->cpu) - break; - - } - g_assert(itracefiles->len); - tfs = LTTV_TRACEFILE_STATE(tfc); -#endif //0 - // LttvTracefileState *tfs = - // (LttvTracefileState*)tsc->traces[process_info->trace_num]-> - // tracefiles[process_info->cpu]; - -// LttvProcessState *process; -// process = lttv_state_find_process(ts, process_info->cpu, -// process_info->pid); - -// if(unlikely(process != NULL)) { - -// LttvFilter *filter = control_flow_data->filter; -// if(filter != NULL && filter->head != NULL) -// if(!lttv_filter_tree_parse(filter->head,NULL,NULL, -// tc->t,NULL,process,tc)) -// dodraw = FALSE; - - /* Only draw for processes that are currently in the trace states */ + /* Only draw for processes that are currently in the trace states */ - ProcessList *process_list = control_flow_data->process_list; + ProcessList *process_list = resourceview_data->process_list; #ifdef EXTRA_CHECK - /* Should be alike when background info is ready */ - if(control_flow_data->background_info_waiting==0) + /* Should be alike when background info is ready */ + if(resourceview_data->background_info_waiting==0) g_assert(ltt_time_compare(process->creation_time, process_info->birth) == 0); #endif //EXTRA_CHECK - /* 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(unlikely(ltt_time_compare(hashed_process_data->next_good_time, - evtime) <= 0)) - { - TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); + /* 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(unlikely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) <= 0)) + { + TimeWindow time_window = + lttvwindow_get_time_window(resourceview_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; + 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 = closure_data->x_end; - - 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.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; + Drawing_t *drawing = resourceview_data->drawing; + guint width = drawing->width; + + guint x = closure_data->x_end; + + 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.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; #if 0 - /* Jump over draw if we are at the same x position */ - if(x == hashed_process_data->x.over) - { - /* jump */ - } else { - draw_context.drawinfo.start.x = hashed_process_data->x.over; - /* Draw the line */ - PropertiesLine prop_line = prepare_execmode_line(process); - draw_line((void*)&prop_line, (void*)&draw_context); + /* Jump over draw if we are at the same x position */ + if(x == hashed_process_data->x.over) + { + /* jump */ + } else { + draw_context.drawinfo.start.x = hashed_process_data->x.over; + /* Draw the line */ + PropertiesLine prop_line = prepare_execmode_line(process); + draw_line((void*)&prop_line, (void*)&draw_context); - hashed_process_data->x.over = x; - } + hashed_process_data->x.over = x; + } #endif //0 - if(unlikely(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used)) { + if(unlikely(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used)) { #if 0 /* do not mark closure : not missing information */ - if(hashed_process_data->x.middle_marked == FALSE) { - /* Draw collision indicator */ - gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); - gdk_draw_point(drawing->pixmap, - drawing->gc, - x, - y+(height/2)-3); - hashed_process_data->x.middle_marked = TRUE; - } + if(hashed_process_data->x.middle_marked == FALSE) { + /* Draw collision indicator */ + gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); + gdk_draw_point(drawing->pixmap, + drawing->gc, + x, + y+(height/2)-3); + hashed_process_data->x.middle_marked = TRUE; + } #endif //0 - /* Jump */ - } else { - draw_context.drawinfo.start.x = hashed_process_data->x.middle; - /* Draw the line */ - if(dodraw) { - PropertiesLine prop_line; - prop_line.line_width = STATE_LINE_WIDTH; - prop_line.style = GDK_LINE_SOLID; - prop_line.y = MIDDLE; - 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]); - else if(process_info->type == 2) { - gint devcode_gint = process_info->id; - LttvBdevState *bdev = g_hash_table_lookup(ts->bdev_states, &devcode_gint); - // the lookup may return null; bdev_set_line_color must act appropriately - bdev_set_line_color(&prop_line, bdev); - } - - draw_line((void*)&prop_line, (void*)&draw_context); + /* Jump */ + } else { + draw_context.drawinfo.start.x = hashed_process_data->x.middle; + /* Draw the line */ + if(dodraw) { + PropertiesLine prop_line; + prop_line.line_width = STATE_LINE_WIDTH; + prop_line.style = GDK_LINE_SOLID; + prop_line.y = MIDDLE; + if(hashed_process_data->type == RV_RESOURCE_CPU) + cpu_set_line_color(&prop_line, &ts->cpu_states[process_info->id]); + else if(hashed_process_data->type == RV_RESOURCE_IRQ) + irq_set_line_color(&prop_line, &ts->irq_states[process_info->id]); + else if(hashed_process_data->type == RV_RESOURCE_BDEV) { + gint devcode_gint = process_info->id; + LttvBdevState *bdev = g_hash_table_lookup(ts->bdev_states, &devcode_gint); + // the lookup may return null; bdev_set_line_color must act appropriately + bdev_set_line_color(&prop_line, bdev); } + + draw_line((void*)&prop_line, (void*)&draw_context); + } - /* become the last x position */ - if(likely(x != hashed_process_data->x.middle)) { - hashed_process_data->x.middle = x; - /* but don't use the pixel */ - hashed_process_data->x.middle_used = FALSE; + /* become the last x position */ + if(likely(x != hashed_process_data->x.middle)) { + hashed_process_data->x.middle = x; + /* but don't use the pixel */ + hashed_process_data->x.middle_used = FALSE; - /* Calculate the next good time */ - convert_pixels_to_time(width, x+1, time_window, - &hashed_process_data->next_good_time); - } + /* Calculate the next good time */ + convert_pixels_to_time(width, x+1, time_window, + &hashed_process_data->next_good_time); } } -// } + } } - return; } int before_chunk(void *hook_data, void *call_data) @@ -2135,7 +1640,7 @@ int before_chunk(void *hook_data, void *call_data) LttvTracesetState *tss = (LttvTracesetState*)call_data; ControlFlowData *cfd = (ControlFlowData*)events_request->viewer_data; #if 0 - /* Desactivate sort */ + /* Deactivate sort */ gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE(cfd->process_list->list_store), TRACE_COLUMN, @@ -2166,38 +1671,39 @@ int before_request(void *hook_data, void *call_data) * draw closing line * expose */ -// TODO pmf: reenable this int after_request(void *hook_data, void *call_data) { -// EventsRequest *events_request = (EventsRequest*)hook_data; -// ControlFlowData *control_flow_data = events_request->viewer_data; -// LttvTracesetState *tss = (LttvTracesetState*)call_data; -// -// ProcessList *process_list = control_flow_data->process_list; -// LttTime end_time = events_request->end_time; -// -// ClosureData closure_data; -// closure_data.events_request = (EventsRequest*)hook_data; -// closure_data.tss = tss; -// closure_data.end_time = end_time; -// -// TimeWindow time_window = -// lttvwindow_get_time_window(control_flow_data->tab); -// guint width = control_flow_data->drawing->width; -// convert_time_to_pixels( -// time_window, -// end_time, -// width, -// &closure_data.x_end); -// -// -// /* Draw last items */ -// g_hash_table_foreach(process_list->process_hash, draw_closure, -// (void*)&closure_data); -// -// -// /* Request expose */ -// drawing_request_expose(events_request, tss, end_time); + guint i; + EventsRequest *events_request = (EventsRequest*)hook_data; + ControlFlowData *resourceview_data = events_request->viewer_data; + LttvTracesetState *tss = (LttvTracesetState*)call_data; + + ProcessList *process_list = resourceview_data->process_list; + LttTime end_time = events_request->end_time; + + ClosureData closure_data; + closure_data.events_request = (EventsRequest*)hook_data; + closure_data.tss = tss; + closure_data.end_time = end_time; + + TimeWindow time_window = + lttvwindow_get_time_window(resourceview_data->tab); + guint width = resourceview_data->drawing->width; + convert_time_to_pixels( + time_window, + end_time, + width, + &closure_data.x_end); + + + /* Draw last items */ + for(i=0; iviewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracesetState *tss = (LttvTracesetState*)call_data; LttvTracesetContext *tsc = (LttvTracesetContext*)call_data; LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc); LttTime end_time; - ProcessList *process_list = control_flow_data->process_list; + ProcessList *process_list = resourceview_data->process_list; guint i; LttvTraceset *traceset = tsc->ts; guint nb_trace = lttv_traceset_number(traceset); @@ -2240,8 +1746,8 @@ int after_chunk(void *hook_data, void *call_data) closure_data.end_time = end_time; TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); - guint width = control_flow_data->drawing->width; + lttvwindow_get_time_window(resourceview_data->tab); + guint width = resourceview_data->drawing->width; convert_time_to_pixels( time_window, end_time, @@ -2249,18 +1755,20 @@ int after_chunk(void *hook_data, void *call_data) &closure_data.x_end); /* Draw last items */ - g_hash_table_foreach(process_list->process_hash, draw_closure, + for(i=0; iprocess_list->list_store), + GTK_TREE_SORTABLE(resourceview_data->process_list->list_store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING); - update_index_to_pixmap(control_flow_data->process_list); + update_index_to_pixmap(resourceview_data->process_list); /* Request a full expose : drawing scrambled */ - gtk_widget_queue_draw(control_flow_data->drawing->drawing_area); + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); #endif //0 /* Request expose (updates damages zone also) */ drawing_request_expose(events_request, tss, end_time); @@ -2278,9 +1786,11 @@ int after_chunk(void *hook_data, void *call_data) */ int before_statedump_end(void *hook_data, void *call_data) { + gint i; + LttvTraceHook *th = (LttvTraceHook*)hook_data; EventsRequest *events_request = (EventsRequest*)th->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; + ControlFlowData *resourceview_data = events_request->viewer_data; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; @@ -2289,12 +1799,12 @@ int before_statedump_end(void *hook_data, void *call_data) LttvTraceState *ts = (LttvTraceState *)tfc->t_context; LttvTracesetState *tss = (LttvTracesetState*)tfc->t_context->ts_context; - ProcessList *process_list = control_flow_data->process_list; + ProcessList *process_list = resourceview_data->process_list; LttEvent *e; e = ltt_tracefile_get_event(tfc->tf); - LttvFilter *filter = control_flow_data->filter; + LttvFilter *filter = resourceview_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)) @@ -2308,8 +1818,8 @@ int before_statedump_end(void *hook_data, void *call_data) closure_data.end_time = evtime; TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); - guint width = control_flow_data->drawing->width; + lttvwindow_get_time_window(resourceview_data->tab); + guint width = resourceview_data->drawing->width; convert_time_to_pixels( time_window, evtime, @@ -2317,18 +1827,21 @@ int before_statedump_end(void *hook_data, void *call_data) &closure_data.x_end); /* Draw last items */ - g_hash_table_foreach(process_list->process_hash, draw_closure, + + for(i=0; iprocess_list->list_store), + GTK_TREE_SORTABLE(resourceview_data->process_list->list_store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING); - update_index_to_pixmap(control_flow_data->process_list); + update_index_to_pixmap(resourceview_data->process_list); /* Request a full expose : drawing scrambled */ - gtk_widget_queue_draw(control_flow_data->drawing->drawing_area); + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); #endif //0 /* Request expose (updates damages zone also) */ drawing_request_expose(events_request, tss, evtime); diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c index 940369f8..3495202c 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c @@ -26,7 +26,6 @@ #include #include #include -# #include "processlist.h" #include "drawing.h" @@ -58,54 +57,23 @@ gint resource_sort_func ( GtkTreeModel *model, return strcmp(a_name, b_name); } -//static guint process_list_hash_fct(gconstpointer key) -//{ -// guint pid = ((const ResourceInfo*)key)->pid; -// return ((pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ^ ((const ResourceInfo*)key)->cpu); -//} -// -///* If hash is good, should be different */ -//static gboolean process_list_equ_fct(gconstpointer a, gconstpointer b) -//{ -// const ResourceInfo *pa = (const ResourceInfo*)a; -// const ResourceInfo *pb = (const ResourceInfo*)b; -// -// gboolean ret = TRUE; -// -// if(likely(pa->pid != pb->pid)) -// ret = FALSE; -// if(likely((pa->pid == 0 && (pa->cpu != pb->cpu)))) -// ret = FALSE; -// if(unlikely(ltt_time_compare(pa->birth, pb->birth) != 0)) -// ret = FALSE; -// if(unlikely(pa->trace_num != pb->trace_num)) -// ret = FALSE; -// -// return ret; -//} - -static guint resource_list_hash_fct(gconstpointer key) +static guint ru_numeric_hash_fct(gconstpointer key) { - gchar *name = g_quark_to_string(((const ResourceInfo*)key)->name); - return g_str_hash(name); + ResourceUniqueNumeric *ru = (const ResourceUniqueNumeric *)key; + int tmp = (ru->trace_num << 8) ^ ru->id; + + return g_int_hash(&tmp); } -static gboolean resource_list_equ_fct(gconstpointer a, gconstpointer b) +static gboolean ru_numeric_equ_fct(gconstpointer a, gconstpointer b) { - const ResourceInfo *pa = (const ResourceInfo*)a; - const ResourceInfo *pb = (const ResourceInfo*)b; + const ResourceUniqueNumeric *pa = (const ResourceUniqueNumeric *)a; + const ResourceUniqueNumeric *pb = (const ResourceUniqueNumeric *)b; - gboolean ret = TRUE; - - /* TODO pmf: add some else's here to make it faster */ - /* TODO pmf: this is highly inefficient */ - - if(likely(strcmp(g_quark_to_string(pa->name), g_quark_to_string(pb->name)) != 0)) - ret = FALSE; - if(unlikely(pa->trace_num != pb->trace_num)) - ret = FALSE; + if(pa->id == pb->id && pa->trace_num == pb->trace_num) + return TRUE; - return ret; + return FALSE; } void destroy_hash_key(gpointer key); @@ -118,7 +86,7 @@ gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) ControlFlowData *control_flow_data = (ControlFlowData*)g_object_get_data( G_OBJECT(widget), - "control_flow_data"); + "resourceview_data"); Drawing_t *drawing = control_flow_data->drawing; unsigned int cell_height = get_cell_height(GTK_TREE_VIEW(control_flow_data->process_list->process_list_widget)); @@ -138,33 +106,45 @@ gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) return TRUE; } - -static void update_index_to_pixmap_each(ResourceInfo *key, - HashedResourceData *value, - ProcessList *process_list) +static gboolean update_index_to_pixmap_each (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, UpdateIndexPixmapArg *arg) { - guint array_index = processlist_get_index_from_data(process_list, value); + guint array_index = arg->count; + HashedResourceData *hdata; + gchar *name; + + gtk_tree_model_get(model, iter, NAME_COLUMN, &name, DATA_COLUMN, &hdata, -1); + + g_assert(array_index < arg->process_list->index_to_pixmap->len); - g_assert(array_index < process_list->index_to_pixmap->len); + GdkPixmap **pixmap = + (GdkPixmap**)&g_ptr_array_index(arg->process_list->index_to_pixmap, array_index); + *pixmap = hdata->pixmap; - GdkPixmap **pixmap = - (GdkPixmap**)&g_ptr_array_index(process_list->index_to_pixmap, array_index); + arg->count++; - *pixmap = value->pixmap; + return FALSE; } - void update_index_to_pixmap(ProcessList *process_list) { - g_ptr_array_set_size(process_list->index_to_pixmap, - g_hash_table_size(process_list->process_hash)); - g_hash_table_foreach(process_list->process_hash, - (GHFunc)update_index_to_pixmap_each, - process_list); + int i, items=0; + UpdateIndexPixmapArg arg; + + for(i=0; irestypes[i].hash_table); + } + + g_ptr_array_set_size(process_list->index_to_pixmap, items); + + arg.count = 0; + arg.process_list = process_list; + + gtk_tree_model_foreach(process_list->list_store, + (GtkTreeModelForeachFunc)update_index_to_pixmap_each, &arg); } -static void update_pixmap_size_each(ResourceInfo *key, +static void update_pixmap_size_each(void *key, HashedResourceData *value, guint width) { @@ -182,9 +162,12 @@ static void update_pixmap_size_each(ResourceInfo *key, void update_pixmap_size(ProcessList *process_list, guint width) { - g_hash_table_foreach(process_list->process_hash, + int i; + for(i=0; irestypes[i].hash_table, (GHFunc)update_pixmap_size_each, (gpointer)width); + } } @@ -195,7 +178,7 @@ typedef struct _CopyPixmap { gint xsrc, ysrc, xdest, ydest, width, height; } CopyPixmap; -static void copy_pixmap_region_each(ResourceInfo *key, +static void copy_pixmap_region_each(void *key, HashedResourceData *value, CopyPixmap *cp) { @@ -220,11 +203,14 @@ void copy_pixmap_region(ProcessList *process_list, GdkDrawable *dest, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height) { + int i; CopyPixmap cp = { dest, gc, src, xsrc, ysrc, xdest, ydest, width, height }; - g_hash_table_foreach(process_list->process_hash, + for(i=0; irestypes[i].hash_table, (GHFunc)copy_pixmap_region_each, &cp); + } } @@ -235,7 +221,7 @@ typedef struct _RectanglePixmap { GdkGC *gc; } RectanglePixmap; -static void rectangle_pixmap_each(ResourceInfo *key, +static void rectangle_pixmap_each(void *key, HashedResourceData *value, RectanglePixmap *rp) { @@ -249,20 +235,19 @@ static void rectangle_pixmap_each(ResourceInfo *key, rp->width, rp->height); } - - - void rectangle_pixmap(ProcessList *process_list, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height) { + int i; RectanglePixmap rp = { filled, x, y, width, height, gc }; - g_hash_table_foreach(process_list->process_hash, + for(i=0; irestypes[i].hash_table, (GHFunc)rectangle_pixmap_each, &rp); + } } - /* Renders each pixmaps into on big drawable */ void copy_pixmap_to_screen(ProcessList *process_list, GdkDrawable *dest, @@ -308,12 +293,12 @@ ProcessList *processlist_construct(void) process_list->current_hash_data = NULL; /* Create the Process list */ - process_list->list_store = gtk_list_store_new ( N_COLUMNS, G_TYPE_STRING); - + process_list->list_store = gtk_tree_store_new ( N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); process_list->process_list_widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (process_list->list_store)); + g_object_set(process_list->process_list_widget, "enable-tree-lines", TRUE, NULL); g_object_unref (G_OBJECT (process_list->list_store)); @@ -329,13 +314,6 @@ ProcessList *processlist_construct(void) GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING); - - process_list->process_hash = g_hash_table_new_full( - resource_list_hash_fct, resource_list_equ_fct, - destroy_hash_key, destroy_hash_data - ); - - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(process_list->process_list_widget), TRUE); @@ -377,77 +355,6 @@ ProcessList *processlist_construct(void) GTK_TREE_VIEW (process_list->process_list_widget), column); process_list->button = column->button; - -// column = gtk_tree_view_column_new_with_attributes ( "Brand", -// renderer, -// "text", -// BRAND_COLUMN, -// NULL); -// gtk_tree_view_column_set_alignment (column, 0.0); -// gtk_tree_view_column_set_fixed_width (column, 45); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// column = gtk_tree_view_column_new_with_attributes ( "PID", -// renderer, -// "text", -// PID_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// column = gtk_tree_view_column_new_with_attributes ( "TGID", -// renderer, -// "text", -// TGID_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// column = gtk_tree_view_column_new_with_attributes ( "PPID", -// renderer, -// "text", -// PPID_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// column = gtk_tree_view_column_new_with_attributes ( "CPU", -// renderer, -// "text", -// CPU_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// column = gtk_tree_view_column_new_with_attributes ( "Birth sec", -// renderer, -// "text", -// BIRTH_S_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// //gtk_tree_view_column_set_visible(column, 0); -// // -// column = gtk_tree_view_column_new_with_attributes ( "Birth nsec", -// renderer, -// "text", -// BIRTH_NS_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); -// -// column = gtk_tree_view_column_new_with_attributes ( "TRACE", -// renderer, -// "text", -// TRACE_COLUMN, -// NULL); -// gtk_tree_view_append_column ( -// GTK_TREE_VIEW (process_list->process_list_widget), column); - - - //gtk_tree_view_column_set_visible(column, 0); g_object_set_data_full( G_OBJECT(process_list->process_list_widget), @@ -456,22 +363,32 @@ ProcessList *processlist_construct(void) (GDestroyNotify)processlist_destroy); process_list->index_to_pixmap = g_ptr_array_sized_new(ALLOCATE_PROCESSES); + + process_list->restypes[RV_RESOURCE_MACHINE].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); + process_list->restypes[RV_RESOURCE_CPU].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); + process_list->restypes[RV_RESOURCE_IRQ].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); + process_list->restypes[RV_RESOURCE_BDEV].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); return process_list; } void processlist_destroy(ProcessList *process_list) { + int i; + g_debug("processlist_destroy %p", process_list); - g_hash_table_destroy(process_list->process_hash); - process_list->process_hash = NULL; + + for(i=0; irestypes[i].hash_table); + process_list->restypes[i].hash_table = NULL; + } g_ptr_array_free(process_list->index_to_pixmap, TRUE); g_free(process_list); g_debug("processlist_destroy end"); } -static gboolean remove_hash_item(ResourceInfo *process_info, +static gboolean remove_hash_item(void *key, HashedResourceData *hashed_process_data, ProcessList *process_list) { @@ -479,7 +396,7 @@ static gboolean remove_hash_item(ResourceInfo *process_info, iter = hashed_process_data->y_iter; - gtk_list_store_remove (process_list->list_store, &iter); + gtk_tree_store_remove (process_list->list_store, &iter); gdk_pixmap_unref(hashed_process_data->pixmap); // TODO pmf: check this; might be needed @@ -493,11 +410,15 @@ static gboolean remove_hash_item(ResourceInfo *process_info, void processlist_clear(ProcessList *process_list) { + int i; + g_info("processlist_clear %p", process_list); - g_hash_table_foreach_remove(process_list->process_hash, - (GHRFunc)remove_hash_item, - (gpointer)process_list); + for(i=RV_RESOURCE_COUNT-1; i>=0; i--) { + g_hash_table_foreach_remove(process_list->restypes[i].hash_table, + (GHRFunc)remove_hash_item, + (gpointer)process_list); + } process_list->number_of_process = 0; update_index_to_pixmap(process_list); } @@ -519,298 +440,324 @@ void destroy_hash_data(gpointer data) g_free(data); } - -//void processlist_set_name(ProcessList *process_list, -// GQuark name, -// HashedResourceData *hashed_process_data) -//{ -// gtk_list_store_set ( process_list->list_store, &hashed_process_data->y_iter, -// PROCESS_COLUMN, g_quark_to_string(name), -// -1); -//} -// -//void processlist_set_brand(ProcessList *process_list, -// GQuark brand, -// HashedResourceData *hashed_process_data) -//{ -// gtk_list_store_set ( process_list->list_store, &hashed_process_data->y_iter, -// BRAND_COLUMN, g_quark_to_string(brand), -// -1); -//} -// -//void processlist_set_tgid(ProcessList *process_list, -// guint tgid, -// HashedResourceData *hashed_process_data) -//{ -// gtk_list_store_set ( process_list->list_store, &hashed_process_data->y_iter, -// TGID_COLUMN, tgid, -// -1); -//} -// -//void processlist_set_ppid(ProcessList *process_list, -// guint ppid, -// HashedResourceData *hashed_process_data) -//{ -// gtk_list_store_set ( process_list->list_store, &hashed_process_data->y_iter, -// PPID_COLUMN, ppid, -// -1); -//} - -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) +HashedResourceData *resourcelist_obtain_machine(ControlFlowData *resourceview_data, guint trace_num, guint id) { - ResourceInfo *Resource_Info = g_new(ResourceInfo, 1); - HashedResourceData *hashed_resource_data = g_new(HashedResourceData, 1); - *pm_hashed_resource_data = hashed_resource_data; - *pm_resource_info = Resource_Info; + ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); + HashedResourceData *data = g_new(HashedResourceData, 1); + + /* Prepare hash key */ + ru->trace_num = trace_num; + ru->id = id; + + /* Search within hash table */ + GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_MACHINE].hash_table; + data = g_hash_table_lookup(ht, ru); + + /* If not found in hash table, add it */ + if(data == NULL) { + GQuark name; + + data = g_malloc(sizeof(HashedResourceData)); + /* Prepare hashed data */ + data->type = RV_RESOURCE_MACHINE; + data->x.over = 0; + data->x.over_used = FALSE; + data->x.over_marked = FALSE; + data->x.middle = 0; // last + data->x.middle_used = FALSE; + data->x.middle_marked = FALSE; + data->x.under = 0; + data->x.under_used = FALSE; + data->x.under_marked = FALSE; + data->next_good_time = ltt_time_zero; + + data->height = resourceview_data->process_list->cell_height; + data->pixmap = + gdk_pixmap_new(resourceview_data->drawing->drawing_area->window, + resourceview_data->drawing->alloc_width, + data->height, + -1); + g_assert(data->pixmap); - Resource_Info->name = name; - -// Process_Info->pid = pid; -// Process_Info->tgid = tgid; -// if(pid == 0) -// Process_Info->cpu = cpu; -// else -// Process_Info->cpu = 0; -// Process_Info->ppid = ppid; -// Process_Info->birth = *birth; - Resource_Info->trace_num = trace_num; - Resource_Info->type = type; - Resource_Info->id = id; - - /* When we create it from before state update, we are sure that the - * last event occured before the beginning of the global area. - * - * If it is created after state update, this value (0) will be - * overriden by the new state before anything is drawn. - * - * There are 3 potential lines for the each process: one in the middle, - * one under it and one over it. The {over,middle,under} fields tell us - * the x pixel on the pixmap where we are. The _used fields tell us - * whether that pixel was used. The _marked field tells us if we marked a - * conflict point. - */ - hashed_resource_data->x.over = 0; - hashed_resource_data->x.over_used = FALSE; - hashed_resource_data->x.over_marked = FALSE; - hashed_resource_data->x.middle = 0; // last - hashed_resource_data->x.middle_used = FALSE; - hashed_resource_data->x.middle_marked = FALSE; - hashed_resource_data->x.under = 0; - hashed_resource_data->x.under_used = FALSE; - hashed_resource_data->x.under_marked = FALSE; - hashed_resource_data->next_good_time = ltt_time_zero; - - /* Add a new row to the model */ - gtk_list_store_append ( process_list->list_store, - &hashed_resource_data->y_iter); + gdk_draw_rectangle (data->pixmap, + resourceview_data->drawing->drawing_area->style->black_gc, + TRUE, + 0, 0, + resourceview_data->drawing->alloc_width, + data->height); + + /* add to hash table */ + g_hash_table_insert(ht, ru, data); + resourceview_data->process_list->number_of_process++; // TODO: check + + /* add to process list */ + { + gchar *str; + str = g_strdup_printf("Trace %u", id); + name = g_quark_from_string(str); + g_free(str); + } + + gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, NULL); + gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, + NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, + -1); + + update_index_to_pixmap(resourceview_data->process_list); + + int heightall = data->height * resourceview_data->process_list->number_of_process; + + gtk_widget_set_size_request(resourceview_data->drawing->drawing_area, + -1, + heightall); - gtk_list_store_set ( process_list->list_store, &hashed_resource_data->y_iter, - NAME_COLUMN, g_quark_to_string(name), - -1); + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); + } + + gtk_tree_view_expand_all(resourceview_data->process_list->process_list_widget); + + return data; +} + +HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); + HashedResourceData *data = g_new(HashedResourceData, 1); - g_hash_table_insert(process_list->process_hash, - (gpointer)Resource_Info, - (gpointer)hashed_resource_data); + /* Prepare hash key */ + ru->trace_num = trace_num; + ru->id = id; - process_list->number_of_process++; // of resources + /* Search within hash table */ + GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_CPU].hash_table; + data = g_hash_table_lookup(ht, ru); + + /* If not found in hash table, add it */ + if(data == NULL) { + GQuark name; + HashedResourceData *parent; + + /* Find the parent machine */ + parent = resourcelist_obtain_machine(resourceview_data, trace_num, trace_num); + + /* Prepare hashed data */ + data = g_malloc(sizeof(HashedResourceData)); + + data->type = RV_RESOURCE_CPU; + data->x.over = 0; + data->x.over_used = FALSE; + data->x.over_marked = FALSE; + data->x.middle = 0; // last + data->x.middle_used = FALSE; + data->x.middle_marked = FALSE; + data->x.under = 0; + data->x.under_used = FALSE; + data->x.under_marked = FALSE; + data->next_good_time = ltt_time_zero; + + data->height = resourceview_data->process_list->cell_height; + data->pixmap = + gdk_pixmap_new(resourceview_data->drawing->drawing_area->window, + resourceview_data->drawing->alloc_width, + data->height, + -1); + + gdk_draw_rectangle (data->pixmap, + resourceview_data->drawing->drawing_area->style->black_gc, + TRUE, + 0, 0, + resourceview_data->drawing->alloc_width, + data->height); - hashed_resource_data->height = process_list->cell_height; + /* add to hash table */ + g_hash_table_insert(ht, ru, data); + resourceview_data->process_list->number_of_process++; // TODO: check - g_assert(hashed_resource_data->height != 0); + /* add to process list */ + { + gchar *str; + str = g_strdup_printf("CPU%u", id); + name = g_quark_from_string(str); + g_free(str); + } - *height = hashed_resource_data->height * process_list->number_of_process; + gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, &parent->y_iter); + gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, + NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, + -1); - hashed_resource_data->pixmap = - gdk_pixmap_new(drawing->drawing_area->window, - drawing->alloc_width, - hashed_resource_data->height, - -1); + update_index_to_pixmap(resourceview_data->process_list); + + int heightall = data->height * resourceview_data->process_list->number_of_process; + + gtk_widget_set_size_request(resourceview_data->drawing->drawing_area, + -1, + heightall); + + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); + } + + return data; +} + +HashedResourceData *resourcelist_obtain_irq(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); + HashedResourceData *data = g_new(HashedResourceData, 1); + + /* Prepare hash key */ + ru->trace_num = trace_num; + ru->id = id; - // Clear the image with black background - gdk_draw_rectangle (hashed_resource_data->pixmap, - drawing->drawing_area->style->black_gc, + /* Search within hash table */ + GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_IRQ].hash_table; + data = g_hash_table_lookup(ht, ru); + + /* If not found in hash table, add it */ + if(data == NULL) { + GQuark name; + HashedResourceData *parent; + + /* Find the parent machine */ + parent = resourcelist_obtain_machine(resourceview_data, trace_num, trace_num); + + /* Prepare hashed data */ + data = g_malloc(sizeof(HashedResourceData)); + + data->type = RV_RESOURCE_IRQ; + data->x.over = 0; + data->x.over_used = FALSE; + data->x.over_marked = FALSE; + data->x.middle = 0; // last + data->x.middle_used = FALSE; + data->x.middle_marked = FALSE; + data->x.under = 0; + data->x.under_used = FALSE; + data->x.under_marked = FALSE; + data->next_good_time = ltt_time_zero; + + data->height = resourceview_data->process_list->cell_height; + data->pixmap = + gdk_pixmap_new(resourceview_data->drawing->drawing_area->window, + resourceview_data->drawing->alloc_width, + data->height, + -1); + + gdk_draw_rectangle (data->pixmap, + resourceview_data->drawing->drawing_area->style->black_gc, TRUE, 0, 0, - drawing->alloc_width, - hashed_resource_data->height); + resourceview_data->drawing->alloc_width, + data->height); - update_index_to_pixmap(process_list); + /* add to hash table */ + g_hash_table_insert(ht, ru, data); + resourceview_data->process_list->number_of_process++; // TODO: check - return 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 **pm_process_info, -// HashedResourceData **pm_hashed_process_data) -//{ -// ResourceInfo *Process_Info = g_new(ResourceInfo, 1); -// HashedResourceData *hashed_process_data = g_new(HashedResourceData, 1); -// *pm_hashed_process_data = hashed_process_data; -// *pm_process_info = Process_Info; -// -// Process_Info->pid = pid; -// Process_Info->tgid = tgid; -// if(pid == 0) -// Process_Info->cpu = cpu; -// else -// Process_Info->cpu = 0; -// Process_Info->ppid = ppid; -// Process_Info->birth = *birth; -// Process_Info->trace_num = trace_num; -// -// /* When we create it from before state update, we are sure that the -// * last event occured before the beginning of the global area. -// * -// * If it is created after state update, this value (0) will be -// * overriden by the new state before anything is drawn. -// */ -// hashed_process_data->x.over = 0; -// hashed_process_data->x.over_used = FALSE; -// hashed_process_data->x.over_marked = FALSE; -// hashed_process_data->x.middle = 0; -// hashed_process_data->x.middle_used = FALSE; -// hashed_process_data->x.middle_marked = FALSE; -// hashed_process_data->x.under = 0; -// hashed_process_data->x.under_used = FALSE; -// hashed_process_data->x.under_marked = FALSE; -// hashed_process_data->next_good_time = ltt_time_zero; -// -// /* Add a new row to the model */ -// gtk_list_store_append ( process_list->list_store, -// &hashed_process_data->y_iter); -// -// gtk_list_store_set ( process_list->list_store, &hashed_process_data->y_iter, -// PROCESS_COLUMN, g_quark_to_string(name), -// BRAND_COLUMN, g_quark_to_string(brand), -// PID_COLUMN, pid, -// TGID_COLUMN, tgid, -// PPID_COLUMN, ppid, -// CPU_COLUMN, cpu, -// BIRTH_S_COLUMN, birth->tv_sec, -// BIRTH_NS_COLUMN, birth->tv_nsec, -// TRACE_COLUMN, trace_num, -// -1); -// //gtk_tree_view_set_model(GTK_TREE_VIEW(process_list->process_list_widget), -// // GTK_TREE_MODEL(process_list->list_store)); -// //gtk_container_resize_children(GTK_CONTAINER(process_list->process_list_widget)); -// -// g_hash_table_insert(process_list->process_hash, -// (gpointer)Process_Info, -// (gpointer)hashed_process_data); -// -// process_list->number_of_process++; -// -// hashed_process_data->height = process_list->cell_height; -// -// g_assert(hashed_process_data->height != 0); -// -// *height = hashed_process_data->height * process_list->number_of_process; -// -// hashed_process_data->pixmap = -// gdk_pixmap_new(drawing->drawing_area->window, -// drawing->alloc_width, -// hashed_process_data->height, -// -1); -// -// // Clear the image -// gdk_draw_rectangle (hashed_process_data->pixmap, -// drawing->drawing_area->style->black_gc, -// TRUE, -// 0, 0, -// drawing->alloc_width, -// hashed_process_data->height); -// -// update_index_to_pixmap(process_list); -// -// -// return 0; -//} - -// TODO pmf: make this work once again -//int processlist_remove( ProcessList *process_list, -// guint pid, -// guint cpu, -// LttTime *birth, -// guint trace_num) -//{ -// ResourceInfo process_info; -// HashedResourceData *hashed_process_data; -// GtkTreeIter iter; -// -// process_info.pid = pid; -// if(pid == 0) -// process_info.cpu = cpu; -// else -// process_info.cpu = 0; -// process_info.birth = *birth; -// process_info.trace_num = trace_num; -// -// -// hashed_process_data = -// (HashedResourceData*)g_hash_table_lookup( -// process_list->process_hash, -// &process_info); -// if(likely(hashed_process_data != NULL)) -// { -// iter = hashed_process_data->y_iter; -// -// gtk_list_store_remove (process_list->list_store, &iter); -// -// g_hash_table_remove(process_list->process_hash, -// &process_info); -// -// if(likely(process_list->current_hash_data != NULL)) { -// if(likely(hashed_process_data == process_list->current_hash_data[trace_num][cpu])) { -// process_list->current_hash_data[trace_num][cpu] = NULL; -// } -// } -// -// gdk_pixmap_unref(hashed_process_data->pixmap); -// -// update_index_to_pixmap(process_list); -// -// process_list->number_of_process--; -// -// return 0; -// } else { -// return 1; -// } -//} + /* add to process list */ + { + gchar *str; + str = g_strdup_printf("IRQ %u", id); + name = g_quark_from_string(str); + g_free(str); + } + + gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, &parent->y_iter); + gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, + NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, + -1); + + update_index_to_pixmap(resourceview_data->process_list); + int heightall = data->height * resourceview_data->process_list->number_of_process; + + gtk_widget_set_size_request(resourceview_data->drawing->drawing_area, + -1, + heightall); + + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); + } + + return data; +} -#if 0 -static inline guint get_cpu_number_from_name(GQuark name) +HashedResourceData *resourcelist_obtain_bdev(ControlFlowData *resourceview_data, guint trace_num, guint id) { - const gchar *string; - char *begin; - guint cpu; + ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); + HashedResourceData *data = g_new(HashedResourceData, 1); + + /* Prepare hash key */ + ru->trace_num = trace_num; + ru->id = id; + + /* Search within hash table */ + GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_BDEV].hash_table; + data = g_hash_table_lookup(ht, ru); + + /* If not found in hash table, add it */ + if(data == NULL) { + GQuark name; + HashedResourceData *parent; + + /* Find the parent machine */ + parent = resourcelist_obtain_machine(resourceview_data, trace_num, trace_num); + + /* Prepare hashed data */ + data = g_malloc(sizeof(HashedResourceData)); + + data->type = RV_RESOURCE_BDEV; + data->x.over = 0; + data->x.over_used = FALSE; + data->x.over_marked = FALSE; + data->x.middle = 0; // last + data->x.middle_used = FALSE; + data->x.middle_marked = FALSE; + data->x.under = 0; + data->x.under_used = FALSE; + data->x.under_marked = FALSE; + data->next_good_time = ltt_time_zero; + + data->height = resourceview_data->process_list->cell_height; + data->pixmap = + gdk_pixmap_new(resourceview_data->drawing->drawing_area->window, + resourceview_data->drawing->alloc_width, + data->height, + -1); - string = g_quark_to_string(name); + gdk_draw_rectangle (data->pixmap, + resourceview_data->drawing->drawing_area->style->black_gc, + TRUE, + 0, 0, + resourceview_data->drawing->alloc_width, + data->height); - begin = strrchr(string, '/'); - begin++; + /* add to hash table */ + g_hash_table_insert(ht, ru, data); + resourceview_data->process_list->number_of_process++; // TODO: check - g_assert(begin != '\0'); + /* add to process list */ + { + gchar *str; + str = g_strdup_printf("Block (%u,%u)", MAJOR(id), MINOR(id)); + name = g_quark_from_string(str); + g_free(str); + } - cpu = strtoul(begin, NULL, 10); + gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, &parent->y_iter); + gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, + NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, + -1); + + update_index_to_pixmap(resourceview_data->process_list); + + int heightall = data->height * resourceview_data->process_list->number_of_process; + + gtk_widget_set_size_request(resourceview_data->drawing->drawing_area, + -1, + heightall); + + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); + } - return cpu; + return data; } -#endif //0 diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h index a68df007..e8f5a849 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.h @@ -25,6 +25,7 @@ #include #include "drawitem.h" +#include "cfv.h" /* The process list * @@ -39,23 +40,37 @@ * */ +/* Unique identifiers for resource types */ +#define RV_RESOURCE_MACHINE 0 +#define RV_RESOURCE_CPU 1 +#define RV_RESOURCE_IRQ 2 +#define RV_RESOURCE_BDEV 3 +#define RV_RESOURCE_COUNT 4 /* Enumeration of the columns */ enum { NAME_COLUMN, + DATA_COLUMN, N_COLUMNS }; - +/* typedef struct _ResourceInfo { GQuark name; guint trace_num; guint type; guint64 id; } ResourceInfo; +*/ + +typedef struct _ResourceUniqueNumeric { + guint trace_num; + guint id; +} ResourceUniqueNumeric; typedef struct _HashedResourceData { + guint type; GdkPixmap *pixmap; // Pixmap slice containing drawing buffer for the PID gint height; // height of the pixmap @@ -79,15 +94,24 @@ typedef struct _HashedResourceData { } HashedResourceData; +struct _ResourceType { + /* functions for the hash table below */ + guint (*hashfunc)(gconstpointer); + gboolean (*hashequalfunc)(gconstpointer,gconstpointer); + /* a hashtable containing the data of each resource of this type */ + GHashTable *hash_table; +}; +typedef struct _ResourceType ResourceType; + struct _ProcessList { GtkWidget *process_list_widget; - GtkListStore *list_store; + GtkTreeStore *list_store; GtkWidget *button; /* one button of the tree view */ GtkCellRenderer *renderer; /* A hash table by PID to speed up process position find in the list */ - GHashTable *process_hash; +// GHashTable *process_hash; guint number_of_process; gint cell_height; @@ -99,10 +123,18 @@ struct _ProcessList { * every time the process list is reordered, process added or removed */ GPtrArray * index_to_pixmap; + ResourceType restypes[RV_RESOURCE_COUNT]; }; +typedef struct _UpdateIndexPixmapArg { + ProcessList *process_list; + guint count; +} UpdateIndexPixmapArg; +#ifndef TYPE_PROCESSLIST_DEFINED +#define TYPE_PROCESSLIST_DEFINED typedef struct _ProcessList ProcessList; +#endif //TYPE_PROCESSLIST_DEFINED #ifndef TYPE_DRAWING_T_DEFINED @@ -118,9 +150,9 @@ void processlist_clear(ProcessList *process_list); // out : success (0) and height /* CPU num is only used for PID 0 */ -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); +//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, GQuark parent); // out : success (0) and height int processlist_remove(ProcessList *process_list, guint pid, guint cpu, @@ -168,7 +200,6 @@ void copy_pixmap_to_screen(ProcessList *process_list, gint x, gint y, gint width, gint height); - static inline gint get_cell_height(GtkTreeView *TreeView) { gint height; @@ -191,26 +222,26 @@ static inline guint processlist_get_height(ProcessList *process_list) } -static inline HashedResourceData *processlist_get_process_data( - ProcessList *process_list, GQuark resource_name, guint trace_num) -{ - ResourceInfo resource_info; - -// process_info.pid = pid; -// if(pid == 0) -// process_info.cpu = cpu; -// else -// process_info.cpu = ANY_CPU; -// process_info.birth = *birth; -// process_info.trace_num = trace_num; - resource_info.name = resource_name; - resource_info.trace_num = trace_num; - - return (HashedResourceData*)g_hash_table_lookup( - process_list->process_hash, - &resource_info); -} - +//static inline HashedResourceData *processlist_get_process_data( +// ProcessList *process_list, GQuark resource_name, guint trace_num) +//{ +// ResourceInfo resource_info; +// +//// process_info.pid = pid; +//// if(pid == 0) +//// process_info.cpu = cpu; +//// else +//// process_info.cpu = ANY_CPU; +//// process_info.birth = *birth; +//// process_info.trace_num = trace_num; +// resource_info.name = resource_name; +// resource_info.trace_num = trace_num; +// +// return (HashedResourceData*)g_hash_table_lookup( +// process_list->process_hash, +// &resource_info); +//} +// static inline gint processlist_get_pixels_from_data( ProcessList *process_list, HashedResourceData *hashed_process_data, @@ -238,18 +269,30 @@ static inline guint processlist_get_index_from_data(ProcessList *process_list, gint *path_indices; GtkTreePath *tree_path; guint ret; + gint depth; tree_path = gtk_tree_model_get_path((GtkTreeModel*)process_list->list_store, &hashed_process_data->y_iter); path_indices = gtk_tree_path_get_indices (tree_path); + depth = gtk_tree_path_get_depth(tree_path); +// ret = path_indices[1]+path_indices[0]+1; ret = path_indices[0]; + if(depth>1) + ret+= 1+path_indices[1]; gtk_tree_path_free(tree_path); return ret; } +/* Return the hash table used to store the data of each resource of a given resource type */ + +static inline GHashTable *resourcelist_get_resource_hash_table(ControlFlowData *resourceview_data, guint type) +{ + return resourceview_data->process_list->restypes[type].hash_table; +} + #endif // _PROCESS_LIST_H -- 2.34.1