From c7620c793509802e9bc0b789a5b72b9510bb6b0e Mon Sep 17 00:00:00 2001 From: compudj Date: Wed, 5 Dec 2007 16:54:23 +0000 Subject: [PATCH] fix process end of life git-svn-id: http://ltt.polymtl.ca/svn@2782 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/lttv/lttv/state.c | 44 ++++-- ltt/branches/poly/lttv/lttv/state.h | 1 + .../lttv/modules/gui/controlflow/drawing.c | 1 + .../lttv/modules/gui/controlflow/drawing.h | 1 + .../lttv/modules/gui/controlflow/eventhooks.c | 142 +++++++++--------- 5 files changed, 107 insertions(+), 82 deletions(-) diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index 9034cc0c..c02a3227 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -616,7 +616,7 @@ static void write_process_state(gpointer key, gpointer value, process = (LttvProcessState *)value; fprintf(fp, -" \n", +" \n", process, process->pid, process->tgid, process->ppid, g_quark_to_string(process->type), process->creation_time.tv_sec, @@ -625,7 +625,7 @@ static void write_process_state(gpointer key, gpointer value, process->insertion_time.tv_nsec, g_quark_to_string(process->name), g_quark_to_string(process->brand), - process->cpu); + process->cpu, process->free_events); for(i = 0 ; i < process->execution_stack->len; i++) { es = &g_array_index(process->execution_stack, LttvExecutionState, i); @@ -726,6 +726,7 @@ static void write_process_state_raw(gpointer key, gpointer value, //fputc('\0', fp); fwrite(&process->brand, sizeof(process->brand), 1, fp); fwrite(&process->pid, sizeof(process->pid), 1, fp); + fwrite(&process->free_events, sizeof(process->free_events), 1, fp); fwrite(&process->tgid, sizeof(process->tgid), 1, fp); fwrite(&process->ppid, sizeof(process->ppid), 1, fp); fwrite(&process->cpu, sizeof(process->cpu), 1, fp); @@ -875,6 +876,7 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp, fread(&tmp.name, sizeof(tmp.name), 1, fp); fread(&tmp.brand, sizeof(tmp.brand), 1, fp); fread(&tmp.pid, sizeof(tmp.pid), 1, fp); + fread(&tmp.free_events, sizeof(tmp.free_events), 1, fp); fread(&tmp.tgid, sizeof(tmp.tgid), 1, fp); fread(&tmp.ppid, sizeof(tmp.ppid), 1, fp); fread(&tmp.cpu, sizeof(tmp.cpu), 1, fp); @@ -905,7 +907,7 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp, (gchar*)g_ptr_array_index(quarktable, tmp.brand)); process->name = g_quark_from_string((gchar*)g_ptr_array_index(quarktable, tmp.name)); - + process->free_events = tmp.free_events; do { if(feof(fp) || ferror(fp)) goto end_loop; @@ -2162,6 +2164,7 @@ lttv_state_create_process(LttvTraceState *tcs, LttvProcessState *parent, process->creation_time.tv_nsec); process->pid_time = g_quark_from_string(buffer); process->cpu = cpu; + process->free_events = 0; //process->last_cpu = tfs->cpu_name; //process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf); process->execution_stack = g_array_sized_new(FALSE, FALSE, @@ -2236,17 +2239,23 @@ lttv_state_find_process_or_create(LttvTraceState *ts, guint cpu, guint pid, * has the flag SA_NOCLDWAIT. It can also happen when the child is part * of a killed thread group, but isn't the leader. */ -static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) +static int exit_process(LttvTracefileState *tfs, LttvProcessState *process) { LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context); LttvProcessState key; + /* Wait for both schedule with exit dead and process free to happen. + * They can happen in any order. */ + if (++(process->free_events) < 2) + return 0; + key.pid = process->pid; key.cpu = process->cpu; g_hash_table_remove(ts->processes, &key); g_array_free(process->execution_stack, TRUE); g_array_free(process->user_stack, TRUE); g_free(process); + return 1; } @@ -2669,9 +2678,13 @@ static gboolean schedchange(void *hook_data, void *call_data) process->state->change = s->parent.timestamp; } - if(state_out == 32 || state_out == 64) - exit_process(s, process); /* EXIT_DEAD || TASK_DEAD */ - /* see sched.h for states */ + if(state_out == 32 || state_out == 64) { /* EXIT_DEAD || TASK_DEAD */ + /* see sched.h for states */ + if (!exit_process(s, process)) { + process->state->s = LTTV_STATE_DEAD; + process->state->change = s->parent.timestamp; + } + } } } process = ts->running_process[cpu] = @@ -2800,11 +2813,13 @@ static gboolean process_kernel_thread(void *hook_data, void *call_data) process = lttv_state_find_process_or_create(ts, ANY_CPU, pid, <t_time_zero); - process->execution_stack = - g_array_set_size(process->execution_stack, 1); - es = process->state = - &g_array_index(process->execution_stack, LttvExecutionState, 0); - es->t = LTTV_STATE_SYSCALL; + if (process->state->s != LTTV_STATE_DEAD) { + process->execution_stack = + g_array_set_size(process->execution_stack, 1); + es = process->state = + &g_array_index(process->execution_stack, LttvExecutionState, 0); + es->t = LTTV_STATE_SYSCALL; + } process->type = LTTV_STATE_KERNEL_THREAD; return FALSE; @@ -2848,7 +2863,10 @@ static gboolean process_free(void *hook_data, void *call_data) g_assert(release_pid != 0); process = lttv_state_find_process(ts, ANY_CPU, release_pid); - + if(likely(process != NULL)) + exit_process(s, process); + return FALSE; +//DISABLED if(likely(process != NULL)) { /* release_task is happening at kernel level : we can now safely release * the data structure of the process */ diff --git a/ltt/branches/poly/lttv/lttv/state.h b/ltt/branches/poly/lttv/lttv/state.h index aad7ef4b..7334e781 100644 --- a/ltt/branches/poly/lttv/lttv/state.h +++ b/ltt/branches/poly/lttv/lttv/state.h @@ -260,6 +260,7 @@ typedef struct _LttvProcessState { guint64 current_function; LttvProcessType type; /* kernel thread or user space ? */ guint target_pid; /* target PID of the current event. */ + guint free_events; /* 0 : none, 1 : free or exit dead, 2 : should delete */ } LttvProcessState; #define ANY_CPU 0 /* For clarity sake : a call to lttv_state_find_process for diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c index dbd37dd9..8d670123 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c @@ -78,6 +78,7 @@ GdkColor drawing_colors[NUM_COLORS] = { 0, 0x6400, 0x0000, 0x5D00 }, /* COL_ZOMBIE : dark purple */ { 0, 0x0700, 0x6400, 0x0000 }, /* COL_WAIT_FORK : dark green */ { 0, 0x8900, 0x0000, 0x8400 }, /* COL_EXIT : "less dark" magenta */ + { 0, 0x0000, 0x0000, 0x0000 }, /* COL_DEAD : black */ { 0, 0xFFFF, 0xFFFF, 0xFFFF }, /* COL_MODE_UNKNOWN : white */ { 0, 0xFFFF, 0xFFFF, 0xFFFF } /* COL_UNNAMED : white */ diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h index 58f562a2..3e4b3dc8 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h @@ -46,6 +46,7 @@ typedef enum _draw_color { COL_ZOMBIE, /* dark purple */ COL_WAIT_FORK, /* dark green */ COL_EXIT, /* "less dark" magenta */ + COL_DEAD, /* black */ COL_MODE_UNKNOWN, /* white */ COL_UNNAMED, /* white */ NUM_COLORS } draw_color; diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c b/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c index cde8be6b..cffd9b89 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c @@ -266,6 +266,8 @@ static inline PropertiesLine prepare_s_e_line(LttvProcessState *process) prop_line.color = drawing_colors[COL_EXIT]; } else if(process->state->s == LTTV_STATE_UNNAMED) { prop_line.color = drawing_colors[COL_UNNAMED]; + } else if(process->state->s == LTTV_STATE_DEAD) { + prop_line.color = drawing_colors[COL_DEAD]; } else { g_critical("unknown state : %s", g_quark_to_string(process->state->s)); g_assert(FALSE); /* UNKNOWN STATE */ @@ -319,9 +321,11 @@ int before_schedchange_hook(void *hook_data, void *call_data) guint pid_out; guint pid_in; + guint state_out; { 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)); + state_out = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 2)); } tfc->target_pid = pid_out; @@ -709,11 +713,6 @@ int after_schedchange_hook(void *hook_data, void *call_data) 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) */ @@ -731,79 +730,84 @@ int after_schedchange_hook(void *hook_data, void *call_data) pid_in = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 1)); } - - /* Find process pid_in in the list... */ - //process_in = lttv_state_find_process(ts, ANY_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. */ + 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)) { + /* Find process pid_in in the list... */ + //process_in = lttv_state_find_process(ts, ANY_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); + g_assert(process_in != NULL); #endif //EXTRA_CHECK - birth = process_in->creation_time; - - hashed_process_data_in = processlist_get_process_data(process_list, + 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) + { + 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); - if(hashed_process_data_in == NULL) - { - 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); - } - /* Set the current process */ - process_list->current_hash_data[trace_num][process_in->cpu] = - hashed_process_data_in; - - if(ltt_time_compare(hashed_process_data_in->next_good_time, - evtime) <= 0) - { - TimeWindow time_window = - lttvwindow_get_time_window(control_flow_data->tab); - + 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); + } + /* Set the current process */ + process_list->current_hash_data[trace_num][process_in->cpu] = + hashed_process_data_in; + + if(ltt_time_compare(hashed_process_data_in->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 FALSE; + if(ltt_time_compare(evtime, time_window.start_time) == -1 + || ltt_time_compare(evtime, time_window.end_time) == 1) + return FALSE; #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(hashed_process_data_in->x.middle != new_x) { - hashed_process_data_in->x.middle = new_x; - hashed_process_data_in->x.middle_used = FALSE; - hashed_process_data_in->x.middle_marked = FALSE; + 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(hashed_process_data_in->x.middle != new_x) { + hashed_process_data_in->x.middle = new_x; + hashed_process_data_in->x.middle_used = FALSE; + hashed_process_data_in->x.middle_marked = FALSE; + } } } + return 0; } -- 2.34.1