performance tweaks
[lttv.git] / ltt / branches / poly / lttv / lttv / state.c
index ec5298482d420522dca7e3359730c02714882692..2ff087f48d335aef3363dcd593445f0bf7bbe598 100644 (file)
@@ -42,6 +42,7 @@ LttvProcessStatus
   LTTV_STATE_WAIT_FORK,
   LTTV_STATE_WAIT_CPU,
   LTTV_STATE_EXIT,
+  LTTV_STATE_ZOMBIE,
   LTTV_STATE_WAIT,
   LTTV_STATE_RUN;
 
@@ -96,7 +97,8 @@ void lttv_state_state_saved_free(LttvTraceState *self,
 
 guint process_hash(gconstpointer key) 
 {
-  return ((const LttvProcessState *)key)->pid;
+  guint pid = ((const LttvProcessState *)key)->pid;
+  return (pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ;
 }
 
 
@@ -843,9 +845,6 @@ lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid)
  * cases in the child's exit : when the parent ignores its children SIGCCHLD or
  * has the flag SA_NOCLDWAIT. It can also happen when the child is part
  * of a killed thread ground, but isn't the leader.
- *
- * This function is important : it removes the dead PID entry in the hash
- * table so there is no collision when the OS reuses PID.
  */
 static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) 
 {
@@ -972,14 +971,15 @@ static gboolean schedchange(void *hook_data, void *call_data)
       g_assert(s->process->pid == 0);
     }
 
-    if(s->process->state->s != LTTV_STATE_EXIT) {
+    if(s->process->state->s == LTTV_STATE_EXIT) {
+      s->process->state->s = LTTV_STATE_ZOMBIE;
+    } else {
       if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
       else s->process->state->s = LTTV_STATE_WAIT;
     } /* FIXME : we do not remove process here, because the kernel
        * still has them : they may be zombies. We need to know
        * exactly when release_task is executed on the PID to 
-       * know when the zombie is destroyed. We should rename STATE_EXIT
-       * for STATE_ZOMBIE.
+       * know when the zombie is destroyed.
        */
     //else
     //  exit_process(s, s->process);
@@ -998,25 +998,24 @@ static gboolean process_fork(LttvTraceHook *trace_hook, LttvTracefileState *s)
 {
   LttField *f;
   guint child_pid;
+  LttvProcessState *zombie_process;
 
   /* Child PID */
   f = trace_hook->f2;
   child_pid = ltt_event_get_unsigned(s->parent.e, f);
 
-  lttv_state_create_process(s, s->process, child_pid);
-
-  return FALSE;
-#if 0
-  LttField *f = ((LttvTraceHook *)hook_data)->f1;
+  zombie_process = lttv_state_find_process(s, child_pid);
 
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  guint child_pid;
-
-  child_pid = ltt_event_get_unsigned(s->parent.e, f);
+  if(zombie_process != NULL) {
+    /* Reutilisation of PID. Only now we are sure that the old PID
+     * has been released. FIXME : sould know when release_task happens instead.
+     */
+    exit_process(s, zombie_process);
+  }
+  g_assert(s->process->pid != child_pid);
   lttv_state_create_process(s, s->process, child_pid);
+
   return FALSE;
-#endif //0
 }
 
 
@@ -1026,15 +1025,6 @@ static gboolean process_exit(LttvTraceHook *trace_hook, LttvTracefileState *s)
     s->process->state->s = LTTV_STATE_EXIT;
   }
   return FALSE;
-#if 0
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  if(s->process != NULL) {
-    s->process->state->s = LTTV_STATE_EXIT;
-  }
-  return FALSE;
-#endif //0
 }
 
 gboolean process(void *hook_data, void *call_data)
@@ -1587,6 +1577,7 @@ static void module_init()
   LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)");
   LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu");
   LTTV_STATE_EXIT = g_quark_from_string("exiting");
+  LTTV_STATE_ZOMBIE = g_quark_from_string("zombie");
   LTTV_STATE_WAIT = g_quark_from_string("wait for I/O");
   LTTV_STATE_RUN = g_quark_from_string("running");
   LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
This page took 0.023296 seconds and 4 git commands to generate.