still some performance enhancements
[lttv.git] / ltt / branches / poly / lttv / lttv / state.c
index fbe725420ab6797071c8d1694967c9f46f44fdf7..d60b4588a3d3f428ac39c8d3951e5129d598710b 100644 (file)
@@ -26,6 +26,8 @@
 #include <ltt/type.h>
 #include <stdio.h>
 
+#define PREALLOCATED_EXECUTION_STACK 10
+
 LttvExecutionMode
   LTTV_STATE_MODE_UNKNOWN,
   LTTV_STATE_USER_MODE,
@@ -42,6 +44,7 @@ LttvProcessStatus
   LTTV_STATE_WAIT_FORK,
   LTTV_STATE_WAIT_CPU,
   LTTV_STATE_EXIT,
+  LTTV_STATE_ZOMBIE,
   LTTV_STATE_WAIT,
   LTTV_STATE_RUN;
 
@@ -96,7 +99,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) ;
 }
 
 
@@ -135,6 +139,7 @@ restore_init_state(LttvTraceState *self)
     tfcs->process = lttv_state_create_process(tfcs, NULL,0);
     tfcs->process->state->s = LTTV_STATE_RUN;
     tfcs->process->last_cpu = tfcs->cpu_name;
+    tfcs->process->last_cpu_index = ((LttvTracefileContext*)tfcs)->index;
   }
 }
 
@@ -320,8 +325,8 @@ static void copy_process_state(gpointer key, gpointer value,gpointer user_data)
   process = (LttvProcessState *)value;
   new_process = g_new(LttvProcessState, 1);
   *new_process = *process;
-  new_process->execution_stack = g_array_new(FALSE, FALSE, 
-      sizeof(LttvExecutionState));
+  new_process->execution_stack = g_array_sized_new(FALSE, FALSE, 
+      sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
   g_array_set_size(new_process->execution_stack,process->execution_stack->len);
   for(i = 0 ; i < process->execution_stack->len; i++) {
     g_array_index(new_process->execution_stack, LttvExecutionState, i) =
@@ -775,6 +780,7 @@ lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent,
        
   process->pid = pid;
   process->last_cpu = tfs->cpu_name;
+  process->last_cpu_index = ((LttvTracefileContext*)tfs)->index;
   g_warning("Process %u, core %p", process->pid, process);
   g_hash_table_insert(tcs->processes, process, process);
 
@@ -799,8 +805,9 @@ lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent,
          process->creation_time.tv_nsec);
   process->pid_time = g_quark_from_string(buffer);
   process->last_cpu = tfs->cpu_name;
-  process->execution_stack = g_array_new(FALSE, FALSE, 
-      sizeof(LttvExecutionState));
+  process->last_cpu_index = ((LttvTracefileContext*)tfs)->index;
+  process->execution_stack = g_array_sized_new(FALSE, FALSE, 
+      sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
   g_array_set_size(process->execution_stack, 1);
   es = process->state = &g_array_index(process->execution_stack, 
       LttvExecutionState, 0);
@@ -969,14 +976,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);
@@ -986,6 +994,7 @@ static gboolean schedchange(void *hook_data, void *call_data)
   s->process = lttv_state_find_process_or_create(s, pid_in);
   s->process->state->s = LTTV_STATE_RUN;
   s->process->last_cpu = s->cpu_name;
+  s->process->last_cpu_index = ((LttvTracefileContext*)s)->index;
   s->process->state->change = s->parent.timestamp;
   return FALSE;
 }
@@ -1009,6 +1018,7 @@ static gboolean process_fork(LttvTraceHook *trace_hook, LttvTracefileState *s)
      */
     exit_process(s, zombie_process);
   }
+  g_assert(s->process->pid != child_pid);
   lttv_state_create_process(s, s->process, child_pid);
 
   return FALSE;
@@ -1573,6 +1583,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.025346 seconds and 4 git commands to generate.