add support for block devices in restore_init_state()
[lttv.git] / ltt / branches / poly / lttv / lttv / state.c
index 0c0a4cbcd1677bf04c86e79b8f513ea0211dbedb..bc4884ca6e19950cb8711ef647070bb0397909e7 100644 (file)
@@ -163,7 +163,8 @@ static GQuark
   LTTV_STATE_HOOKS,
   LTTV_STATE_NAME_TABLES,
   LTTV_STATE_TRACE_STATE_USE_COUNT,
-  LTTV_STATE_RESOURCE_CPUS;
+  LTTV_STATE_RESOURCE_CPUS,
+  LTTV_STATE_RESOURCE_IRQS;
 
 static void create_max_time(LttvTraceState *tcs);
 
@@ -184,6 +185,11 @@ static void lttv_state_free_process_table(GHashTable *processes);
 static void lttv_trace_states_read_raw(LttvTraceState *tcs, FILE *fp,
                        GPtrArray *quarktable);
 
+/* Resource function prototypes */
+static void bdev_state_free(gpointer key, gpointer value, gpointer user_data);
+static LttvBdevState *bdev_state_get(LttvTraceState *ts, guint16 devcode);
+
+
 void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
 {
   LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container);
@@ -297,6 +303,9 @@ restore_init_state(LttvTraceState *self)
     if(self->irq_states[i].mode_stack->len > 0)
       g_array_remove_range(self->irq_states[i].mode_stack, 0, self->irq_states[i].mode_stack->len);
   }
+
+  g_hash_table_foreach(self->bdev_states, bdev_state_free, NULL);
+  g_hash_table_steal_all(self->bdev_states);
   
 #if 0
   nb_tracefile = self->parent.tracefiles->len;
@@ -1143,6 +1152,35 @@ static void lttv_state_free_cpu_states(LttvCPUState *states, guint n)
   g_free(states);
 }
 
+static LttvIRQState *lttv_state_copy_irq_states(LttvIRQState *states, guint n)
+{
+  guint i,j;
+  LttvIRQState *retval;
+
+  retval = g_malloc(n*sizeof(LttvIRQState));
+
+  for(i=0; i<n; i++) {
+    retval[i].mode_stack = g_array_new(FALSE, FALSE, sizeof(LttvIRQMode));
+    g_array_set_size(retval[i].mode_stack, states[i].mode_stack->len);
+    for(j=0; j<states[i].mode_stack->len; j++) {
+      g_array_index(retval[i].mode_stack, GQuark, j) = g_array_index(states[i].mode_stack, GQuark, j);
+    }
+  }
+
+  return retval;
+}
+
+static void lttv_state_free_irq_states(LttvIRQState *states, guint n)
+{
+  guint i;
+
+  for(i=0; i<n; i++) {
+    g_array_free(states[i].mode_stack, FALSE);
+  }
+
+  g_free(states);
+}
+
 /* The saved state for each trace contains a member "processes", which
    stores a copy of the process table, and a member "tracefiles" with
    one entry per tracefile. Each tracefile has a "process" member pointing
@@ -1151,7 +1189,7 @@ static void lttv_state_free_cpu_states(LttvCPUState *states, guint n)
 
 static void state_save(LttvTraceState *self, LttvAttribute *container)
 {
-  guint i, nb_tracefile, nb_cpus;
+  guint i, nb_tracefile, nb_cpus, nb_irqs;
 
   LttvTracefileState *tfcs;
 
@@ -1224,16 +1262,28 @@ static void state_save(LttvTraceState *self, LttvAttribute *container)
     }
   }
 
-  value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_CPUS,
-      LTTV_POINTER);
-  guint size = sizeof(LttvCPUState)*nb_cpus;
-  *(value.v_pointer) = lttv_state_copy_cpu_states(self->cpu_states, nb_cpus);
+  /* save the cpu state */
+  {
+    guint size = sizeof(LttvCPUState)*nb_cpus;
+    value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_CPUS,
+        LTTV_POINTER);
+    *(value.v_pointer) = lttv_state_copy_cpu_states(self->cpu_states, nb_cpus);
+  }
+
+  /* save the irq state */
+  nb_irqs = self->nb_irqs;
+  {
+    guint size = sizeof(LttvCPUState)*nb_irqs;
+    value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_IRQS,
+        LTTV_POINTER);
+    *(value.v_pointer) = lttv_state_copy_irq_states(self->irq_states, nb_irqs);
+  }
 }
 
 
 static void state_restore(LttvTraceState *self, LttvAttribute *container)
 {
-  guint i, nb_tracefile, pid, nb_cpus;
+  guint i, nb_tracefile, pid, nb_cpus, nb_irqs;
 
   LttvTracefileState *tfcs;
 
@@ -1274,8 +1324,6 @@ static void state_restore(LttvTraceState *self, LttvAttribute *container)
     g_assert(self->running_process[i] != NULL);
   }
 
-  printf("state restore\n"); 
-
   nb_tracefile = self->parent.tracefiles->len;
 
   //g_tree_destroy(tsc->pqueue);
@@ -1287,6 +1335,13 @@ static void state_restore(LttvTraceState *self, LttvAttribute *container)
   lttv_state_free_cpu_states(self->cpu_states, nb_cpus);
   self->cpu_states = lttv_state_copy_cpu_states(*(value.v_pointer), nb_cpus);
  
+  /* restore irq resource states */
+  nb_irqs = self->nb_irqs;
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_IRQS, &value);
+  g_assert(type == LTTV_POINTER);
+  lttv_state_free_irq_states(self->irq_states, nb_irqs);
+  self->irq_states = lttv_state_copy_irq_states(*(value.v_pointer), nb_irqs);
   for(i = 0 ; i < nb_tracefile ; i++) {
     tfcs = 
           LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
@@ -1689,7 +1744,7 @@ static void cpu_push_mode(LttvCPUState *cpust, LttvCPUMode state)
 
 static void cpu_pop_mode(LttvCPUState *cpust)
 {
-  if(cpust->mode_stack->len == 1)
+  if(cpust->mode_stack->len <= 1)
     cpu_set_base_mode(cpust, LTTV_CPU_UNKNOWN);
   else
     g_array_set_size(cpust->mode_stack, cpust->mode_stack->len - 1);
@@ -1710,7 +1765,7 @@ static void bdev_push_mode(LttvBdevState *bdevst, LttvBdevMode state)
 
 static void bdev_pop_mode(LttvBdevState *bdevst)
 {
-  if(bdevst->mode_stack->len == 1)
+  if(bdevst->mode_stack->len <= 1)
     bdev_set_base_mode(bdevst, LTTV_BDEV_UNKNOWN);
   else
     g_array_set_size(bdevst->mode_stack, bdevst->mode_stack->len - 1);
@@ -1730,7 +1785,7 @@ static void irq_push_mode(LttvIRQState *irqst, LttvIRQMode state)
 
 static void irq_pop_mode(LttvIRQState *irqst)
 {
-  if(irqst->mode_stack->len == 1)
+  if(irqst->mode_stack->len <= 1)
     irq_set_base_mode(irqst, LTTV_IRQ_UNKNOWN);
   else
     g_array_set_size(irqst->mode_stack, irqst->mode_stack->len - 1);
@@ -2212,7 +2267,7 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data)
   return FALSE;
 }
 
-LttvBdevState *bdev_state_get(LttvTraceState *ts, guint16 devcode)
+static LttvBdevState *bdev_state_get(LttvTraceState *ts, guint16 devcode)
 {
   gint devcode_gint = devcode;
   gpointer bdev = g_hash_table_lookup(ts->bdev_states, &devcode_gint);
@@ -2231,6 +2286,14 @@ LttvBdevState *bdev_state_get(LttvTraceState *ts, guint16 devcode)
   return bdev;
 }
 
+static void bdev_state_free(gpointer key, gpointer value, gpointer user_data)
+{
+       LttvBdevState *bds = (LttvBdevState *) value;
+       
+       g_array_free(bds->mode_stack, FALSE);
+       g_free(bds);
+}
+
 static gboolean bdev_request_issue(void *hook_data, void *call_data)
 {
   LttvTracefileState *s = (LttvTracefileState *)call_data;
This page took 0.024797 seconds and 4 git commands to generate.