update end of process
[lttv.git] / ltt / branches / poly / lttv / lttv / state.c
index 17c5906e508f74d086de1d125b1de1bbd489e188..bcb44f5ace21e4cc0a20486840b701ec43dd4c0b 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, 
@@ -2314,6 +2317,7 @@ static gboolean syscall_exit(void *hook_data, void *call_data)
 static gboolean trap_entry(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttvTraceState *ts = (LttvTraceState *)s->parent.t_context;
   LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
   LttvTraceHook *th = (LttvTraceHook *)hook_data;
   struct marker_field *f = lttv_trace_get_hook_field(th, 0);
@@ -2338,18 +2342,28 @@ static gboolean trap_entry(void *hook_data, void *call_data)
   /* update cpu status */
   cpu_push_mode(s->cpu_state, LTTV_CPU_TRAP);
 
+  /* update trap status */
+  s->cpu_state->last_trap = trap;
+  ts->trap_states[trap].running++;
+
   return FALSE;
 }
 
 static gboolean trap_exit(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
+  LttvTraceState *ts = (LttvTraceState *)s->parent.t_context;
+  guint trap = s->cpu_state->last_trap;
 
   pop_state(s, LTTV_STATE_TRAP);
 
   /* update cpu status */
   cpu_pop_mode(s->cpu_state);
 
+  /* update trap status */
+  if(ts->trap_states[trap].running)
+    ts->trap_states[trap].running--;
+
   return FALSE;
 }
 
@@ -2658,9 +2672,11 @@ 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 */
+        process->state->s = LTTV_STATE_DEAD;
+        process->state->change = s->parent.timestamp;
+      }
     }
   }
   process = ts->running_process[cpu] =
@@ -2758,8 +2774,9 @@ static gboolean process_fork(void *hook_data, void *call_data)
      *
      * Simply put a correct parent.
      */
-    g_assert(0); /* This is a problematic case : the process has been created
-                    before the fork event */
+    g_error("Process %u has been created before fork on cpu %u. Probably an unsynchronized TSC problem on the traced machine.", child_pid, cpu);
+    //g_assert(0); /* This is a problematic case : the process has been created
+    //                before the fork event */
     child_process->ppid = process->pid;
     child_process->tgid = child_tgid;
   }
@@ -2788,11 +2805,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;
@@ -2836,32 +2855,8 @@ 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)) {
-    /* release_task is happening at kernel level : we can now safely release
-     * the data structure of the process */
-    //This test is fun, though, as it may happen that 
-    //at time t : CPU 0 : process_free
-    //at time t+150ns : CPU 1 : schedule out
-    //Clearly due to time imprecision, we disable it. (Mathieu)
-    //If this weird case happen, we have no choice but to put the 
-    //Currently running process on the cpu to 0.
-    //I re-enable it following time precision fixes. (Mathieu)
-    //Well, in the case where an process is freed by a process on another CPU
-    //and still scheduled, it happens that this is the schedchange that will
-    //drop the last reference count. Do not free it here!
-    guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
-    guint i;
-    for(i=0; i< num_cpus; i++) {
-      //g_assert(process != ts->running_process[i]);
-      if(process == ts->running_process[i]) {
-        //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
-        break;
-      }
-    }
-    if(i == num_cpus) /* process is not scheduled */
-      exit_process(s, process);
-  }
+  if(likely(process != NULL))
+    exit_process(s, process);
 
   return FALSE;
 }
This page took 0.024988 seconds and 4 git commands to generate.