update stats for pid 0 at beginning of trace
[lttv.git] / ltt / branches / poly / lttv / lttv / state.c
index 85a50e80972cbea841bec0d860048022c1f2bd6d..7770e9abec506b45704483551fc1ad2e5d1ffdc9 100644 (file)
@@ -231,8 +231,18 @@ restore_init_state(LttvTraceState *self)
   
   /* Put the per cpu running_process to beginning state : process 0. */
   for(i=0; i< nb_cpus; i++) {
+    LttvExecutionState *es;
     self->running_process[i] = lttv_state_create_process(self, NULL, i, 0, 0,
         LTTV_STATE_UNNAMED, &start_time);
+    /* We are not sure is it's a kernel thread or normal thread, put the
+      * bottom stack state to unknown */
+    self->running_process[i]->execution_stack = 
+      g_array_set_size(self->running_process[i]->execution_stack, 1);
+    es = self->running_process[i]->state =
+      &g_array_index(self->running_process[i]->execution_stack,
+        LttvExecutionState, 0);
+    es->t = LTTV_STATE_MODE_UNKNOWN;
+
     self->running_process[i]->state->s = LTTV_STATE_RUN;
     self->running_process[i]->cpu = i;
   }
@@ -424,7 +434,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\" PROCESS_TYPE=%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\">\n",
       process, process->pid, process->tgid, process->ppid,
       g_quark_to_string(process->type),
       process->creation_time.tv_sec,
@@ -673,8 +683,6 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp)
   LttvProcessState *process, *parent_process;
   LttvProcessState tmp;
 
-  FILE *fp = (FILE *)user_data;
-
   guint i;
   guint64 address;
   guint cpu;
@@ -691,14 +699,13 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp)
   fread(&tmp.insertion_time, sizeof(tmp.insertion_time), 1, fp);
 
   if(tmp.pid == 0) {
-    process = lttv_state_find_process(self, tmp.cpu, tmp.pid,
-        tmp.insertion_time);
+    process = lttv_state_find_process(self, tmp.cpu, tmp.pid);
   } else {
     /* We must link to the parent */
     parent_process = lttv_state_find_process_or_create(self, ANY_CPU, tmp.ppid,
-        LTT_TIME_ZERO);
+        &ltt_time_zero);
     process = lttv_state_find_process_or_create(self, ANY_CPU, tmp.pid,
-        tmp.insertion_time);
+        &tmp.insertion_time);
   }
   process->creation_time = tmp.creation_time;
   process->type = tmp.type;
@@ -709,7 +716,7 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp)
   do {
     if(feof(fp) || ferror(fp)) goto end_loop;
 
-    hdr = fgetc(fp);
+    gint hdr = fgetc(fp);
 
     switch(hdr) {
       case HDR_ES:
@@ -726,7 +733,7 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp)
     };
   } while(1);
 end_loop:
-
+  return;
 }
 
 
@@ -737,6 +744,7 @@ void lttv_state_read_raw(LttvTraceState *self, FILE *fp)
   guint i, nb_tracefile, nb_block, offset;
   guint64 tsc;
   LttTracefile *tf;
+  LttvTracefileState *tfcs;
 
   LttEventPosition *ep;
 
@@ -810,17 +818,18 @@ end_loop:
     fread(&tfcs->parent.timestamp, sizeof(tfcs->parent.timestamp), 1, fp);
     /* Note : if timestamp if LTT_TIME_INFINITE, there will be no
      * position following : end of trace */
-    if(ltt_time_compare(tfcs->parent.timestamp, LTT_TIME_INFINITE) != 0) {
+    if(ltt_time_compare(tfcs->parent.timestamp, ltt_time_infinite) != 0) {
       fread(&nb_block, sizeof(nb_block), 1, fp);
       fread(&offset, sizeof(offset), 1, fp);
       fread(&tsc, sizeof(tsc), 1, fp);
       ltt_event_position_set(ep, tf, nb_block, offset, tsc);
-      g_assert(ltt_tracefile_seek_position(tfc->tf, ep) == 0);
+      gint ret = ltt_tracefile_seek_position(tfcs->parent.tf, ep);
+      g_assert(ret == 0);
     }
   }
   g_free(ep);
 
-  saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, 
+  saved_states_tree = lttv_attribute_find_subdir(self->parent.t_a, 
       LTTV_STATE_SAVED_STATES);
   saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
   value = lttv_attribute_add(saved_states_tree, 
@@ -828,9 +837,9 @@ end_loop:
   *(value.v_gobject) = (GObject *)saved_state_tree;
   value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
   *(value.v_time) = t;
-  lttv_state_save(tcs, saved_state_tree);
+  lttv_state_save(self, saved_state_tree);
   g_debug("Saving state at time %lu.%lu", t.tv_sec,
-    self->parent.timestamp.tv_nsec);
+    t.tv_nsec);
 
   *(self->max_time_state_recomputed_in_seek) = t;
 }
@@ -1659,7 +1668,7 @@ LttvProcessState *lttv_state_find_process(LttvTraceState *ts, guint cpu,
 
 LttvProcessState *
 lttv_state_find_process_or_create(LttvTraceState *ts, guint cpu, guint pid,
-    LttTime *timestamp)
+    const LttTime *timestamp)
 {
   LttvProcessState *process = lttv_state_find_process(ts, cpu, pid);
   LttvExecutionState *es;
@@ -1715,6 +1724,9 @@ static void lttv_state_free_process_table(GHashTable *processes)
 static gboolean syscall_entry(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
+  guint cpu = s->cpu;
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
   LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
   LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
   LttField *f = thf->f1;
@@ -1734,7 +1746,9 @@ static gboolean syscall_entry(void *hook_data, void *call_data)
     submode = g_quark_from_string(string->str);
     g_string_free(string, TRUE);
   }
-  push_state(s, LTTV_STATE_SYSCALL, submode);
+  /* There can be no system call from PID 0 : unknown state */
+  if(process->pid != 0)
+    push_state(s, LTTV_STATE_SYSCALL, submode);
   return FALSE;
 }
 
@@ -1742,8 +1756,13 @@ static gboolean syscall_entry(void *hook_data, void *call_data)
 static gboolean syscall_exit(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
+  guint cpu = s->cpu;
+  LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+  LttvProcessState *process = ts->running_process[cpu];
 
-  pop_state(s, LTTV_STATE_SYSCALL);
+  /* There can be no system call from PID 0 : unknown state */
+  if(process->pid != 0)
+    pop_state(s, LTTV_STATE_SYSCALL);
   return FALSE;
 }
 
@@ -1961,7 +1980,12 @@ static gboolean schedchange(void *hook_data, void *call_data)
     //if(unlikely(process->pid != pid_out)) {
     //  g_assert(process->pid == 0);
     //}
-
+    if(process->pid == 0 && process->state->t == LTTV_STATE_MODE_UNKNOWN) {
+      /* Scheduling out of pid 0 at beginning of the trace :
+       * we know for sure it is in syscall mode at this point. */
+      g_assert(process->execution_stack->len == 1);
+      process->state->t = LTTV_STATE_SYSCALL;
+    }
     if(unlikely(process->state->s == LTTV_STATE_EXIT)) {
       process->state->s = LTTV_STATE_ZOMBIE;
       process->state->change = s->parent.timestamp;
This page took 0.025637 seconds and 4 git commands to generate.