X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Fresourceview%2Feventhooks.c;h=432931c8f7bf2bd5679c10d31ec296474f97d429;hb=a53e6234cf0a2b52fd395a3dbf297f97914ff57d;hp=953a92897faa5bb086ebcdc63b1bcb032f37c2c5;hpb=c4e6f4dcd943f5fc42a6f903c2ca336a343a4624;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c index 953a9289..432931c8 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/eventhooks.c @@ -185,12 +185,12 @@ static void request_background_data(ControlFlowData *control_flow_data) * @return The widget created. */ GtkWidget * -h_guicontrolflow(LttvPlugin *plugin) +h_resourceview(LttvPlugin *plugin) { LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin); Tab *tab = ptab->tab; g_info("h_guicontrolflow, %p", tab); - ControlFlowData *control_flow_data = guicontrolflow(ptab); + ControlFlowData *control_flow_data = resourceview(ptab); control_flow_data->tab = tab; @@ -277,7 +277,6 @@ static inline PropertiesLine prepare_s_e_line(LttvProcessState *process) prop_line.line_width = STATE_LINE_WIDTH; prop_line.style = GDK_LINE_SOLID; prop_line.y = MIDDLE; - //GdkColormap *colormap = gdk_colormap_get_system(); if(process->state->s == LTTV_STATE_RUN) { if(process->state->t == LTTV_STATE_USER_MODE) @@ -318,6 +317,71 @@ static inline PropertiesLine prepare_s_e_line(LttvProcessState *process) } +static void cpu_set_line_color(PropertiesLine *prop_line, LttvCPUState *s) +{ + GQuark present_state; + + if(s->mode_stack->len == 0) + present_state = LTTV_CPU_UNKNOWN; + else + present_state = ((GQuark*)s->mode_stack->data)[s->mode_stack->len-1]; + + if(present_state == LTTV_CPU_IDLE) { + prop_line->color = drawing_colors_cpu[COL_CPU_IDLE]; + } + else if(present_state == LTTV_CPU_BUSY) { + prop_line->color = drawing_colors_cpu[COL_CPU_BUSY]; + } + else if(present_state == LTTV_CPU_IRQ) { + prop_line->color = drawing_colors_cpu[COL_CPU_IRQ]; + } + else if(present_state == LTTV_CPU_TRAP) { + prop_line->color = drawing_colors_cpu[COL_CPU_TRAP]; + } else { + prop_line->color = drawing_colors_cpu[COL_CPU_UNKNOWN]; + } +} + +static void irq_set_line_color(PropertiesLine *prop_line, LttvIRQState *s) +{ + GQuark present_state; + if(s->mode_stack->len == 0) + present_state = LTTV_IRQ_UNKNOWN; + else + present_state = ((GQuark*)s->mode_stack->data)[s->mode_stack->len-1]; + + if(present_state == LTTV_IRQ_IDLE) { + prop_line->color = drawing_colors_irq[COL_IRQ_IDLE]; + } + else if(present_state == LTTV_IRQ_BUSY) { + prop_line->color = drawing_colors_irq[COL_IRQ_BUSY]; + } + else { + prop_line->color = drawing_colors_irq[COL_IRQ_UNKNOWN]; + } +} + +static void bdev_set_line_color(PropertiesLine *prop_line, LttvBdevState *s) +{ + GQuark present_state; + if(s == 0 || s->mode_stack->len == 0) + present_state = LTTV_BDEV_UNKNOWN; + else + present_state = ((GQuark*)s->mode_stack->data)[s->mode_stack->len-1]; + + if(present_state == LTTV_BDEV_IDLE) { + prop_line->color = drawing_colors_bdev[COL_BDEV_IDLE]; + } + else if(present_state == LTTV_BDEV_BUSY_READING) { + prop_line->color = drawing_colors_bdev[COL_BDEV_BUSY_READING]; + } + else if(present_state == LTTV_BDEV_BUSY_WRITING) { + prop_line->color = drawing_colors_bdev[COL_BDEV_BUSY_WRITING]; + } + else { + prop_line->color = drawing_colors_bdev[COL_BDEV_UNKNOWN]; + } +} /* before_schedchange_hook * @@ -355,6 +419,8 @@ int before_schedchange_hook(void *hook_data, void *call_data) LttTime evtime = ltt_event_time(e); LttvFilter *filter = control_flow_data->filter; + GQuark cpuq; + /* 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 * time to do it. @@ -362,17 +428,17 @@ int before_schedchange_hook(void *hook_data, void *call_data) guint pid_out; guint pid_in; - { - pid_out = ltt_event_get_long_unsigned(e, thf->f1); - pid_in = ltt_event_get_long_unsigned(e, thf->f2); - } + pid_out = ltt_event_get_long_unsigned(e, thf->f1); + pid_in = ltt_event_get_long_unsigned(e, thf->f2); +// if(pid_in != 0 && pid_out != 0) { +// /* not a transition to/from idle */ +// return 0; +// } - g_debug("a"); - 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)) { +// 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 @@ -380,44 +446,48 @@ int before_schedchange_hook(void *hook_data, void *call_data) * 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]; +// 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->pid != pid_out) +// process = lttv_state_find_process(ts, +// tfs->cpu, pid_out); - if(process != NULL) { +// 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; - HashedProcessData *hashed_process_data = NULL; + HashedResourceData *hashed_process_data = NULL; ProcessList *process_list = control_flow_data->process_list; - LttTime birth = process->creation_time; +// LttTime birth = process->creation_time; - hashed_process_data = processlist_get_process_data(process_list, - pid_out, - process->cpu, - &birth, - trace_num); + 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); +// g_assert(pid_out == 0 || pid_out != process->ppid); /* Process not present */ - ProcessInfo *process_info; + ResourceInfo *process_info; Drawing_t *drawing = control_flow_data->drawing; resourcelist_add(process_list, drawing, -// pid_out, -// process->tgid, -// process->cpu, -// process->ppid, -// &birth, -// trace_num, - process->name, -// process->brand, + trace_num, + cpuq, //process->name, + 0, //cpu + cpu, &pl_height, &process_info, &hashed_process_data); @@ -478,7 +548,6 @@ int before_schedchange_hook(void *hook_data, void *call_data) 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) @@ -517,7 +586,12 @@ int before_schedchange_hook(void *hook_data, void *call_data) { /* Draw the line */ - PropertiesLine prop_line = prepare_s_e_line(process); + //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); } @@ -531,176 +605,177 @@ int before_schedchange_hook(void *hook_data, void *call_data) &hashed_process_data->next_good_time); } } - } - } - - 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; - HashedProcessData *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, - pid_in, - tfs->cpu, - &birth, - trace_num); - if(hashed_process_data == NULL) - { - g_assert(pid_in == 0 || pid_in != process->ppid); - /* Process not present */ - ProcessInfo *process_info; - Drawing_t *drawing = control_flow_data->drawing; - processlist_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; +// } +// } + +// 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; @@ -761,11 +836,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; - HashedProcessData *hashed_process_data_in = NULL; + HashedResourceData *hashed_process_data_in = NULL; ProcessList *process_list = control_flow_data->process_list; @@ -781,6 +858,12 @@ 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. */ @@ -789,27 +872,24 @@ 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, - pid_in, - process_in->cpu, - &birth, - trace_num); + 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); - ProcessInfo *process_info; + ResourceInfo *process_info; Drawing_t *drawing = control_flow_data->drawing; /* Process not present */ - processlist_add(process_list, + resourcelist_add(process_list, drawing, - pid_in, - process_in->tgid, - process_in->cpu, - process_in->ppid, - &birth, trace_num, - process_in->name, - process_in->brand, + cpuq, + 0, + cpu, &pl_height, &process_info, &hashed_process_data_in); @@ -852,9 +932,6 @@ int after_schedchange_hook(void *hook_data, void *call_data) return 0; } - - - /* before_execmode_hook * * This function basically draw lines and icons. Two types of lines are drawn : @@ -872,7 +949,6 @@ int after_schedchange_hook(void *hook_data, void *call_data) * process. */ - int before_execmode_hook(void *hook_data, void *call_data) { LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; @@ -882,20 +958,17 @@ int before_execmode_hook(void *hook_data, void *call_data) LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; LttvTracefileState *tfs = (LttvTracefileState *)call_data; - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; LttEvent *e; e = ltt_tracefile_get_event(tfc->tf); - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; - LttTime evtime = ltt_event_time(e); + GQuark cpuq; + + before_execmode_hook_irq(hook_data, call_data); + /* we are in a execmode, before the state update. We must draw the * items corresponding to the state before it changes : now is the right * time to do it. @@ -903,48 +976,51 @@ int before_execmode_hook(void *hook_data, void *call_data) /* 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; +// 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; - HashedProcessData *hashed_process_data = NULL; + 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, - pid, - process->cpu, - &birth, - trace_num); + 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); - ProcessInfo *process_info; + //g_assert(pid == 0 || pid != process->ppid); + ResourceInfo *process_info; /* Process not present */ Drawing_t *drawing = control_flow_data->drawing; - processlist_add(process_list, - drawing, - pid, - process->tgid, - process->cpu, - process->ppid, - &birth, - trace_num, - process->name, - process->brand, - &pl_height, - &process_info, - &hashed_process_data); + 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); @@ -988,7 +1064,8 @@ int before_execmode_hook(void *hook_data, void *call_data) COLLISION_POSITION(hashed_process_data->height)); hashed_process_data->x.middle_marked = TRUE; } - } else { + } + else { TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab); @@ -1022,7 +1099,8 @@ int before_execmode_hook(void *hook_data, void *call_data) hashed_process_data->x.middle_marked = TRUE; } /* jump */ - } else { + } + else { DrawContext draw_context; /* Now create the drawing context that will be used to draw @@ -1046,9 +1124,12 @@ int before_execmode_hook(void *hook_data, void *call_data) { /* 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; @@ -1064,96 +1145,107 @@ int before_execmode_hook(void *hook_data, void *call_data) return 0; } -/* before_process_exit_hook - * - * Draw lines for process event. - * - * @param hook_data ControlFlowData structure of the viewer. - * @param call_data Event context. - * - * This function adds items to be drawn in a queue for each process. - * - */ - - -int before_process_exit_hook(void *hook_data, void *call_data) +int before_execmode_hook_irq(void *hook_data, void *call_data) { LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; EventsRequest *events_request = (EventsRequest*)thf->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; LttvTracefileState *tfs = (LttvTracefileState *)call_data; - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; LttEvent *e; e = ltt_tracefile_get_event(tfc->tf); - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; - LttTime evtime = ltt_event_time(e); - /* Add process to process list (if not present) */ - //LttvProcessState *process = tfs->process; + GQuark resourceq; + + /* we are in a execmode, before the state update. We must draw the + * items corresponding to the state before it changes : now is the right + * time to do it. + */ + /* For the pid */ + + guint64 irq; guint cpu = tfs->cpu; - guint trace_num = ts->parent.index; - LttvProcessState *process = ts->running_process[cpu]; - guint pid = process->pid; - LttTime birth; - guint pl_height = 0; - HashedProcessData *hashed_process_data = NULL; - ProcessList *process_list = control_flow_data->process_list; - - g_assert(process != NULL); + LttFacility *ev_facility = ltt_event_facility(e); + if(ltt_facility_name(ev_facility) != LTT_FACILITY_KERNEL) + return 0; + guint8 ev_id_entry = ltt_eventtype_id(ltt_facility_eventtype_get_by_name(ev_facility, LTT_EVENT_IRQ_ENTRY)); + guint8 ev_id_exit = ltt_eventtype_id(ltt_facility_eventtype_get_by_name(ev_facility, LTT_EVENT_IRQ_EXIT)); + if(ltt_facility_name(ev_facility) == LTT_FACILITY_KERNEL && + ev_id_entry == ltt_event_eventtype_id(e)) { + irq = ltt_event_get_long_unsigned(e, thf->f1); + } + else if(ltt_facility_name(ev_facility) == LTT_FACILITY_KERNEL && + ev_id_exit == ltt_event_eventtype_id(e)) { + irq = ts->cpu_states[cpu].last_irq; + } + else { + return 0; + } + + { + gchar *irqstr; + irqstr = g_strdup_printf("IRQ %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; - birth = process->creation_time; +// guint pid = process->pid; - 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, - pid, - process->cpu, - &birth, - trace_num); + /* 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); + //g_assert(pid == 0 || pid != process->ppid); + ResourceInfo *process_info; /* Process not present */ Drawing_t *drawing = control_flow_data->drawing; - ProcessInfo *process_info; - processlist_add(process_list, - drawing, - pid, - process->tgid, - process->cpu, - process->ppid, - &birth, - trace_num, - process->name, - process->brand, - &pl_height, - &process_info, - &hashed_process_data); - gtk_widget_set_size_request(drawing->drawing_area, - -1, - pl_height); - gtk_widget_queue_draw(drawing->drawing_area); - } - } + resourcelist_add(process_list, + drawing, + trace_num, + resourceq, //process->name, + 1, //irq + irq, + &pl_height, + &process_info, + &hashed_process_data); + gtk_widget_set_size_request(drawing->drawing_area, + -1, + pl_height); + gtk_widget_queue_draw(drawing->drawing_area); + } + /* Set the current process */ +// process_list->current_hash_data[trace_num][process->cpu] = +// hashed_process_data; +// } /* Now, the process is in the state hash and our own process hash. * We definitely can draw the items related to the ending state. */ - + if(likely(ltt_time_compare(hashed_process_data->next_good_time, evtime) > 0)) { @@ -1183,7 +1275,8 @@ int before_process_exit_hook(void *hook_data, void *call_data) COLLISION_POSITION(hashed_process_data->height)); hashed_process_data->x.middle_marked = TRUE; } - } else { + } + else { TimeWindow time_window = lttvwindow_get_time_window(control_flow_data->tab); @@ -1205,8 +1298,8 @@ int before_process_exit_hook(void *hook_data, void *call_data) /* Jump over draw if we are at the same x position */ if(unlikely(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used)) - { + hashed_process_data->x.middle_used)) + { if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { /* Draw collision indicator */ gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); @@ -1217,592 +1310,53 @@ int before_process_exit_hook(void *hook_data, void *call_data) hashed_process_data->x.middle_marked = TRUE; } /* jump */ - } else { - DrawContext draw_context; + } + else { + DrawContext draw_context; /* Now create the drawing context that will be used to draw * items related to the last state. */ draw_context.drawable = hashed_process_data->pixmap; draw_context.gc = drawing->gc; draw_context.pango_layout = drawing->pango_layout; - draw_context.drawinfo.start.x = hashed_process_data->x.middle; - draw_context.drawinfo.end.x = x; - - draw_context.drawinfo.y.over = 1; - draw_context.drawinfo.y.middle = (hashed_process_data->height/2); - draw_context.drawinfo.y.under = hashed_process_data->height; - - draw_context.drawinfo.start.offset.over = 0; - draw_context.drawinfo.start.offset.middle = 0; - draw_context.drawinfo.start.offset.under = 0; - draw_context.drawinfo.end.offset.over = 0; - draw_context.drawinfo.end.offset.middle = 0; - draw_context.drawinfo.end.offset.under = 0; - - { - /* Draw the line */ - PropertiesLine prop_line = prepare_s_e_line(process); - draw_line((void*)&prop_line, (void*)&draw_context); - - } - /* become the last x position */ - hashed_process_data->x.middle = x; - hashed_process_data->x.middle_used = TRUE; - hashed_process_data->x.middle_marked = FALSE; - - /* Calculate the next good time */ - convert_pixels_to_time(width, x+1, time_window, - &hashed_process_data->next_good_time); - } - } - - return 0; - -} - - - -/* before_process_release_hook - * - * Draw lines for process event. - * - * @param hook_data ControlFlowData structure of the viewer. - * @param call_data Event context. - * - * This function adds items to be drawn in a queue for each process. - * - */ - - -int before_process_release_hook(void *hook_data, void *call_data) -{ - LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; - EventsRequest *events_request = (EventsRequest*)thf->hook_data; - - ControlFlowData *control_flow_data = events_request->viewer_data; - - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; - - LttEvent *e; - e = ltt_tracefile_get_event(tfc->tf); - - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; - - LttTime evtime = ltt_event_time(e); - - guint trace_num = ts->parent.index; - - guint pid; - { - pid = ltt_event_get_long_unsigned(e, thf->f1); - } - - /* Add process to process list (if not present) */ - /* Don't care about the process if it's not in the state hash already : - * that means a process that has never done anything in the trace and - * unknown suddently gets destroyed : no state meaningful to show. */ - LttvProcessState *process = lttv_state_find_process(ts, ANY_CPU, pid); - - if(process != NULL) { - LttTime birth; - guint pl_height = 0; - HashedProcessData *hashed_process_data = NULL; - - ProcessList *process_list = control_flow_data->process_list; - - birth = process->creation_time; - - /* Cannot use current process : this event happens on another process, - * action done by the parent. */ - 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); - /* Process not present */ - Drawing_t *drawing = control_flow_data->drawing; - ProcessInfo *process_info; - processlist_add(process_list, - drawing, - pid, - process->tgid, - process->cpu, - process->ppid, - &birth, - trace_num, - process->name, - process->brand, - &pl_height, - &process_info, - &hashed_process_data); - gtk_widget_set_size_request(drawing->drawing_area, - -1, - pl_height); - gtk_widget_queue_draw(drawing->drawing_area); - } - - /* Now, the process is in the state hash and our own process hash. - * We definitely can draw the items related to the ending state. - */ - - if(likely(ltt_time_compare(hashed_process_data->next_good_time, - evtime) > 0)) - { - if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { - TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); - -#ifdef EXTRA_CHECK - if(ltt_time_compare(evtime, time_window.start_time) == -1 - || ltt_time_compare(evtime, time_window.end_time) == 1) - return; -#endif //EXTRA_CHECK - Drawing_t *drawing = control_flow_data->drawing; - guint width = drawing->width; - guint x; - convert_time_to_pixels( - time_window, - evtime, - width, - &x); - - /* Draw collision indicator */ - gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); - gdk_draw_point(hashed_process_data->pixmap, - drawing->gc, - x, - COLLISION_POSITION(hashed_process_data->height)); - hashed_process_data->x.middle_marked = TRUE; - } - } else { - TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); - -#ifdef EXTRA_CHECK - if(ltt_time_compare(evtime, time_window.start_time) == -1 - || ltt_time_compare(evtime, time_window.end_time) == 1) - return; -#endif //EXTRA_CHECK - Drawing_t *drawing = control_flow_data->drawing; - guint width = drawing->width; - guint x; - - convert_time_to_pixels( - time_window, - evtime, - width, - &x); - - - /* Jump over draw if we are at the same x position */ - if(unlikely(x == hashed_process_data->x.middle && - hashed_process_data->x.middle_used)) - { - if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { - /* Draw collision indicator */ - gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); - gdk_draw_point(hashed_process_data->pixmap, - drawing->gc, - x, - COLLISION_POSITION(hashed_process_data->height)); - hashed_process_data->x.middle_marked = TRUE; - } - /* jump */ - } else { - DrawContext draw_context; - - /* Now create the drawing context that will be used to draw - * items related to the last state. */ - draw_context.drawable = hashed_process_data->pixmap; - draw_context.gc = drawing->gc; - draw_context.pango_layout = drawing->pango_layout; - draw_context.drawinfo.start.x = hashed_process_data->x.middle; - draw_context.drawinfo.end.x = x; - - draw_context.drawinfo.y.over = 1; - draw_context.drawinfo.y.middle = (hashed_process_data->height/2); - draw_context.drawinfo.y.under = hashed_process_data->height; - - draw_context.drawinfo.start.offset.over = 0; - draw_context.drawinfo.start.offset.middle = 0; - draw_context.drawinfo.start.offset.under = 0; - draw_context.drawinfo.end.offset.over = 0; - draw_context.drawinfo.end.offset.middle = 0; - draw_context.drawinfo.end.offset.under = 0; - - { - /* Draw the line */ - PropertiesLine prop_line = prepare_s_e_line(process); - draw_line((void*)&prop_line, (void*)&draw_context); - - } - /* become the last x position */ - hashed_process_data->x.middle = x; - hashed_process_data->x.middle_used = TRUE; - hashed_process_data->x.middle_marked = FALSE; - - /* Calculate the next good time */ - convert_pixels_to_time(width, x+1, time_window, - &hashed_process_data->next_good_time); - } - } - } - - return 0; -} - - - - - -/* after_process_fork_hook - * - * Create the processlist entry for the child process. Put the last - * position in x at the current time value. - * - * @param hook_data ControlFlowData structure of the viewer. - * @param call_data Event context. - * - * This function adds items to be drawn in a queue for each process. - * - */ -int after_process_fork_hook(void *hook_data, void *call_data) -{ - LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; - EventsRequest *events_request = (EventsRequest*)thf->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; - - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; - - LttEvent *e; - e = ltt_tracefile_get_event(tfc->tf); - - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; - - LttTime evtime = ltt_event_time(e); - - guint child_pid; - { - child_pid = ltt_event_get_long_unsigned(e, thf->f2); - } - - /* Add process to process list (if not present) */ - LttvProcessState *process_child; - LttTime birth; - guint pl_height = 0; - HashedProcessData *hashed_process_data_child = NULL; - - ProcessList *process_list = control_flow_data->process_list; - - /* Find child in the list... */ - process_child = lttv_state_find_process(ts, ANY_CPU, child_pid); - /* It should exist, because we are after the state update. */ - g_assert(process_child != NULL); - - birth = process_child->creation_time; - guint trace_num = ts->parent.index; - - /* Cannot use current process, because this action is done by the parent - * on its child. */ - hashed_process_data_child = processlist_get_process_data(process_list, - child_pid, - process_child->cpu, - &birth, - trace_num); - if(likely(hashed_process_data_child == NULL)) - { - g_assert(child_pid == 0 || child_pid != process_child->ppid); - /* Process not present */ - Drawing_t *drawing = control_flow_data->drawing; - ProcessInfo *process_info; - processlist_add(process_list, - drawing, - child_pid, - process_child->tgid, - process_child->cpu, - process_child->ppid, - &birth, - trace_num, - process_child->name, - process_child->brand, - &pl_height, - &process_info, - &hashed_process_data_child); - gtk_widget_set_size_request(drawing->drawing_area, - -1, - pl_height); - gtk_widget_queue_draw(drawing->drawing_area); - } else { - processlist_set_ppid(process_list, process_child->ppid, - hashed_process_data_child); - processlist_set_tgid(process_list, process_child->tgid, - hashed_process_data_child); - } - - - if(likely(ltt_time_compare(hashed_process_data_child->next_good_time, - evtime) <= 0)) - { - 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 new_x; - convert_time_to_pixels( - time_window, - evtime, - width, - &new_x); - - if(likely(hashed_process_data_child->x.over != new_x)) { - hashed_process_data_child->x.over = new_x; - hashed_process_data_child->x.over_used = FALSE; - hashed_process_data_child->x.over_marked = FALSE; - } - if(likely(hashed_process_data_child->x.middle != new_x)) { - hashed_process_data_child->x.middle = new_x; - hashed_process_data_child->x.middle_used = FALSE; - hashed_process_data_child->x.middle_marked = FALSE; - } - if(likely(hashed_process_data_child->x.under != new_x)) { - hashed_process_data_child->x.under = new_x; - hashed_process_data_child->x.under_used = FALSE; - hashed_process_data_child->x.under_marked = FALSE; - } - } - return 0; -} - - - -/* after_process_exit_hook - * - * Create the processlist entry for the child process. Put the last - * position in x at the current time value. - * - * @param hook_data ControlFlowData structure of the viewer. - * @param call_data Event context. - * - * This function adds items to be drawn in a queue for each process. - * - */ -int after_process_exit_hook(void *hook_data, void *call_data) -{ - LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; - EventsRequest *events_request = (EventsRequest*)thf->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; - - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; - - LttEvent *e; - e = ltt_tracefile_get_event(tfc->tf); - - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; - - LttTime evtime = ltt_event_time(e); - - /* Add process to process list (if not present) */ - //LttvProcessState *process = tfs->process; - guint cpu = tfs->cpu; - guint trace_num = ts->parent.index; - LttvProcessState *process = ts->running_process[cpu]; - - /* It should exist, because we are after the state update. */ - g_assert(process != NULL); - - guint pid = process->pid; - LttTime birth; - guint pl_height = 0; - HashedProcessData *hashed_process_data = NULL; - - ProcessList *process_list = control_flow_data->process_list; - - 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, - pid, - process->cpu, - &birth, - trace_num); - if(unlikely(hashed_process_data == NULL)) - { - g_assert(pid == 0 || pid != process->ppid); - /* Process not present */ - Drawing_t *drawing = control_flow_data->drawing; - ProcessInfo *process_info; - processlist_add(process_list, - drawing, - pid, - process->tgid, - process->cpu, - process->ppid, - &birth, - trace_num, - process->name, - process->brand, - &pl_height, - &process_info, - &hashed_process_data); - gtk_widget_set_size_request(drawing->drawing_area, - -1, - pl_height); - gtk_widget_queue_draw(drawing->drawing_area); - } - - /* Set the current process */ - process_list->current_hash_data[trace_num][process->cpu] = - hashed_process_data; - } - - if(unlikely(ltt_time_compare(hashed_process_data->next_good_time, - evtime) <= 0)) - { - 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 new_x; - convert_time_to_pixels( - time_window, - evtime, - width, - &new_x); - if(unlikely(hashed_process_data->x.middle != new_x)) { - hashed_process_data->x.middle = new_x; - hashed_process_data->x.middle_used = FALSE; - hashed_process_data->x.middle_marked = FALSE; - } - } - - return 0; -} - - -/* Get the filename of the process to print */ -int after_fs_exec_hook(void *hook_data, void *call_data) -{ - LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; - EventsRequest *events_request = (EventsRequest*)thf->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; - - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; - - LttEvent *e; - e = ltt_tracefile_get_event(tfc->tf); + draw_context.drawinfo.start.x = hashed_process_data->x.middle; + draw_context.drawinfo.end.x = x; - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; + 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; - guint cpu = tfs->cpu; - guint trace_num = ts->parent.index; - LttvProcessState *process = ts->running_process[cpu]; - g_assert(process != NULL); + 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; - guint pid = process->pid; + { + /* Draw the line */ + PropertiesLine prop_line; + prop_line.line_width = STATE_LINE_WIDTH; + prop_line.style = GDK_LINE_SOLID; + prop_line.y = MIDDLE; + irq_set_line_color(&prop_line, &ts->irq_states[irq]); + draw_line((void*)&prop_line, (void*)&draw_context); + } + /* become the last x position */ + hashed_process_data->x.middle = x; + hashed_process_data->x.middle_used = TRUE; + hashed_process_data->x.middle_marked = FALSE; - /* 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; - HashedProcessData *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, - pid, - process->cpu, - &birth, - trace_num); - if(unlikely(hashed_process_data == NULL)) - { - g_assert(pid == 0 || pid != process->ppid); - ProcessInfo *process_info; - /* Process not present */ - Drawing_t *drawing = control_flow_data->drawing; - processlist_add(process_list, - drawing, - pid, - process->tgid, - process->cpu, - process->ppid, - &birth, - trace_num, - process->name, - process->brand, - &pl_height, - &process_info, - &hashed_process_data); - gtk_widget_set_size_request(drawing->drawing_area, - -1, - pl_height); - gtk_widget_queue_draw(drawing->drawing_area); + /* Calculate the next good time */ + convert_pixels_to_time(width, x+1, time_window, + &hashed_process_data->next_good_time); } - /* Set the current process */ - process_list->current_hash_data[trace_num][process->cpu] = - hashed_process_data; } - - processlist_set_name(process_list, process->name, hashed_process_data); - + return 0; - } -/* Get the filename of the process to print */ -int after_user_generic_thread_brand_hook(void *hook_data, void *call_data) +int before_bdev_event_hook(void *hook_data, void *call_data) { LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; EventsRequest *events_request = (EventsRequest*)thf->hook_data; @@ -1811,192 +1365,198 @@ int after_user_generic_thread_brand_hook(void *hook_data, void *call_data) LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; LttvTracefileState *tfs = (LttvTracefileState *)call_data; - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; LttEvent *e; e = ltt_tracefile_get_event(tfc->tf); - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; + LttTime evtime = ltt_event_time(e); + + GQuark resourceq; + + /* we are in a execmode, before the state update. We must draw the + * items corresponding to the state before it changes : now is the right + * time to do it. + */ + /* For the pid */ guint cpu = tfs->cpu; + guint8 major = ltt_event_get_long_unsigned(e, thf->f1); + guint8 minor = ltt_event_get_long_unsigned(e, thf->f2); + guint oper = ltt_event_get_long_unsigned(e, thf->f3); + 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; - LttvProcessState *process = ts->running_process[cpu]; - g_assert(process != NULL); - guint pid = process->pid; + 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; - HashedProcessData *hashed_process_data = NULL; + HashedResourceData *hashed_process_data = NULL; ProcessList *process_list = control_flow_data->process_list; - LttTime birth = process->creation_time; +// 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, - pid, - process->cpu, - &birth, - trace_num); +// 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); - ProcessInfo *process_info; + //g_assert(pid == 0 || pid != process->ppid); + ResourceInfo *process_info; /* Process not present */ Drawing_t *drawing = control_flow_data->drawing; - processlist_add(process_list, - drawing, - pid, - process->tgid, - process->cpu, - process->ppid, - &birth, - trace_num, - process->name, - process->brand, - &pl_height, - &process_info, - &hashed_process_data); + 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; - } - - processlist_set_brand(process_list, process->brand, hashed_process_data); +// process_list->current_hash_data[trace_num][process->cpu] = +// hashed_process_data; +// } - return 0; - -} + /* Now, the process is in the state hash and our own process hash. + * We definitely can draw the items related to the ending state. + */ + if(likely(ltt_time_compare(hashed_process_data->next_good_time, + evtime) > 0)) + { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { + TimeWindow time_window = + lttvwindow_get_time_window(control_flow_data->tab); -/* after_event_enum_process_hook - * - * Create the processlist entry for the child process. Put the last - * position in x at the current time value. - * - * @param hook_data ControlFlowData structure of the viewer. - * @param call_data Event context. - * - * This function adds items to be drawn in a queue for each process. - * - */ -int after_event_enum_process_hook(void *hook_data, void *call_data) -{ - LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data; - EventsRequest *events_request = (EventsRequest*)thf->hook_data; - ControlFlowData *control_flow_data = events_request->viewer_data; +#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); - LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; + /* 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); - LttvTracefileState *tfs = (LttvTracefileState *)call_data; +#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; - LttvTraceState *ts = (LttvTraceState *)tfc->t_context; + convert_time_to_pixels( + time_window, + evtime, + width, + &x); - guint first_cpu, nb_cpus, cpu; - LttEvent *e; - e = ltt_tracefile_get_event(tfc->tf); + /* Jump over draw if we are at the same x position */ + if(unlikely(x == hashed_process_data->x.middle && + hashed_process_data->x.middle_used)) + { + if(unlikely(hashed_process_data->x.middle_marked == FALSE)) { + /* Draw collision indicator */ + gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]); + gdk_draw_point(hashed_process_data->pixmap, + drawing->gc, + x, + COLLISION_POSITION(hashed_process_data->height)); + hashed_process_data->x.middle_marked = TRUE; + } + /* jump */ + } + else { - LttvFilter *filter = control_flow_data->filter; - if(filter != NULL && filter->head != NULL) - if(!lttv_filter_tree_parse(filter->head,e,tfc->tf, - tfc->t_context->t,tfc,NULL,NULL)) - return FALSE; + 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; - LttTime evtime = ltt_event_time(e); + 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; - /* Add process to process list (if not present) */ - LttvProcessState *process_in; - LttTime birth; - guint pl_height = 0; - HashedProcessData *hashed_process_data_in = NULL; + 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; - ProcessList *process_list = control_flow_data->process_list; - guint trace_num = ts->parent.index; - - guint pid_in; - { - pid_in = ltt_event_get_long_unsigned(e, thf->f1); - } - - if(pid_in == 0) { - first_cpu = 0; - nb_cpus = ltt_trace_get_num_cpu(ts->parent.t); - } else { - first_cpu = ANY_CPU; - nb_cpus = ANY_CPU+1; - } + { + /* Draw the line */ + PropertiesLine prop_line; + prop_line.line_width = STATE_LINE_WIDTH; + prop_line.style = GDK_LINE_SOLID; + prop_line.y = MIDDLE; + bdev_set_line_color(&prop_line, bdev); + 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; - for(cpu = first_cpu; cpu < nb_cpus; cpu++) { - /* Find process pid_in in the list... */ - process_in = lttv_state_find_process(ts, cpu, pid_in); - //process_in = tfs->process; - //guint cpu = tfs->cpu; - //guint trace_num = ts->parent.index; - //process_in = ts->running_process[cpu]; - /* It should exist, because we are after the state update. */ - #ifdef EXTRA_CHECK - //g_assert(process_in != NULL); - #endif //EXTRA_CHECK - birth = process_in->creation_time; - - hashed_process_data_in = processlist_get_process_data(process_list, - pid_in, - process_in->cpu, - &birth, - trace_num); - if(hashed_process_data_in == NULL) - { - if(pid_in != 0 && pid_in == process_in->ppid) - g_critical("TEST %u , %u", pid_in, process_in->ppid); - g_assert(pid_in == 0 || pid_in != process_in->ppid); - ProcessInfo *process_info; - Drawing_t *drawing = control_flow_data->drawing; - /* Process not present */ - processlist_add(process_list, - drawing, - pid_in, - process_in->tgid, - process_in->cpu, - process_in->ppid, - &birth, - trace_num, - process_in->name, - process_in->brand, - &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); - } else { - processlist_set_name(process_list, process_in->name, - hashed_process_data_in); - processlist_set_ppid(process_list, process_in->ppid, - hashed_process_data_in); - processlist_set_tgid(process_list, process_in->tgid, - hashed_process_data_in); + /* Calculate the next good time */ + convert_pixels_to_time(width, x+1, time_window, + &hashed_process_data->next_good_time); } } + return 0; } - gint update_time_window_hook(void *hook_data, void *call_data) { ControlFlowData *control_flow_data = (ControlFlowData*) hook_data; @@ -2394,11 +1954,12 @@ typedef struct _ClosureData { guint x_end; } ClosureData; +/* Draw line until end of the screen */ void draw_closure(gpointer key, gpointer value, gpointer user_data) { - ProcessInfo *process_info = (ProcessInfo*)key; - HashedProcessData *hashed_process_data = (HashedProcessData*)value; + ResourceInfo *process_info = (ResourceInfo*)key; + HashedResourceData *hashed_process_data = (HashedResourceData*)value; ClosureData *closure_data = (ClosureData*)user_data; EventsRequest *events_request = closure_data->events_request; @@ -2443,17 +2004,17 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) // (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); +// LttvProcessState *process; +// process = lttv_state_find_process(ts, process_info->cpu, +// process_info->pid); - if(unlikely(process != NULL)) { +// 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; +// 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 */ @@ -2537,8 +2098,22 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) draw_context.drawinfo.start.x = hashed_process_data->x.middle; /* Draw the line */ if(dodraw) { - PropertiesLine prop_line = prepare_s_e_line(process); - draw_line((void*)&prop_line, (void*)&draw_context); + 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); } /* become the last x position */ @@ -2553,7 +2128,7 @@ void draw_closure(gpointer key, gpointer value, gpointer user_data) } } } - } +// } } return; } @@ -2595,37 +2170,38 @@ 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); +// 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); return 0; }