fix process end of life
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Wed, 5 Dec 2007 16:54:23 +0000 (16:54 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Wed, 5 Dec 2007 16:54:23 +0000 (16:54 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@2782 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/lttv/lttv/state.c
ltt/branches/poly/lttv/lttv/state.h
ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c
ltt/branches/poly/lttv/modules/gui/controlflow/drawing.h
ltt/branches/poly/lttv/modules/gui/controlflow/eventhooks.c

index 9034cc0cd8614cf55dd6ccdb2db9e07e358229c5..c02a32275afcd75412ed1e9396df14116975d636 100644 (file)
@@ -616,7 +616,7 @@ static void write_process_state(gpointer key, gpointer value,
 
   process = (LttvProcessState *)value;
   fprintf(fp,
-"  <PROCESS CORE=%p PID=%u TGID=%u PPID=%u TYPE=\"%s\" CTIME_S=%lu CTIME_NS=%lu ITIME_S=%lu ITIME_NS=%lu NAME=\"%s\" BRAND=\"%s\" CPU=\"%u\">\n",
+"  <PROCESS CORE=%p PID=%u TGID=%u PPID=%u TYPE=\"%s\" CTIME_S=%lu CTIME_NS=%lu ITIME_S=%lu ITIME_NS=%lu NAME=\"%s\" BRAND=\"%s\" CPU=\"%u\" FREE_EVENTS=\"%u\">\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,
                &ltt_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 */
index aad7ef4b670c630fbdd6582726abcd521a8c3339..7334e7815a5ee482cd8554bbcdd97a14fd9a5b9b 100644 (file)
@@ -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
index dbd37dd9b28ab43ffeb8c9c86a00fb5b89e79ee1..8d670123835c4141bed4c2bee3ae514ad2d54af3 100644 (file)
@@ -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 */
 
index 58f562a2a6380e4be299b805e68807f1aaf29365..3e4b3dc86bad8278e797927df26e4cc5bda89c9f 100644 (file)
@@ -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; 
index cde8be6baab95c0352e550eb0162e6bf28490b00..cffd9b89b9ccc6051f82beb2172af29fe5a81122 100644 (file)
@@ -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;
 }
 
This page took 0.030092 seconds and 4 git commands to generate.