revert mainLib, part 1
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 27 Jan 2004 23:06:25 +0000 (23:06 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 27 Jan 2004 23:06:25 +0000 (23:06 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@426 04897980-b3bd-0310-b5e0-8ef037075253

18 files changed:
ltt/branches/poly/lttv/main/attribute.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/filter.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/hook.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/iattribute.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/module.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/processTrace.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/state.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/stats.c [new file with mode: 0644]
ltt/branches/poly/lttv/main/traceset.c [new file with mode: 0644]
ltt/branches/poly/lttv/mainLib/attribute.c [deleted file]
ltt/branches/poly/lttv/mainLib/filter.c [deleted file]
ltt/branches/poly/lttv/mainLib/hook.c [deleted file]
ltt/branches/poly/lttv/mainLib/iattribute.c [deleted file]
ltt/branches/poly/lttv/mainLib/module.c [deleted file]
ltt/branches/poly/lttv/mainLib/processTrace.c [deleted file]
ltt/branches/poly/lttv/mainLib/state.c [deleted file]
ltt/branches/poly/lttv/mainLib/stats.c [deleted file]
ltt/branches/poly/lttv/mainLib/traceset.c [deleted file]

diff --git a/ltt/branches/poly/lttv/main/attribute.c b/ltt/branches/poly/lttv/main/attribute.c
new file mode 100644 (file)
index 0000000..4b6938d
--- /dev/null
@@ -0,0 +1,383 @@
+
+#include <lttv/attribute.h>
+#include <ltt/ltt.h>
+
+typedef union _AttributeValue {
+  int dv_int;
+  unsigned dv_uint;
+  long dv_long;
+  unsigned long dv_ulong;
+  float dv_float;
+  double dv_double;
+  LttTime dv_time;
+  gpointer dv_pointer;
+  char *dv_string;
+  GObject *dv_gobject;
+} AttributeValue;
+
+
+typedef struct _Attribute {
+  LttvAttributeName name;
+  LttvAttributeType type;
+  AttributeValue value;
+} Attribute;
+
+
+LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v)
+{
+  LttvAttributeValue va;
+
+  switch(t) {
+  case LTTV_INT: va.v_int = &v->dv_int; break;
+  case LTTV_UINT: va.v_uint = &v->dv_uint; break;
+  case LTTV_LONG: va.v_long = &v->dv_long; break;
+  case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break;
+  case LTTV_FLOAT: va.v_float = &v->dv_float; break;
+  case LTTV_DOUBLE: va.v_double = &v->dv_double; break;
+  case LTTV_TIME: va.v_time = &v->dv_time; break;
+  case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break;
+  case LTTV_STRING: va.v_string = &v->dv_string; break;
+  case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break;
+  }
+  return va;
+}
+
+
+AttributeValue init_value(LttvAttributeType t)
+{
+  AttributeValue v;
+
+  switch(t) {
+  case LTTV_INT: v.dv_int = 0; break;
+  case LTTV_UINT: v.dv_uint = 0; break;
+  case LTTV_LONG: v.dv_long = 0; break;
+  case LTTV_ULONG: v.dv_ulong = 0; break;
+  case LTTV_FLOAT: v.dv_float = 0; break;
+  case LTTV_DOUBLE: v.dv_double = 0; break;
+  case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break;
+  case LTTV_POINTER: v.dv_pointer = NULL; break;
+  case LTTV_STRING: v.dv_string = NULL; break;
+  case LTTV_GOBJECT: v.dv_gobject = NULL; break;
+  }
+  return v;
+}
+
+
+unsigned int 
+lttv_attribute_get_number(LttvAttribute *self)
+{
+  return self->attributes->len;
+}
+
+
+gboolean 
+lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
+{
+  *homogeneous = FALSE;
+  return TRUE;
+}
+
+
+LttvAttributeType 
+lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, 
+    LttvAttributeValue *v)
+{
+  Attribute *a;
+
+  a = &g_array_index(self->attributes, Attribute, i);
+  *name = a->name;
+  *v = address_of_value(a->type, &(a->value));
+  return a->type;
+}
+
+
+LttvAttributeType 
+lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeValue *v)
+{
+  Attribute *a;
+
+  unsigned i;
+
+  gpointer p;
+
+  p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(p == NULL) return LTTV_NONE;
+
+  i = GPOINTER_TO_UINT(p);
+  i--;
+  a = &g_array_index(self->attributes, Attribute, i);
+  *v = address_of_value(a->type, &(a->value));
+  return a->type;
+}
+
+
+LttvAttributeValue 
+lttv_attribute_add(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t)
+{
+  unsigned i;
+
+  Attribute a, *pa;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(i != 0) g_error("duplicate entry in attribute table");
+
+  a.name = name;
+  a.type = t;
+  a.value = init_value(t);
+  g_array_append_val(self->attributes, a);
+  i = self->attributes->len - 1;
+  pa = &g_array_index(self->attributes, Attribute, i);
+  g_hash_table_insert(self->names, GUINT_TO_POINTER(name), 
+      GUINT_TO_POINTER(i + 1));
+  return address_of_value(t, &(pa->value));
+}
+
+
+/* Remove an attribute */
+
+void 
+lttv_attribute_remove(LttvAttribute *self, unsigned i)
+{
+  Attribute *a;
+
+  a = &g_array_index(self->attributes, Attribute, i);
+
+  /* Remove the array element and its entry in the name index */
+
+  g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
+  g_array_remove_index_fast(self->attributes, i);
+
+  /* The element used to replace the removed element has its index entry
+     all wrong now. Reinsert it with its new position. */
+
+  if(self->attributes->len != i){
+    g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
+    g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1));
+  }
+}
+
+void 
+lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
+{
+  unsigned i;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(i == 0) g_error("remove by name non existent attribute");
+
+  lttv_attribute_remove(self, i - 1);
+}
+
+/* Create an empty iattribute object and add it as an attribute under the
+   specified name, or return an existing iattribute attribute. If an
+   attribute of that name already exists but is not a GObject supporting the
+   iattribute interface, return NULL. */
+
+/*CHECK*/LttvAttribute* 
+lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name)
+{
+  unsigned i;
+
+  Attribute a;
+
+  LttvAttribute *new;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(i != 0) {
+    a = g_array_index(self->attributes, Attribute, i - 1);
+    if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) {
+      return LTTV_ATTRIBUTE(a.value.dv_gobject);
+    }
+    else return NULL;    
+  }
+  new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new);
+  return (LttvAttribute *)new;
+}
+
+gboolean 
+lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  unsigned i;
+
+  Attribute *a;
+
+  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
+  if(i != 0) {
+    a = &g_array_index(self->attributes, Attribute, i - 1);
+    if(a->type != t) return FALSE;
+    *v = address_of_value(t, &(a->value));
+    return TRUE;
+  }
+
+  *v = lttv_attribute_add(self, name, t);
+  return TRUE;
+}
+
+
+void lttv_attribute_recursive_free(LttvAttribute *self)
+{
+  int i, nb;
+
+  Attribute *a;
+
+  nb = self->attributes->len;
+
+  for(i = 0 ; i < nb ; i++) {
+    a = &g_array_index(self->attributes, Attribute, i);
+    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+      lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject));
+    }
+  }
+  g_object_unref(self);
+}
+
+
+void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
+{
+  int i, nb;
+
+  Attribute *a;
+
+  LttvAttributeValue value;
+
+  nb = src->attributes->len;
+
+  for(i = 0 ; i < nb ; i++) {
+    a = &g_array_index(src->attributes, Attribute, i);
+    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
+      lttv_attribute_recursive_add(
+      /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
+          (LttvAttribute *)(a->value.dv_gobject));
+    }
+    else {
+      g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
+      switch(a->type) {
+       case LTTV_INT:
+          *value.v_int += a->value.dv_int;
+          break;
+        case LTTV_UINT:
+          *value.v_uint += a->value.dv_uint;
+          break;
+        case LTTV_LONG:
+          *value.v_long += a->value.dv_long;
+          break;
+        case LTTV_ULONG:
+          *value.v_ulong += a->value.dv_ulong;
+          break;
+        case LTTV_FLOAT:
+          *value.v_float += a->value.dv_float;
+          break;
+        case LTTV_DOUBLE:
+          *value.v_double += a->value.dv_double;
+          break;
+        case LTTV_TIME:
+          *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time);
+          break;
+        case LTTV_POINTER:
+          break;
+        case LTTV_STRING:
+          break;
+        case LTTV_GOBJECT:
+          break;
+        case LTTV_NONE:
+          break;
+      }    
+    }
+  }
+}
+
+
+static void
+attribute_interface_init (gpointer g_iface, gpointer iface_data)
+{
+  LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
+
+  klass->get_number = (unsigned int (*) (LttvIAttribute *self)) 
+      lttv_attribute_get_number;
+
+  klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
+      lttv_attribute_named;
+
+  klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, 
+      LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get;
+
+  klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
+      LttvAttributeName name, LttvAttributeValue *v)) 
+      lttv_attribute_get_by_name;
+
+  klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, 
+      LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
+
+  klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) 
+      lttv_attribute_remove;
+
+  klass->remove_by_name = (void (*) (LttvIAttribute *self,
+      LttvAttributeName name)) lttv_attribute_remove_by_name;
+
+  klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, 
+      LttvAttributeName name)) lttv_attribute_find_subdir;
+}
+
+
+static void
+attribute_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  LttvAttribute *self = (LttvAttribute *)instance;
+  self->names = g_hash_table_new(g_direct_hash, g_direct_equal);
+  self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
+}
+
+
+static void
+attribute_finalize (LttvAttribute *self)
+{
+  g_hash_table_destroy(self->names);
+  g_critical("attribute_finalize()");
+  g_array_free(self->attributes, TRUE);
+  G_OBJECT_CLASS(g_type_class_peek_parent(
+      g_type_class_peek(LTTV_ATTRIBUTE_TYPE)))->finalize(G_OBJECT(self));
+}
+
+
+static void
+attribute_class_init (LttvAttributeClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
+}
+
+GType 
+lttv_attribute_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvAttributeClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) attribute_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvAttribute),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) attribute_instance_init    /* instance_init */
+    };
+
+    static const GInterfaceInfo iattribute_info = {
+      (GInterfaceInitFunc) attribute_interface_init,    /* interface_init */
+      NULL,                                       /* interface_finalize */
+      NULL                                        /* interface_data */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info, 
+        0);
+    g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
+  }
+  return type;
+}
+
+
diff --git a/ltt/branches/poly/lttv/main/filter.c b/ltt/branches/poly/lttv/main/filter.c
new file mode 100644 (file)
index 0000000..c63940b
--- /dev/null
@@ -0,0 +1,58 @@
+
+   consist in AND, OR and NOT nested expressions, forming a tree with 
+   simple relations as leaves. The simple relations test is a field
+   in an event is equal, not equal, smaller, smaller or equal, larger, or
+   larger or equal to a specified value. */
+
+typedef enum _lttv_expression_op
+{ LTTV_FIELD_EQ,
+  LTTV_FIELD_NE,
+  LTTV_FIELD_LT,
+  LTTV_FIELD_LE,
+  LTTV_FIELD_GT,
+  LTTV_FIELD_GE
+} lttv_expression_op;
+
+typedef _lttv_simple_expression
+{ lttv_expression_op op;
+  char *field_name;
+  char *value;
+} lttv_simple_expression;
+
+typedef _lttv_expression_type
+{ LTTV_EXPRESSION,
+  LTTV_SIMPLE_EXPRESSION
+
+}
+typedef struct _lttv_expression 
+{ bool or;
+  bool not;
+  bool simple_expression;
+  union 
+  { lttv_expression *e;
+    lttv_field_relation *se;
+  } e;
+} lttv_expression;
+
+read_token
+
+read_expression
+  ( read expr )
+  simple expr [ op expr ]
+
+read_simple_expression
+  read_field_path [ rel value ]
+
+read_field_path
+  read_field_component [. field path]
+
+read_field_component
+  name [ \[ value \] ]
+
+data struct:
+and/or(left/right)
+not(child)
+op(left/right)
+path(component...) -> field
+
+
diff --git a/ltt/branches/poly/lttv/main/hook.c b/ltt/branches/poly/lttv/main/hook.c
new file mode 100644 (file)
index 0000000..8edbb2a
--- /dev/null
@@ -0,0 +1,212 @@
+
+#include <lttv/hook.h>
+
+
+typedef struct _LttvHookClosure {
+  LttvHook hook;
+  void *hook_data;
+} LttvHookClosure;
+
+
+LttvHooks *lttv_hooks_new() 
+{
+  return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure));
+}
+
+
+void lttv_hooks_destroy(LttvHooks *h) 
+{
+  g_critical("lttv_hooks_destroy()");
+  g_array_free(h, TRUE);
+}
+
+
+void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) 
+{
+  LttvHookClosure c;
+
+  if(h == NULL)g_error("Null hook added");
+
+  c.hook = f;
+  c.hook_data = hook_data;
+  g_array_append_val(h,c);
+}
+
+
+void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) 
+{
+  guint i;
+
+  if(list == NULL) return;
+  for(i = 0 ; i < list->len; i++) {
+    g_array_append_val(h,g_array_index(list, LttvHookClosure, i));
+  }
+}
+
+
+void *lttv_hooks_remove(LttvHooks *h, LttvHook f)
+{
+  unsigned i;
+
+  void *hook_data;
+
+  LttvHookClosure *c;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(c->hook == f) {
+      hook_data = c->hook_data;
+      lttv_hooks_remove_by_position(h, i);
+      return hook_data;
+    }
+  }
+  return NULL;
+}
+
+
+void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data)
+{
+  unsigned i;
+
+  LttvHookClosure *c;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(c->hook == f && c->hook_data == hook_data) {
+      lttv_hooks_remove_by_position(h, i);
+      return;
+    }
+  }
+}
+
+
+void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list)
+{
+  guint i, j;
+
+  LttvHookClosure *c, *c_list;
+
+  if(list == NULL) return;
+  for(i = 0, j = 0 ; i < h->len && j < list->len ;) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    c_list = &g_array_index(list, LttvHookClosure, j);
+    if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) {
+      lttv_hooks_remove_by_position(h, i);
+      j++;
+    }
+    else i++;
+  }
+
+  /* Normally the hooks in h are ordered as in list. If this is not the case,
+     try harder here. */
+
+  if(j < list->len) {
+    for(; j < list->len ; j++) {
+      c_list = &g_array_index(list, LttvHookClosure, j);
+      lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data);
+    }
+  }
+}
+
+
+unsigned lttv_hooks_number(LttvHooks *h)
+{
+  return h->len;
+}
+
+
+void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data)
+{
+  LttvHookClosure *c;
+
+  c = &g_array_index(h, LttvHookClosure, i);
+  *f = c->hook;
+  *hook_data = c->hook_data;
+}
+
+
+void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i)
+{
+  g_array_remove_index(h, i);
+}
+
+
+gboolean lttv_hooks_call(LttvHooks *h, void *call_data)
+{
+  gboolean ret, sum_ret = FALSE;
+
+  LttvHookClosure *c;
+
+  guint i;
+
+  if(h != NULL) {
+    for(i = 0 ; i < h->len ; i++) {
+      c = &g_array_index(h, LttvHookClosure, i);
+      ret = c->hook(c->hook_data,call_data);
+      sum_ret = sum_ret || ret;
+    }
+  }
+  return sum_ret;
+}
+
+
+gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data)
+{
+  LttvHookClosure *c;
+
+  guint i;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = &g_array_index(h, LttvHookClosure, i);
+    if(c->hook(c->hook_data,call_data)) return TRUE;
+  }
+  return FALSE;
+}
+
+
+LttvHooksById *lttv_hooks_by_id_new() 
+{
+  return g_ptr_array_new();
+}
+
+
+void lttv_hooks_by_id_destroy(LttvHooksById *h) 
+{
+  guint i;
+
+  for(i = 0 ; i < h->len ; i++) {
+    if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i]));
+  }
+  g_ptr_array_free(h, TRUE);
+}
+
+
+LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id)
+{
+  if(h->len <= id) g_ptr_array_set_size(h, id + 1);
+  if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new();
+  return h->pdata[id];
+}
+
+
+unsigned lttv_hooks_by_id_max_id(LttvHooksById *h)
+{
+  return h->len;
+}
+
+
+LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id)
+{
+  if(id < h->len) return h->pdata[id];
+  return NULL;
+}
+
+
+void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id)
+{
+  if(id < h->len && h->pdata[id] != NULL) {
+    lttv_hooks_destroy((LttvHooks *)h->pdata[id]);
+    h->pdata[id] = NULL;
+  }
+}
+
diff --git a/ltt/branches/poly/lttv/main/iattribute.c b/ltt/branches/poly/lttv/main/iattribute.c
new file mode 100644 (file)
index 0000000..e39d7e0
--- /dev/null
@@ -0,0 +1,260 @@
+
+#include <lttv/iattribute.h>
+
+static void
+lttv_iattribute_base_init (gpointer klass)
+{
+  static gboolean initialized = FALSE;
+
+  if (!initialized) {
+    initialized = TRUE;
+  }
+}
+
+
+GType
+lttv_iattribute_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvIAttributeClass),
+      lttv_iattribute_base_init,   /* base_init */
+      NULL,   /* base_finalize */
+      NULL,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      0,
+      0,      /* n_preallocs */
+      NULL    /* instance_init */
+    };
+    type = g_type_register_static (G_TYPE_INTERFACE, "LttvIAttribute", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+unsigned int lttv_iattribute_get_number(LttvIAttribute *self)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->get_number (self);
+}
+
+
+gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->named (self, homogeneous);
+}
+
+
+LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, 
+    LttvAttributeName *name, LttvAttributeValue *v)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->get (self, i, name, v);
+}
+
+LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self,
+    LttvAttributeName name, LttvAttributeValue *v)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->get_by_name (self, name, v);
+}
+
+
+LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, 
+    LttvAttributeName name, LttvAttributeType t)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->add (self, name, t);
+}
+
+
+void lttv_iattribute_remove(LttvIAttribute *self, unsigned i)
+{
+        return LTTV_IATTRIBUTE_GET_CLASS (self)->remove (self, i);
+}
+
+
+void lttv_iattribute_remove_by_name(LttvIAttribute *self,
+    LttvAttributeName name)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->remove_by_name (self, name);
+}
+
+LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, 
+      LttvAttributeName name)
+{
+  return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir (self, name);
+}
+
+
+/* Find the named attribute in the table, which must be of the specified type.
+   If it does not exist, it is created with a default value of 0 (NULL for
+   pointer types). Since the address of the value is obtained, it may be
+   changed easily afterwards. The function returns false when the attribute
+   exists but is of incorrect type. */
+
+gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  LttvAttributeType found_type;
+
+  found_type = lttv_iattribute_get_by_name(self, name, v);
+  if(found_type == t) return TRUE;
+
+  if(found_type == LTTV_NONE) {
+    *v = lttv_iattribute_add(self, name, t);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+/* Trees of attribute tables may be accessed using a hierarchical path with
+   components separated by /, like in filesystems */
+
+gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, 
+    LttvAttributeType t, LttvAttributeValue *v)
+{
+  LttvIAttribute *node = self;
+
+  LttvAttributeType found_type;
+
+  LttvAttributeName name;
+
+  gchar **components, **cursor;
+
+  components = g_strsplit(path, "\"", G_MAXINT);
+
+  if(components == NULL || *components == NULL) {
+    g_strfreev(components);
+    return FALSE; 
+  }
+
+  for(cursor = components;;) {
+    name = g_quark_from_string(*cursor);
+    cursor++;
+
+    if(*cursor == NULL) {
+      g_strfreev(components);
+      return lttv_iattribute_find(node, name, t, v);
+    }
+    else {
+      found_type = lttv_iattribute_get_by_name(node, name, v);
+      if(found_type == LTTV_NONE) {
+        node = lttv_iattribute_find_subdir(node, name);
+      }
+      else if(found_type == LTTV_GOBJECT && 
+             LTTV_IS_IATTRIBUTE(*(v->v_gobject))) {
+        node = LTTV_IATTRIBUTE(*(v->v_gobject));
+      }
+      else {
+        g_strfreev(components);
+        return FALSE;
+      }
+    }
+  }
+}
+
+/* Shallow and deep copies */
+
+LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self)
+{
+  LttvIAttribute *copy;
+
+  LttvAttributeType t;
+
+  LttvAttributeValue v, v_copy;
+
+  LttvAttributeName name;
+
+  int i;
+
+  int nb_attributes = lttv_iattribute_get_number(self);
+
+  copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self),NULL));
+
+  for(i = 0 ; i < nb_attributes ; i++) {
+    t = lttv_iattribute_get(self, i, &name, &v);
+    v_copy = lttv_iattribute_add(copy, name, t);
+    lttv_iattribute_copy_value(t, v_copy, v);
+  }
+}
+
+LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self)
+{
+  LttvIAttribute *copy, *child;
+
+  LttvAttributeType t;
+
+  LttvAttributeValue v, v_copy;
+
+  LttvAttributeName name;
+
+  int i;
+
+  int nb_attributes = lttv_iattribute_get_number(self);
+
+  copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self), NULL));
+
+  for(i = 0 ; i < nb_attributes ; i++) {
+    t = lttv_iattribute_get(self, i, &name, &v);
+    v_copy = lttv_iattribute_add(copy, name, t);
+    if(t == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(*(v.v_gobject))) {
+      child = LTTV_IATTRIBUTE(*(v.v_gobject));
+      *(v_copy.v_gobject) = G_OBJECT(lttv_iattribute_deep_copy(child));
+    }
+    else lttv_iattribute_copy_value(t, v_copy, v);
+  }
+}
+
+void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, 
+    LttvAttributeValue src) 
+{
+  switch(t) {
+    case LTTV_INT:
+      *(dest.v_int) = *(src.v_int); 
+      break;
+
+    case LTTV_UINT:
+      *(dest.v_uint) = *(src.v_uint); 
+      break;
+
+    case LTTV_LONG:
+      *(dest.v_long) = *(src.v_long); 
+      break;
+
+    case LTTV_ULONG:
+      *(dest.v_ulong) = *(src.v_ulong); 
+      break;
+
+    case LTTV_FLOAT:
+      *(dest.v_float) = *(src.v_float); 
+      break;
+
+    case LTTV_DOUBLE: 
+      *(dest.v_double) = *(src.v_double); 
+      break;
+
+    case LTTV_TIME: 
+      *(dest.v_time) = *(src.v_time); 
+      break;
+
+    case LTTV_POINTER:
+      *(dest.v_pointer) = *(src.v_pointer); 
+      break;
+
+    case LTTV_STRING:
+      *(dest.v_string) = *(src.v_string); 
+      break;
+
+    case LTTV_GOBJECT:
+      *(dest.v_gobject) = *(src.v_gobject); 
+      break;
+
+    case LTTV_NONE:
+      break;
+  }
+}
+
+
diff --git a/ltt/branches/poly/lttv/main/module.c b/ltt/branches/poly/lttv/main/module.c
new file mode 100644 (file)
index 0000000..e225992
--- /dev/null
@@ -0,0 +1,302 @@
+
+/* module.c : Implementation of the module loading/unloading mechanism.
+ * 
+ */
+
+#include <lttv/module.h>
+
+#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
+#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
+
+struct _LttvModule
+{
+  GModule *module;
+  guint ref_count;
+  guint load_count;
+  GPtrArray *dependents;
+};
+
+
+/* Table of loaded modules and paths where to search for modules */
+
+static GHashTable *modules = NULL;
+
+static GPtrArray *modulesPaths = NULL;
+
+static void lttv_module_unload_all();
+
+
+void lttv_module_init(int argc, char **argv) 
+{
+  g_info("Init module.c");
+  modules = g_hash_table_new(g_str_hash, g_str_equal);
+  modulesPaths = g_ptr_array_new();
+}
+
+
+void lttv_module_destroy() 
+{  
+  int i;
+
+  g_info("Destroy module.c");
+
+  /* Unload all modules */
+  lttv_module_unload_all();
+
+  /* Free the modules paths pointer array as well as the elements */
+  for(i = 0; i < modulesPaths->len ; i++) {
+    g_free(modulesPaths->pdata[i]);
+  }
+  g_ptr_array_free(modulesPaths,TRUE) ;
+  modulesPaths = NULL;
+  
+  /* destroy the hash table */
+  g_hash_table_destroy(modules) ;
+  modules = NULL;
+}
+
+
+/* Add a new pathname to the modules loading search path */
+
+void lttv_module_path_add(const char *name) 
+{
+  g_info("Add module path %s", name);
+  g_ptr_array_add(modulesPaths,(char*)g_strdup(name));
+}
+
+
+static LttvModule *
+module_load(const char *name, int argc, char **argv) 
+{
+  GModule *gm;
+
+  LttvModule *m;
+
+  int i;
+
+  char *pathname;
+
+  const char *module_name;
+  
+  LttvModuleInit init_function;
+
+  g_info("Load module %s", name);
+
+  /* Try to find the module along all the user specified paths */
+
+  for(i = 0 ; i < modulesPaths->len ; i++) {
+    pathname = g_module_build_path(modulesPaths->pdata[i],name);
+    g_info("Try path %s", pathname);
+    gm = g_module_open(pathname,0);
+    g_free(pathname);    
+    
+    if(gm != NULL) break;
+    g_info("Trial failed, %s", g_module_error());
+  }
+
+  /* Try the default system path */
+
+  if(gm == NULL) {
+    pathname = g_module_build_path(NULL,name);
+    g_info("Try default path");
+    gm = g_module_open(pathname,0);
+    g_free(pathname);
+  }
+
+  /* Module cannot be found */
+  if(gm == NULL) {
+    g_info("Trial failed, %s", g_module_error());
+    g_info("Failed to load %s", name); 
+    return NULL;
+  }
+
+  /* Check if the module was already opened using the hopefully canonical name
+     returned by g_module_name. */
+
+  module_name = g_module_name(gm);
+
+  m = g_hash_table_lookup(modules, module_name);
+
+  if(m == NULL) {
+    g_info("Module %s (%s) loaded, call its init function", name, module_name);
+
+    /* Module loaded for the first time. Insert it in the table and call the
+       init function if any. */
+
+    m = g_new(LttvModule, 1);
+    m->module = gm;
+    m->ref_count = 0;
+    m->load_count = 0;
+    m->dependents = g_ptr_array_new();
+    g_hash_table_insert(modules, (gpointer)module_name, m);
+
+    if(!g_module_symbol(gm, "init", (gpointer)&init_function)) {
+      g_warning("module %s (%s) has no init function", name, pathname);
+    }
+    else init_function(m, argc, argv);
+  }
+  else {
+
+    /* Module was already opened, check that it really is the same and
+       undo the extra g_module_open */
+
+    g_info("Module %s (%s) was already loaded, no need to call init function",
+          name, module_name);
+    if(m->module != gm) g_error("Two gmodules with the same pathname");
+    g_module_close(gm);
+  }
+  m->ref_count++;
+  return m;
+}
+
+
+LttvModule *
+lttv_module_load(const char *name, int argc, char **argv) 
+{
+  g_info("Load module %s explicitly", name);
+  LttvModule *m = module_load(name, argc, argv);
+  if(m != NULL) m->load_count++;
+  return m;
+}
+
+
+LttvModule *
+lttv_module_require(LttvModule *m, const char *name, int argc, char **argv)
+{
+  LttvModule *module;
+
+  g_info("Load module %s, as %s is a dependent requiring it", name, 
+      g_module_name(m->module));
+  module = module_load(name, argc, argv);
+  if(module != NULL) g_ptr_array_add(module->dependents, m);
+  return module;
+}
+
+
+static void module_unload(LttvModule *m) 
+{
+  LttvModuleDestroy destroy_function;
+
+  char *pathname;
+
+  guint i, len;
+
+  /* Decrement the reference count */
+
+  g_info("Unload module %s", g_module_name(m->module));
+  m->ref_count--;
+  if(m->ref_count > 0) {
+    g_info("Module usage count decremented to %d", m->ref_count);
+    return;
+  }
+  /* We really have to unload the module, first unload its dependents */
+
+  len = m->dependents->len;
+  g_info("Unload dependent modules");
+
+  for(i = 0 ; i < len ; i++) {
+    module_unload(m->dependents->pdata[i]);
+  }
+
+  if(len != m->dependents->len) g_error("dependents list modified");
+
+  /* Unload the module itself */
+
+  g_info("Call the destroy function and unload the module");
+  if(!g_module_symbol(m->module, "destroy", (gpointer)&destroy_function)) {
+    g_warning("module (%s) has no destroy function", pathname);
+  }
+  else destroy_function();
+
+  g_hash_table_remove(modules, g_module_name(m->module));
+  g_ptr_array_free(m->dependents, TRUE);
+  g_module_close(m->module);
+  g_free(m);
+}
+
+
+void lttv_module_unload(LttvModule *m) 
+{
+  g_info("Explicitly unload module %s", g_module_name(m->module));
+  if(m->load_count <= 0) { 
+    g_error("more unload than load (%s)", g_module_name(m->module));
+    return;
+  }
+  m->load_count--;
+  module_unload(m);
+}
+
+
+static void
+list_modules(gpointer key, gpointer value, gpointer user_data)
+{
+  g_ptr_array_add((GPtrArray *)user_data, value);
+}
+
+
+LttvModule **
+lttv_module_list(guint *nb)
+{
+  GPtrArray *list = g_ptr_array_new();
+
+  LttvModule **array;
+
+  g_hash_table_foreach(modules, list_modules, list);
+  *nb = list->len;
+  array = (LttvModule **)list->pdata;
+  g_ptr_array_free(list, FALSE);
+  return array;
+}
+
+
+LttvModule **
+lttv_module_info(LttvModule *m, const char **name, 
+    guint *ref_count, guint *load_count, guint *nb_dependents)
+{
+  guint i, len = m->dependents->len;
+
+  LttvModule **array = g_new(LttvModule *, len);
+
+  *name = g_module_name(m->module);
+  *ref_count = m->ref_count;
+  *load_count = m->load_count;
+  *nb_dependents = len;
+  for(i = 0 ; i < len ; i++) array[i] = m->dependents->pdata[i];
+  return array;
+}
+
+char * 
+lttv_module_name(LttvModule *m)
+{
+  return g_module_name(m->module);
+}
+
+static void
+list_independent(gpointer key, gpointer value, gpointer user_data)
+{
+  LttvModule *m = (LttvModule *)value;
+
+  if(m->load_count > 0) g_ptr_array_add((GPtrArray *)user_data, m);
+}
+
+
+void
+lttv_module_unload_all()
+{
+  guint i;
+
+  LttvModule *m;
+
+  GPtrArray *independent_modules = g_ptr_array_new();
+
+  g_hash_table_foreach(modules, list_independent, independent_modules);
+
+  for(i = 0 ; i < independent_modules->len ; i++) {
+    m = (LttvModule *)independent_modules->pdata[i];
+    while(m->load_count > 0) lttv_module_unload(m);
+  }
+
+  g_ptr_array_free(independent_modules, TRUE);
+  if(g_hash_table_size(modules) != 0) g_warning("cannot unload all modules"); 
+}
diff --git a/ltt/branches/poly/lttv/main/processTrace.c b/ltt/branches/poly/lttv/main/processTrace.c
new file mode 100644 (file)
index 0000000..4a290dd
--- /dev/null
@@ -0,0 +1,812 @@
+
+#include <lttv/processTrace.h>
+#include <ltt/event.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/type.h>
+
+void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
+{
+  LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
+}
+
+
+void lttv_context_fini(LttvTracesetContext *self)
+{
+  LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
+}
+
+
+LttvTracesetContext *
+lttv_context_new_traceset_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
+}
+
+
+
+
+LttvTraceContext * 
+lttv_context_new_trace_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
+}
+
+
+LttvTracefileContext *
+lttv_context_new_tracefile_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
+}
+
+/****************************************************************************
+ * lttv_traceset_context_compute_time_span
+ *
+ * Keep the Time_Span is sync with on the fly addition and removal of traces
+ * in a trace set. It must be called each time a trace is added/removed from
+ * the traceset. It could be more efficient to call it only once a bunch
+ * of traces are loaded, but the calculation is not long, so it's not
+ * critical.
+ *
+ * Author : Xang Xiu Yang
+ * Imported from gtkTraceSet.c by Mathieu Desnoyers
+ ***************************************************************************/
+static void lttv_traceset_context_compute_time_span(
+                                          LttvTracesetContext *self,
+                                         TimeInterval *Time_Span)
+{
+  LttvTraceset * traceset = self->ts;
+  int numTraces = lttv_traceset_number(traceset);
+  int i;
+  LttTime s, e;
+  LttvTraceContext *tc;
+  LttTrace * trace;
+
+  for(i=0; i<numTraces;i++){
+    tc = self->traces[i];
+    trace = tc->t;
+
+    ltt_trace_time_span_get(trace, &s, &e);
+
+    if(i==0){
+      Time_Span->startTime = s;
+      Time_Span->endTime   = e;
+    }else{
+      if(s.tv_sec < Time_Span->startTime.tv_sec ||
+        (s.tv_sec == Time_Span->startTime.tv_sec 
+          && s.tv_nsec < Time_Span->startTime.tv_nsec))
+       Time_Span->startTime = s;
+      if(e.tv_sec > Time_Span->endTime.tv_sec ||
+        (e.tv_sec == Time_Span->endTime.tv_sec &&
+          e.tv_nsec > Time_Span->endTime.tv_nsec))
+       Time_Span->endTime = e;      
+    }
+  }
+}
+
+
+static void
+init(LttvTracesetContext *self, LttvTraceset *ts)
+{
+  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTracefileContext *tfc;
+
+  LttTime null_time = {0, 0};
+
+  nb_trace = lttv_traceset_number(ts);
+  self->ts = ts;
+  self->traces = g_new(LttvTraceContext *, nb_trace);
+  self->before = lttv_hooks_new();
+  self->after = lttv_hooks_new();
+  self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  self->ts_a = lttv_traceset_attribute(ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
+    self->traces[i] = tc;
+
+    tc->ts_context = self;
+    tc->index = i;
+    tc->vt = lttv_traceset_get(ts, i);
+    tc->t = lttv_trace(tc->vt);
+    tc->check = lttv_hooks_new();
+    tc->before = lttv_hooks_new();
+    tc->after = lttv_hooks_new();
+    tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    tc->t_a = lttv_trace_attribute(tc->vt);
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    tc->control_tracefiles = g_new(LttvTracefileContext *, nb_control);
+    tc->per_cpu_tracefiles = g_new(LttvTracefileContext *, nb_per_cpu);
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
+      if(j < nb_control) {
+        tc->control_tracefiles[j] = tfc;
+        tfc->control = TRUE;
+        tfc->index = j;
+        tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
+      }
+      else {
+        tc->per_cpu_tracefiles[j - nb_control] = tfc;
+        tfc->control = FALSE;
+        tfc->index = j - nb_control;
+        tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
+      }
+      tfc->t_context = tc;
+      tfc->check = lttv_hooks_new();
+      tfc->before = lttv_hooks_new();
+      tfc->after = lttv_hooks_new();
+      tfc->check_event = lttv_hooks_new();
+      tfc->before_event = lttv_hooks_new();
+      tfc->before_event_by_id = lttv_hooks_by_id_new();
+      tfc->after_event = lttv_hooks_new();
+      tfc->after_event_by_id = lttv_hooks_by_id_new();
+      tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    }
+  }
+  lttv_process_traceset_seek_time(self, null_time);
+  /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
+  self->Time_Span = g_new(TimeInterval,1);
+  lttv_traceset_context_compute_time_span(self, self->Time_Span);
+}
+
+
+void fini(LttvTracesetContext *self)
+{
+  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTracefileContext *tfc;
+
+  LttvTraceset *ts = self->ts;
+
+  g_free(self->Time_Span);
+
+  lttv_hooks_destroy(self->before);
+  lttv_hooks_destroy(self->after);
+  //FIXME : segfault
+  g_object_unref(self->a);
+
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+
+    lttv_hooks_destroy(tc->check);
+    lttv_hooks_destroy(tc->before);
+    lttv_hooks_destroy(tc->after);
+    g_object_unref(tc->a);
+
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) tfc = tc->control_tracefiles[j];
+      else tfc = tc->per_cpu_tracefiles[j - nb_control];
+
+      lttv_hooks_destroy(tfc->check);
+      lttv_hooks_destroy(tfc->before);
+      lttv_hooks_destroy(tfc->after);
+      lttv_hooks_destroy(tfc->check_event);
+      lttv_hooks_destroy(tfc->before_event);
+      lttv_hooks_by_id_destroy(tfc->before_event_by_id);
+      lttv_hooks_destroy(tfc->after_event);
+      lttv_hooks_by_id_destroy(tfc->after_event_by_id);
+      g_object_unref(tfc->a);
+      g_object_unref(tfc);
+    }
+    g_free(tc->control_tracefiles);
+    g_free(tc->per_cpu_tracefiles);
+    g_object_unref(tc);
+  }
+  g_free(self->traces);
+}
+
+
+void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
+    LttvHooks *before_traceset, 
+    LttvHooks *after_traceset,
+    LttvHooks *check_trace, 
+    LttvHooks *before_trace, 
+    LttvHooks *after_trace, 
+    LttvHooks *check_tracefile,
+    LttvHooks *before_tracefile,
+    LttvHooks *after_tracefile,
+    LttvHooks *check_event, 
+    LttvHooks *before_event, 
+    LttvHooks *after_event)
+{
+  LttvTraceset *ts = self->ts;
+
+  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTracefileContext *tfc;
+
+  void *hook_data;
+
+  lttv_hooks_add_list(self->before, before_traceset);
+  lttv_hooks_add_list(self->after, after_traceset);
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+    lttv_hooks_add_list(tc->check, check_trace);
+    lttv_hooks_add_list(tc->before, before_trace);
+    lttv_hooks_add_list(tc->after, after_trace);
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfc = tc->control_tracefiles[j];
+      }
+      else {
+        tfc = tc->per_cpu_tracefiles[j-nb_control];
+      }
+      lttv_hooks_add_list(tfc->check, check_tracefile);
+      lttv_hooks_add_list(tfc->before, before_tracefile);
+      lttv_hooks_add_list(tfc->after, after_tracefile);
+      lttv_hooks_add_list(tfc->check_event, check_event);
+      lttv_hooks_add_list(tfc->before_event, before_event);
+      lttv_hooks_add_list(tfc->after_event, after_event);
+    }
+  }
+}
+
+
+void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
+    LttvHooks *before_traceset, 
+    LttvHooks *after_traceset,
+    LttvHooks *check_trace, 
+    LttvHooks *before_trace, 
+    LttvHooks *after_trace, 
+    LttvHooks *check_tracefile,
+    LttvHooks *before_tracefile,
+    LttvHooks *after_tracefile,
+    LttvHooks *check_event, 
+    LttvHooks *before_event, 
+    LttvHooks *after_event)
+{
+  LttvTraceset *ts = self->ts;
+
+  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTracefileContext *tfc;
+
+  void *hook_data;
+
+  lttv_hooks_remove_list(self->before, before_traceset);
+  lttv_hooks_remove_list(self->after, after_traceset);
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+    lttv_hooks_remove_list(tc->check, check_trace);
+    lttv_hooks_remove_list(tc->before, before_trace);
+    lttv_hooks_remove_list(tc->after, after_trace);
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfc = tc->control_tracefiles[j];
+      }
+      else {
+        tfc = tc->per_cpu_tracefiles[j-nb_control];
+      }
+      lttv_hooks_remove_list(tfc->check, check_tracefile);
+      lttv_hooks_remove_list(tfc->before, before_tracefile);
+      lttv_hooks_remove_list(tfc->after, after_tracefile);
+      lttv_hooks_remove_list(tfc->check_event, check_event);
+      lttv_hooks_remove_list(tfc->before_event, before_event);
+      lttv_hooks_remove_list(tfc->after_event, after_event);
+    }
+  }
+}
+
+void lttv_trace_context_add_hooks(LttvTraceContext *tc,
+                                 LttvHooks *check_trace, 
+                                 LttvHooks *before_trace, 
+                                 LttvHooks *after_trace)
+{
+  lttv_hooks_add_list(tc->check, check_trace);
+  lttv_hooks_add_list(tc->before, before_trace);
+  lttv_hooks_add_list(tc->after, after_trace);
+}
+
+void lttv_trace_context_remove_hooks(LttvTraceContext *tc,
+                                    LttvHooks *check_trace, 
+                                    LttvHooks *before_trace, 
+                                    LttvHooks *after_trace)
+{
+  lttv_hooks_remove_list(tc->check, check_trace);
+  lttv_hooks_remove_list(tc->before, before_trace);
+  lttv_hooks_remove_list(tc->after, after_trace);
+}
+
+void lttv_tracefile_context_add_hooks(LttvTracefileContext *tfc,
+                                     LttvHooks *check_tracefile,
+                                     LttvHooks *before_tracefile,
+                                     LttvHooks *after_tracefile,
+                                     LttvHooks *check_event, 
+                                     LttvHooks *before_event, 
+                                     LttvHooks *after_event)
+{
+  lttv_hooks_add_list(tfc->check, check_tracefile);
+  lttv_hooks_add_list(tfc->before, before_tracefile);
+  lttv_hooks_add_list(tfc->after, after_tracefile);
+  lttv_hooks_add_list(tfc->check_event, check_event);
+  lttv_hooks_add_list(tfc->before_event, before_event);
+  lttv_hooks_add_list(tfc->after_event, after_event);
+}
+
+void lttv_tracefile_context_remove_hooks(LttvTracefileContext *tfc,
+                                        LttvHooks *check_tracefile,
+                                        LttvHooks *before_tracefile,
+                                        LttvHooks *after_tracefile,
+                                        LttvHooks *check_event, 
+                                        LttvHooks *before_event, 
+                                        LttvHooks *after_event)
+{
+  lttv_hooks_remove_list(tfc->check, check_tracefile);
+  lttv_hooks_remove_list(tfc->before, before_tracefile);
+  lttv_hooks_remove_list(tfc->after, after_tracefile);
+  lttv_hooks_remove_list(tfc->check_event, check_event);
+  lttv_hooks_remove_list(tfc->before_event, before_event);
+  lttv_hooks_remove_list(tfc->after_event, after_event);
+}
+
+void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
+                                           unsigned i,
+                                           LttvHooks *before_event_by_id, 
+                                           LttvHooks *after_event_by_id)
+{
+  LttvHooks * h;
+  h = lttv_hooks_by_id_find(tfc->before_event_by_id, i);
+  lttv_hooks_add_list(h, before_event_by_id);
+  h = lttv_hooks_by_id_find(tfc->after_event_by_id, i);
+  lttv_hooks_add_list(h, after_event_by_id);
+}
+
+void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
+                                              unsigned i)
+{
+  lttv_hooks_by_id_remove(tfc->before_event_by_id, i);
+  lttv_hooks_by_id_remove(tfc->after_event_by_id, i);
+}
+
+static LttvTracesetContext *
+new_traceset_context(LttvTracesetContext *self)
+{
+  return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
+}
+
+
+static LttvTraceContext * 
+new_trace_context(LttvTracesetContext *self)
+{
+  return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
+}
+
+
+static LttvTracefileContext *
+new_tracefile_context(LttvTracesetContext *self)
+{
+  return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
+}
+
+
+static void
+traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  /* Be careful of anything which would not work well with shallow copies */
+}
+
+
+static void
+traceset_context_finalize (LttvTracesetContext *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
+      ->finalize(G_OBJECT(self));
+}
+
+
+static void
+traceset_context_class_init (LttvTracesetContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
+  klass->init = init;
+  klass->fini = fini;
+  klass->new_traceset_context = new_traceset_context;
+  klass->new_trace_context = new_trace_context;
+  klass->new_tracefile_context = new_tracefile_context;
+}
+
+
+GType 
+lttv_traceset_context_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracesetContextClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) traceset_context_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracesetContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  /* Be careful of anything which would not work well with shallow copies */
+}
+
+
+static void
+trace_context_finalize (LttvTraceContext *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+trace_context_class_init (LttvTraceContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
+}
+
+
+GType 
+lttv_trace_context_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTraceContextClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) trace_context_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTraceContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) trace_context_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+  /* Be careful of anything which would not work well with shallow copies */
+}
+
+
+static void
+tracefile_context_finalize (LttvTracefileContext *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
+      ->finalize(G_OBJECT(self));
+}
+
+
+static void
+tracefile_context_class_init (LttvTracefileContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
+}
+
+
+GType 
+lttv_tracefile_context_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracefileContextClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) tracefile_context_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracefileContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) tracefile_context_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+gint compare_tracefile(gconstpointer a, gconstpointer b)
+{
+  return ltt_time_compare(*((LttTime *)a), *((LttTime *)b));
+}
+
+
+gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
+  *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
+  return TRUE;
+}
+
+
+void lttv_process_traceset(LttvTracesetContext *self, LttTime end, 
+    unsigned maxNumEvents)
+{
+  GPtrArray *traces = g_ptr_array_new();
+
+  GPtrArray *tracefiles = g_ptr_array_new();
+
+  GTree *pqueue = g_tree_new(compare_tracefile);
+
+  guint i, j, nbi, nbj, id, nb_control, nb_cpu;
+
+  LttTrace *trace;
+
+  LttvTraceContext *tc;
+
+  LttTracefile *tracefile;
+
+  LttvTracefileContext *tfc;
+
+  LttEvent *event;
+
+  unsigned count = 0;
+
+  LttTime previous_timestamp = {0, 0};
+
+  /* Call all before_traceset, before_trace, and before_tracefile hooks.
+     For all qualifying tracefiles, seek to the start time, create a context,
+     read one event and insert in the pqueue based on the event time. */
+
+  lttv_hooks_call(self->before, self);
+  nbi = lttv_traceset_number(self->ts);
+
+  for(i = 0 ; i < nbi ; i++) {
+    tc = self->traces[i];
+    trace = tc->t;
+
+    if(!lttv_hooks_call_check(tc->check, tc)) {
+      g_ptr_array_add(traces, tc);
+      lttv_hooks_call(tc->before, tc);
+      nb_control = ltt_trace_control_tracefile_number(trace);
+      nb_cpu = ltt_trace_per_cpu_tracefile_number(trace);
+      nbj = nb_control + nb_cpu;
+
+      for(j = 0 ; j < nbj ; j++) {
+        if(j < nb_control) {
+          tfc = tc->control_tracefiles[j];
+        }
+        else {
+          tfc = tc->per_cpu_tracefiles[j - nb_control];
+        }
+
+        tracefile = tfc->tf;
+
+        if(!lttv_hooks_call_check(tfc->check, tfc)) {
+          g_ptr_array_add(tracefiles, tfc);
+          lttv_hooks_call(tfc->before, tfc);
+
+          if(tfc->e != NULL) {
+           if(tfc->timestamp.tv_sec < end.tv_sec ||
+              (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec)){
+             g_tree_insert(pqueue, &(tfc->timestamp), tfc);
+           }
+          }
+        }
+      }
+    }
+  }
+
+  /* Get the next event from the pqueue, call its hooks, 
+     reinsert in the pqueue the following event from the same tracefile 
+     unless the tracefile is finished or the event is later than the 
+     start time. */
+
+  while(TRUE) {
+    tfc = NULL;
+    g_tree_foreach(pqueue, get_first, &tfc);
+    if(tfc == NULL) break;
+
+    /* Have we reached the maximum number of events specified? However,
+       continue for all the events with the same time stamp (CHECK?). Then,
+       empty the queue and break from the loop. */
+
+    count++;
+    if(count > maxNumEvents){
+      if(tfc->timestamp.tv_sec == previous_timestamp.tv_sec &&
+        tfc->timestamp.tv_nsec == previous_timestamp.tv_nsec) {
+       count--;
+      }else{   
+       while(TRUE){
+         tfc = NULL;
+         g_tree_foreach(pqueue, get_first, &tfc);
+         if(tfc == NULL) break;
+         g_tree_remove(pqueue, &(tfc->timestamp));
+       }
+       break;
+      }
+    }
+    previous_timestamp = tfc->timestamp;
+
+
+    /* Get the tracefile with an event for the smallest time found. If two
+       or more tracefiles have events for the same time, hope that lookup
+       and remove are consistent. */
+
+    tfc = g_tree_lookup(pqueue, &(tfc->timestamp));
+    g_tree_remove(pqueue, &(tfc->timestamp));
+
+    if(!lttv_hooks_call(tfc->check_event, tfc)) {
+      id = ltt_event_eventtype_id(tfc->e);
+      lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
+      lttv_hooks_call(tfc->before_event, tfc);
+      lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
+      lttv_hooks_call(tfc->after_event, tfc);
+    }
+
+    event = ltt_tracefile_read(tfc->tf);
+    if(event != NULL) {
+      tfc->e = event;
+      tfc->timestamp = ltt_event_time(event);
+      if(tfc->timestamp.tv_sec < end.tv_sec ||
+        (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec))
+       g_tree_insert(pqueue, &(tfc->timestamp), tfc);
+    }
+  }
+
+  /* Call all the after_tracefile, after_trace and after_traceset hooks. */
+
+  for(i = 0, j = 0 ; i < traces->len ; i++) {
+    tc = traces->pdata[i];
+    while(j < tracefiles->len) {
+      tfc = tracefiles->pdata[j];
+
+      if(tfc->t_context == tc) {
+        lttv_hooks_call(tfc->after, tfc);
+        j++;
+      }
+      else break;
+    }
+    lttv_hooks_call(tc->after, tc);
+  }
+
+  g_assert(j == tracefiles->len);
+  lttv_hooks_call(self->after, self);
+
+  /* Free the traces, tracefiles and pqueue */
+
+  g_ptr_array_free(tracefiles, TRUE);
+  g_ptr_array_free(traces, TRUE);
+  g_tree_destroy(pqueue);
+}
+
+
+void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
+{
+  guint i, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTracefileContext *tfc;
+
+  LttEvent *event;
+
+  nb_control = ltt_trace_control_tracefile_number(self->t);
+  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->t);
+  nb_tracefile = nb_control + nb_per_cpu;
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    if(i < nb_control) tfc = self->control_tracefiles[i];
+    else tfc = self->per_cpu_tracefiles[i - nb_control];
+
+    ltt_tracefile_seek_time(tfc->tf, start);
+    event = ltt_tracefile_read(tfc->tf);
+    tfc->e = event;
+    if(event != NULL) tfc->timestamp = ltt_event_time(event);
+  }
+}
+
+
+void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
+{
+  guint i, nb_trace;
+
+  LttvTraceContext *tc;
+
+  nb_trace = lttv_traceset_number(self->ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->traces[i];
+    lttv_process_trace_seek_time(tc, start);
+  }
+}
+
+
+static LttField *
+find_field(LttEventType *et, const char *field)
+{
+  LttType *t;
+
+  LttField *f;
+
+  guint i, nb;
+
+  char *name;
+
+  if(field == NULL) return NULL;
+
+  f = ltt_eventtype_field(et);
+  t = ltt_eventtype_type(et);
+  g_assert(ltt_type_class(t) == LTT_STRUCT);
+  nb = ltt_type_member_number(t);
+  for(i = 0 ; i < nb ; i++) {
+    ltt_type_member_type(t, i, &name);
+    if(strcmp(name, field) == 0) break;
+  }
+  g_assert(i < nb);
+  return ltt_field_member(f, i);
+}
+
+
+void 
+lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, 
+    char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
+{
+  LttFacility *f;
+
+  LttEventType *et;
+
+  guint nb, pos, i;
+
+  char *name;
+
+  nb = ltt_trace_facility_find(t, facility, &pos);
+  if(nb < 1) g_error("No %s facility", facility);
+  f = ltt_trace_facility_get(t, pos);
+  et = ltt_facility_eventtype_get_by_name(f, event_type);
+  if(et == NULL) g_error("Event %s does not exist", event_type);
+
+  th->h = h;
+  th->id = ltt_eventtype_id(et);
+  th->f1 = find_field(et, field1);
+  th->f2 = find_field(et, field2);
+  th->f3 = find_field(et, field3);
+}
+
+
diff --git a/ltt/branches/poly/lttv/main/state.c b/ltt/branches/poly/lttv/main/state.c
new file mode 100644 (file)
index 0000000..dbdb11c
--- /dev/null
@@ -0,0 +1,1198 @@
+
+#include <lttv/state.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+
+LttvExecutionMode
+  LTTV_STATE_MODE_UNKNOWN,
+  LTTV_STATE_USER_MODE,
+  LTTV_STATE_SYSCALL,
+  LTTV_STATE_TRAP,
+  LTTV_STATE_IRQ;
+
+LttvExecutionSubmode
+  LTTV_STATE_SUBMODE_UNKNOWN,
+  LTTV_STATE_SUBMODE_NONE;
+
+LttvProcessStatus
+  LTTV_STATE_UNNAMED,
+  LTTV_STATE_WAIT_FORK,
+  LTTV_STATE_WAIT_CPU,
+  LTTV_STATE_EXIT,
+  LTTV_STATE_WAIT,
+  LTTV_STATE_RUN;
+
+static GQuark
+  LTTV_STATE_TRACEFILES,
+  LTTV_STATE_PROCESSES,
+  LTTV_STATE_PROCESS,
+  LTTV_STATE_EVENT,
+  LTTV_STATE_SAVED_STATES,
+  LTTV_STATE_TIME,
+  LTTV_STATE_HOOKS;
+
+
+static void fill_name_tables(LttvTraceState *tcs);
+
+static void free_name_tables(LttvTraceState *tcs);
+
+static void lttv_state_free_process_table(GHashTable *processes);
+
+static LttvProcessState *create_process(LttvTracefileState *tfs, 
+                                LttvProcessState *parent, guint pid);
+
+void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
+{
+  LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container);
+}
+
+
+void lttv_state_restore(LttvTraceState *self, LttvAttribute *container)
+{
+  LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
+}
+
+
+void lttv_state_saved_state_free(LttvTraceState *self, 
+    LttvAttribute *container)
+{
+  LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
+}
+
+
+static void
+restore_init_state(LttvTraceState *self)
+{
+  guint i, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTracefileState *tfcs;
+  
+  LttTime null_time = {0,0};
+
+  if(self->processes != NULL) lttv_state_free_process_table(self->processes);
+  self->processes = g_hash_table_new(g_direct_hash, g_direct_equal);
+  self->nb_event = 0;
+
+  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
+  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
+  nb_tracefile = nb_control + nb_per_cpu;
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    if(i < nb_control) {
+      tfcs = LTTV_TRACEFILE_STATE(self->parent.control_tracefiles[i]);
+    }
+    else {
+      tfcs = LTTV_TRACEFILE_STATE(self->parent.per_cpu_tracefiles[i - nb_control]);
+    }
+
+    tfcs->parent.timestamp = null_time;
+    tfcs->saved_position = 0;
+    tfcs->process = create_process(tfcs, NULL,0);
+  }
+}
+
+
+static void
+init(LttvTracesetState *self, LttvTraceset *ts)
+{
+  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTraceState *tcs;
+
+  LttvTracefileState *tfcs;
+  
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
+      init((LttvTracesetContext *)self, ts);
+
+  nb_trace = lttv_traceset_number(ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tc = self->parent.traces[i];
+    tcs = (LttvTraceState *)tc;
+    tcs->save_interval = 100000;
+    fill_name_tables(tcs);
+
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfcs = LTTV_TRACEFILE_STATE(tc->control_tracefiles[j]);
+      }
+      else {
+        tfcs = LTTV_TRACEFILE_STATE(tc->per_cpu_tracefiles[j - nb_control]);
+      }
+      tfcs->cpu_name= g_quark_from_string(ltt_tracefile_name(tfcs->parent.tf));
+    }
+    tcs->processes = NULL;
+    restore_init_state(tcs);
+  }
+}
+
+
+static void
+fini(LttvTracesetState *self)
+{
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceState *tcs;
+
+  LttvTracefileState *tfcs;
+
+  nb_trace = lttv_traceset_number(LTTV_TRACESET_CONTEXT(self)->ts);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]);
+    lttv_state_free_process_table(tcs->processes);
+    tcs->processes = NULL;
+    free_name_tables(tcs);
+  }
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
+      fini((LttvTracesetContext *)self);
+}
+
+
+static LttvTracesetContext *
+new_traceset_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATE_TYPE, NULL));
+}
+
+
+static LttvTraceContext * 
+new_trace_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATE_TYPE, NULL));
+}
+
+
+static LttvTracefileContext *
+new_tracefile_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATE_TYPE, NULL));
+}
+
+
+static void copy_process_state(gpointer key, gpointer value,gpointer user_data)
+{
+  LttvProcessState *process, *new_process;
+
+  GHashTable *new_processes = (GHashTable *)user_data;
+
+  guint i;
+
+  process = (LttvProcessState *)value;
+  new_process = g_new(LttvProcessState, 1);
+  *new_process = *process;
+  new_process->execution_stack = g_array_new(FALSE, FALSE, 
+      sizeof(LttvExecutionState));
+  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) =
+        g_array_index(process->execution_stack, LttvExecutionState, i);
+  }
+  new_process->state = &g_array_index(new_process->execution_stack, 
+      LttvExecutionState, new_process->execution_stack->len - 1);
+  g_hash_table_insert(new_processes, GUINT_TO_POINTER(new_process->pid), 
+      new_process);
+}
+
+
+static GHashTable *lttv_state_copy_process_table(GHashTable *processes)
+{
+  GHashTable *new_processes = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+  g_hash_table_foreach(processes, copy_process_state, new_processes);
+  return new_processes;
+}
+
+
+/* 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
+   to the current process and a "position" member storing the tracefile
+   position (needed to seek to the current "next" event. */
+
+static void state_save(LttvTraceState *self, LttvAttribute *container)
+{
+  guint i, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttribute *tracefiles_tree, *tracefile_tree;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttEventPosition *ep;
+
+  tracefiles_tree = lttv_attribute_find_subdir(container, 
+      LTTV_STATE_TRACEFILES);
+
+  value = lttv_attribute_add(container, LTTV_STATE_PROCESSES,
+      LTTV_POINTER);
+  *(value.v_pointer) = lttv_state_copy_process_table(self->processes);
+
+  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
+  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
+  nb_tracefile = nb_control + nb_per_cpu;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    if(i < nb_control) 
+        tfcs = (LttvTracefileState *)self->parent.control_tracefiles[i];
+    else tfcs = (LttvTracefileState *)
+        self->parent.per_cpu_tracefiles[i - nb_control];
+
+    tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    value = lttv_attribute_add(tracefiles_tree, i, 
+        LTTV_GOBJECT);
+    *(value.v_gobject) = (GObject *)tracefile_tree;
+    value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS, 
+        LTTV_UINT);
+    *(value.v_uint) = tfcs->process->pid;
+    value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT, 
+        LTTV_POINTER);
+    if(tfcs->parent.e == NULL) *(value.v_pointer) = NULL;
+    else {
+      ep = ltt_event_position_new();
+      ltt_event_position(tfcs->parent.e, ep);
+      *(value.v_pointer) = ep;
+    }
+  }
+}
+
+
+static void state_restore(LttvTraceState *self, LttvAttribute *container)
+{
+  guint i, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttribute *tracefiles_tree, *tracefile_tree;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttEventPosition *ep;
+
+  tracefiles_tree = lttv_attribute_find_subdir(container, 
+      LTTV_STATE_TRACEFILES);
+
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, 
+      &value);
+  g_assert(type == LTTV_POINTER);
+  lttv_state_free_process_table(self->processes);
+  self->processes = lttv_state_copy_process_table(*(value.v_pointer));
+
+  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
+  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
+  nb_tracefile = nb_control + nb_per_cpu;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    if(i < nb_control) tfcs = (LttvTracefileState *)
+        self->parent.control_tracefiles[i];
+    else tfcs = (LttvTracefileState *)
+        self->parent.per_cpu_tracefiles[i - nb_control];
+
+    type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
+    g_assert(type == LTTV_GOBJECT);
+    tracefile_tree = *((LttvAttribute **)(value.v_gobject));
+
+    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS, 
+        &value);
+    g_assert(type == LTTV_UINT);
+    tfcs->process = lttv_state_find_process(tfcs, *(value.v_uint));
+    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, 
+        &value);
+    g_assert(type == LTTV_POINTER);
+    if(*(value.v_pointer) == NULL) tfcs->parent.e = NULL;
+    else {
+      ep = *(value.v_pointer);
+      ltt_tracefile_seek_position(tfcs->parent.tf, ep);
+      tfcs->parent.e = ltt_tracefile_read(tfcs->parent.tf);
+      tfcs->parent.timestamp = ltt_event_time(tfcs->parent.e);
+    }
+  }
+}
+
+
+static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
+{
+  guint i, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTracefileState *tfcs;
+
+  LttvAttribute *tracefiles_tree, *tracefile_tree;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  LttEventPosition *ep;
+
+  tracefiles_tree = lttv_attribute_find_subdir(container, 
+      LTTV_STATE_TRACEFILES);
+  lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES);
+
+  type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, 
+      &value);
+  g_assert(type == LTTV_POINTER);
+  lttv_state_free_process_table(*(value.v_pointer));
+  *(value.v_pointer) = NULL;
+  lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
+
+  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
+  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
+  nb_tracefile = nb_control + nb_per_cpu;
+
+  for(i = 0 ; i < nb_tracefile ; i++) {
+    if(i < nb_control) tfcs = (LttvTracefileState *)
+        self->parent.control_tracefiles[i];
+    else tfcs = (LttvTracefileState *)
+        self->parent.per_cpu_tracefiles[i - nb_control];
+
+    type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
+    g_assert(type == LTTV_GOBJECT);
+    tracefile_tree = *((LttvAttribute **)(value.v_gobject));
+
+    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, 
+        &value);
+    g_assert(type == LTTV_POINTER);
+    if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer));
+  }
+  lttv_attribute_recursive_free(tracefiles_tree);
+}
+
+
+static void 
+fill_name_tables(LttvTraceState *tcs) 
+{
+  int i, nb;
+
+  char *f_name, *e_name;
+
+  LttvTraceHook h;
+
+  LttEventType *et;
+
+  LttType *t;
+
+  GString *fe_name = g_string_new("");
+
+  nb = ltt_trace_eventtype_number(tcs->parent.t);
+  tcs->eventtype_names = g_new(GQuark, nb);
+  for(i = 0 ; i < nb ; i++) {
+    et = ltt_trace_eventtype_get(tcs->parent.t, i);
+    e_name = ltt_eventtype_name(et);
+    f_name = ltt_facility_name(ltt_eventtype_facility(et));
+    g_string_printf(fe_name, "%s.%s", f_name, e_name);
+    tcs->eventtype_names[i] = g_quark_from_string(fe_name->str);    
+  }
+
+  lttv_trace_find_hook(tcs->parent.t, "core", "syscall_entry",
+      "syscall_id", NULL, NULL, NULL, &h);
+  t = ltt_field_type(h.f1);
+  nb = ltt_type_element_number(t);
+
+  /* CHECK syscalls should be an emun but currently are not!  
+  tcs->syscall_names = g_new(GQuark, nb);
+
+  for(i = 0 ; i < nb ; i++) {
+    tcs->syscall_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
+  }
+  */
+
+  tcs->syscall_names = g_new(GQuark, 256);
+  for(i = 0 ; i < 256 ; i++) {
+    g_string_printf(fe_name, "syscall %d", i);
+    tcs->syscall_names[i] = g_quark_from_string(fe_name->str);
+  }
+
+  lttv_trace_find_hook(tcs->parent.t, "core", "trap_entry",
+      "trap_id", NULL, NULL, NULL, &h);
+  t = ltt_field_type(h.f1);
+  nb = ltt_type_element_number(t);
+
+  /*
+  tcs->trap_names = g_new(GQuark, nb);
+  for(i = 0 ; i < nb ; i++) {
+    tcs->trap_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
+  }
+  */
+
+  tcs->trap_names = g_new(GQuark, 256);
+  for(i = 0 ; i < 256 ; i++) {
+    g_string_printf(fe_name, "trap %d", i);
+    tcs->trap_names[i] = g_quark_from_string(fe_name->str);
+  }
+
+  lttv_trace_find_hook(tcs->parent.t, "core", "irq_entry",
+      "irq_id", NULL, NULL, NULL, &h);
+  t = ltt_field_type(h.f1);
+  nb = ltt_type_element_number(t);
+
+  /*
+  tcs->irq_names = g_new(GQuark, nb);
+  for(i = 0 ; i < nb ; i++) {
+    tcs->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
+  }
+  */
+
+  tcs->irq_names = g_new(GQuark, 256);
+  for(i = 0 ; i < 256 ; i++) {
+    g_string_printf(fe_name, "irq %d", i);
+    tcs->irq_names[i] = g_quark_from_string(fe_name->str);
+  }
+
+  g_string_free(fe_name, TRUE);
+}
+
+
+static void 
+free_name_tables(LttvTraceState *tcs) 
+{
+  g_free(tcs->eventtype_names);
+  g_free(tcs->syscall_names);
+  g_free(tcs->trap_names);
+  g_free(tcs->irq_names);
+} 
+
+
+static void push_state(LttvTracefileState *tfs, LttvExecutionMode t, 
+    guint state_id)
+{
+  LttvExecutionState *es;
+
+  LttvProcessState *process = tfs->process;
+
+  guint depth = process->execution_stack->len;
+
+  g_array_set_size(process->execution_stack, depth + 1);
+  es = &g_array_index(process->execution_stack, LttvExecutionState, depth);
+  es->t = t;
+  es->n = state_id;
+  es->entry = es->change = tfs->parent.timestamp;
+  es->s = process->state->s;
+  process->state = es;
+}
+
+
+static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t)
+{
+  LttvProcessState *process = tfs->process;
+
+  guint depth = process->execution_stack->len - 1;
+
+  if(process->state->t != t){
+    g_warning("Different execution mode type (%d.%09d): ignore it\n",
+        tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
+    g_warning("process state has %s when pop_int is %s\n",
+                   g_quark_to_string(process->state->t),
+                   g_quark_to_string(t));
+    g_warning("{ %u, %u, %s, %s }\n",
+                   process->pid,
+                   process->ppid,
+                   g_quark_to_string(process->name),
+                   g_quark_to_string(process->state->s));
+    return;
+  }
+
+  if(depth == 0){
+    g_warning("Trying to pop last state on stack (%d.%09d): ignore it\n",
+        tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
+    return;
+  }
+
+  g_array_remove_index(process->execution_stack, depth);
+  depth--;
+  process->state = &g_array_index(process->execution_stack, LttvExecutionState,
+      depth);
+  process->state->change = tfs->parent.timestamp;
+}
+
+
+static LttvProcessState *create_process(LttvTracefileState *tfs, 
+    LttvProcessState *parent, guint pid)
+{
+  LttvProcessState *process = g_new(LttvProcessState, 1);
+
+  LttvExecutionState *es;
+
+  LttvTraceContext *tc;
+
+  LttvTraceState *tcs;
+
+  char buffer[128];
+
+  tcs = (LttvTraceState *)tc = tfs->parent.t_context;
+       
+  g_hash_table_insert(tcs->processes, GUINT_TO_POINTER(pid), process);
+  process->pid = pid;
+
+  if(parent) {
+    process->ppid = parent->pid;
+    process->name = parent->name;
+  }
+  else {
+    process->ppid = 0;
+    process->name = LTTV_STATE_UNNAMED;
+  }
+
+  process->creation_time = tfs->parent.timestamp;
+  sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec, 
+         process->creation_time.tv_nsec);
+  process->pid_time = g_quark_from_string(buffer);
+  process->execution_stack = g_array_new(FALSE, FALSE, 
+      sizeof(LttvExecutionState));
+  g_array_set_size(process->execution_stack, 1);
+  es = process->state = &g_array_index(process->execution_stack, 
+      LttvExecutionState, 0);
+  es->t = LTTV_STATE_USER_MODE;
+  es->n = LTTV_STATE_SUBMODE_NONE;
+  es->entry = tfs->parent.timestamp;
+  es->change = tfs->parent.timestamp;
+  es->s = LTTV_STATE_WAIT_FORK;
+
+  return process;
+}
+
+
+LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs, 
+    guint pid)
+{
+  LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
+  LttvProcessState *process = g_hash_table_lookup(ts->processes, 
+      GUINT_TO_POINTER(pid));
+  if(process == NULL) process = create_process(tfs, NULL, pid);
+  return process;
+}
+
+
+static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) 
+{
+  LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context);
+
+  g_hash_table_remove(ts->processes, GUINT_TO_POINTER(process->pid));
+  g_array_free(process->execution_stack, TRUE);
+  g_free(process);
+}
+
+
+static void free_process_state(gpointer key, gpointer value,gpointer user_data)
+{
+  g_array_free(((LttvProcessState *)value)->execution_stack, TRUE);
+  g_free(value);
+}
+
+
+static void lttv_state_free_process_table(GHashTable *processes)
+{
+  g_hash_table_foreach(processes, free_process_state, NULL);
+  g_hash_table_destroy(processes);
+}
+
+
+static gboolean syscall_entry(void *hook_data, void *call_data)
+{
+  LttField *f = ((LttvTraceHook *)hook_data)->f1;
+
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  LttvExecutionSubmode submode;
+
+  submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[
+      ltt_event_get_unsigned(s->parent.e, f)];
+  push_state(s, LTTV_STATE_SYSCALL, submode);
+  return FALSE;
+}
+
+
+static gboolean syscall_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  pop_state(s, LTTV_STATE_SYSCALL);
+  return FALSE;
+}
+
+
+static gboolean trap_entry(void *hook_data, void *call_data)
+{
+  LttField *f = ((LttvTraceHook *)hook_data)->f1;
+
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  LttvExecutionSubmode submode;
+
+  submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[
+      ltt_event_get_unsigned(s->parent.e, f)];
+  push_state(s, LTTV_STATE_TRAP, submode);
+  return FALSE;
+}
+
+
+static gboolean trap_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  pop_state(s, LTTV_STATE_TRAP);
+  return FALSE;
+}
+
+
+static gboolean irq_entry(void *hook_data, void *call_data)
+{
+  LttField *f = ((LttvTraceHook *)hook_data)->f1;
+
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  LttvExecutionSubmode submode;
+
+  submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[
+      ltt_event_get_unsigned(s->parent.e, f)];
+
+  /* Do something with the info about being in user or system mode when int? */
+  push_state(s, LTTV_STATE_IRQ, submode);
+  return FALSE;
+}
+
+
+static gboolean irq_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  pop_state(s, LTTV_STATE_IRQ);
+  return FALSE;
+}
+
+
+static gboolean schedchange(void *hook_data, void *call_data)
+{
+  LttvTraceHook *h = (LttvTraceHook *)hook_data;
+
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  guint pid_in, pid_out, state_out;
+
+  pid_in = ltt_event_get_unsigned(s->parent.e, h->f1);
+  pid_out = ltt_event_get_unsigned(s->parent.e, h->f2);
+  state_out = ltt_event_get_unsigned(s->parent.e, h->f3);
+
+  if(s->process != NULL) {
+
+    if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
+    else if(s->process->state->s == LTTV_STATE_EXIT) 
+        exit_process(s, s->process);
+    else s->process->state->s = LTTV_STATE_WAIT;
+
+    if(s->process->pid == 0)
+      s->process->pid = pid_out;
+
+    s->process->state->change = s->parent.timestamp;
+  }
+  s->process = lttv_state_find_process(s, pid_in);
+  s->process->state->s = LTTV_STATE_RUN;
+  s->process->state->change = s->parent.timestamp;
+  return FALSE;
+}
+
+
+static gboolean process_fork(void *hook_data, void *call_data)
+{
+  LttField *f = ((LttvTraceHook *)hook_data)->f1;
+
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  guint child_pid;
+
+  child_pid = ltt_event_get_unsigned(s->parent.e, f);
+  create_process(s, s->process, child_pid);
+  return FALSE;
+}
+
+
+static gboolean process_exit(void *hook_data, void *call_data)
+{
+  LttvTracefileState *s = (LttvTracefileState *)call_data;
+
+  if(s->process != NULL) {
+    s->process->state->s = LTTV_STATE_EXIT;
+  }
+  return FALSE;
+}
+
+
+void lttv_state_add_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  GArray *hooks;
+
+  LttvTraceHook hook;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceState *)self->parent.traces[i];
+
+    /* Find the eventtype id for the following events and register the
+       associated by id hooks. */
+
+    hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+    g_array_set_size(hooks, 9);
+
+    lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id", 
+       NULL, NULL, syscall_entry, &g_array_index(hooks, LttvTraceHook, 0));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL, 
+        NULL, syscall_exit, &g_array_index(hooks, LttvTraceHook, 1));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
+       NULL, NULL, trap_entry, &g_array_index(hooks, LttvTraceHook, 2));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL, 
+        trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL, 
+        NULL, irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL, 
+        irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out", 
+        "out_state", schedchange, &g_array_index(hooks, LttvTraceHook, 6));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid", 
+        NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
+
+    lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL, 
+        NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
+
+    /* Add these hooks to each before_event_by_id hooks list */
+
+    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
+      }
+      else {
+        tfs = LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
+      }
+
+      for(k = 0 ; k < hooks->len ; k++) {
+        hook = g_array_index(hooks, LttvTraceHook, k);
+        lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, 
+         hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
+      }
+    }
+    lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
+    *(val.v_pointer) = hooks;
+  }
+}
+
+
+void lttv_state_remove_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  GArray *hooks;
+
+  LttvTraceHook hook;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = LTTV_TRACE_STATE(self->parent.traces[i]);
+    lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
+    hooks = *(val.v_pointer);
+
+    /* Add these hooks to each before_event_by_id hooks list */
+
+    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
+      }
+      else {
+        tfs = LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
+      }
+
+      for(k = 0 ; k < hooks->len ; k++) {
+        hook = g_array_index(hooks, LttvTraceHook, k);
+        lttv_hooks_remove_data(
+            lttv_hooks_by_id_find(tfs->parent.after_event_by_id, 
+           hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
+      }
+    }
+    g_array_free(hooks, TRUE);
+  }
+}
+
+
+static gboolean block_end(void *hook_data, void *call_data)
+{
+  LttvTracefileState *tfcs = (LttvTracefileState *)call_data;
+
+  LttvTraceState *tcs = (LttvTraceState *)(tfcs->parent.t_context);
+
+  LttEventPosition *ep = ltt_event_position_new();
+
+  guint nb_block, nb_event;
+
+  LttTracefile *tf;
+
+  LttvAttribute *saved_states_tree, *saved_state_tree;
+
+  LttvAttributeValue value;
+
+  ltt_event_position(tfcs->parent.e, ep);
+
+  ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
+  tcs->nb_event += nb_event - tfcs->saved_position;
+  tfcs->saved_position = 0;
+  if(tcs->nb_event >= tcs->save_interval) {
+    saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, 
+        LTTV_STATE_SAVED_STATES);
+    saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+    value = lttv_attribute_add(saved_states_tree, 
+        lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT);
+    *(value.v_gobject) = (GObject *)saved_state_tree;
+    value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
+    *(value.v_time) = tfcs->parent.timestamp;
+    lttv_state_save(tcs, saved_state_tree);
+    tcs->nb_event = 0;
+  }
+  return FALSE;
+}
+
+
+void lttv_state_save_add_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  LttvTraceHook hook;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceState *)self->parent.traces[i];
+    lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, 
+       NULL, NULL, block_end, &hook);
+
+    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
+      }
+      else {
+        tfs =LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
+      }
+
+      lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, 
+         hook.id), hook.h, NULL);
+    }
+  }
+}
+
+
+void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceState *ts;
+
+  LttvTracefileState *tfs;
+
+  LttvTraceHook hook;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = LTTV_TRACE_STATE(self->parent.traces[i]);
+    lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, 
+       NULL, NULL, block_end, &hook);
+
+    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
+      }
+      else {
+        tfs =LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
+      }
+
+      lttv_hooks_remove_data(lttv_hooks_by_id_find(
+          tfs->parent.after_event_by_id, hook.id), hook.h, NULL);
+    }
+  }
+}
+
+
+void lttv_state_restore_closest_state(LttvTracesetState *self, LttTime t)
+{
+  LttvTraceset *traceset = self->parent.ts;
+
+  guint i, j, nb_trace, nb_saved_state;
+
+  int min_pos, mid_pos, max_pos;
+
+  LttvTraceState *tcs;
+
+  LttvAttributeValue value;
+
+  LttvAttributeType type;
+
+  LttvAttributeName name;
+
+  LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceState *)self->parent.traces[i];
+
+    saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
+        LTTV_STATE_SAVED_STATES);
+    min_pos = -1;
+    max_pos = lttv_attribute_get_number(saved_states_tree) - 1;
+    mid_pos = max_pos / 2;
+    while(min_pos < max_pos) {
+      type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value);
+      g_assert(type == LTTV_GOBJECT);
+      saved_state_tree = *((LttvAttribute **)(value.v_gobject));
+      type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME, 
+          &value);
+      g_assert(type == LTTV_TIME);
+      if(ltt_time_compare(*(value.v_time), t) < 0) {
+        min_pos = mid_pos;
+        closest_tree = saved_state_tree;
+      }
+      else max_pos = mid_pos - 1;
+
+      mid_pos = (min_pos + max_pos + 1) / 2;
+    }
+    if(min_pos == -1) {
+      restore_init_state(tcs);
+      lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
+    }
+    else lttv_state_restore(tcs, closest_tree);
+  }
+}
+
+
+static void
+traceset_state_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+traceset_state_finalize (LttvTracesetState *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+traceset_state_class_init (LttvTracesetContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) traceset_state_finalize;
+  klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
+  klass->fini = (void (*)(LttvTracesetContext *self))fini;
+  klass->new_traceset_context = new_traceset_context;
+  klass->new_trace_context = new_trace_context;
+  klass->new_tracefile_context = new_tracefile_context;
+}
+
+
+GType 
+lttv_traceset_state_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracesetStateClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) traceset_state_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracesetContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) traceset_state_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+trace_state_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+trace_state_finalize (LttvTraceState *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_CONTEXT_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+trace_state_class_init (LttvTraceStateClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) trace_state_finalize;
+  klass->state_save = state_save;
+  klass->state_restore = state_restore;
+  klass->state_saved_free = state_saved_free;
+}
+
+
+GType 
+lttv_trace_state_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTraceStateClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) trace_state_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTraceState),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) trace_state_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE, 
+        "LttvTraceStateType", &info, 0);
+  }
+  return type;
+}
+
+
+static void
+tracefile_state_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+tracefile_state_finalize (LttvTracefileState *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_CONTEXT_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+tracefile_state_class_init (LttvTracefileStateClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) tracefile_state_finalize;
+}
+
+
+GType 
+lttv_tracefile_state_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracefileStateClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) tracefile_state_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracefileState),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) tracefile_state_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE, 
+        "LttvTracefileStateType", &info, 0);
+  }
+  return type;
+}
+
+
+void lttv_state_init(int argc, char **argv)
+{
+  LTTV_STATE_UNNAMED = g_quark_from_string("unnamed");
+  LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("unknown execution mode");
+  LTTV_STATE_USER_MODE = g_quark_from_string("user mode");
+  LTTV_STATE_WAIT_FORK = g_quark_from_string("wait fork");
+  LTTV_STATE_SYSCALL = g_quark_from_string("system call");
+  LTTV_STATE_TRAP = g_quark_from_string("trap");
+  LTTV_STATE_IRQ = g_quark_from_string("irq");
+  LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("unknown submode");
+  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_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");
+  LTTV_STATE_PROCESSES = g_quark_from_string("processes");
+  LTTV_STATE_PROCESS = g_quark_from_string("process");
+  LTTV_STATE_EVENT = g_quark_from_string("event");
+  LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states");
+  LTTV_STATE_TIME = g_quark_from_string("time");
+  LTTV_STATE_HOOKS = g_quark_from_string("saved state hooks");
+}
+
+void lttv_state_destroy() 
+{
+}
+
+
+
+
diff --git a/ltt/branches/poly/lttv/main/stats.c b/ltt/branches/poly/lttv/main/stats.c
new file mode 100644 (file)
index 0000000..4265853
--- /dev/null
@@ -0,0 +1,1180 @@
+
+#include <stdio.h>
+#include <lttv/stats.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/event.h>
+
+#define BUF_SIZE 256
+
+GQuark
+  LTTV_STATS_PROCESS_UNKNOWN,
+  LTTV_STATS_PROCESSES,
+  LTTV_STATS_CPU,
+  LTTV_STATS_MODE_TYPES,
+  LTTV_STATS_MODES,
+  LTTV_STATS_SUBMODES,
+  LTTV_STATS_EVENT_TYPES,
+  LTTV_STATS_CPU_TIME,
+  LTTV_STATS_ELAPSED_TIME,
+  LTTV_STATS_EVENTS,
+  LTTV_STATS_EVENTS_COUNT;
+
+static GQuark
+  LTTV_STATS_BEFORE_HOOKS,
+  LTTV_STATS_AFTER_HOOKS;
+
+static void remove_all_processes(GHashTable *processes);
+
+static void
+find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu,
+    GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, 
+    LttvAttribute **event_types_tree);
+
+static void
+init(LttvTracesetStats *self, LttvTraceset *ts)
+{
+  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceContext *tc;
+
+  LttvTraceStats *tcs;
+
+  LttvTracefileContext *tfc;
+
+  LttvTracefileStats *tfcs;
+  
+  LttTime timestamp = {0,0};
+
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
+      init((LttvTracesetContext *)self, ts);
+
+  self->stats = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]);
+    tcs->stats = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+
+    nb_control = ltt_trace_control_tracefile_number(tc->t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfcs = LTTV_TRACEFILE_STATS(tc->control_tracefiles[j]);
+      }
+      else {
+        tfcs = LTTV_TRACEFILE_STATS(tc->per_cpu_tracefiles[j - nb_control]);
+      }
+
+      tfcs->stats = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+      find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
+          tfcs->parent.cpu_name, LTTV_STATE_MODE_UNKNOWN, 
+          LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
+          &tfcs->current_event_types_tree);
+    }
+  }
+}
+
+
+static void
+fini(LttvTracesetStats *self)
+{
+  guint i, j, nb_trace, nb_tracefile;
+
+  LttvTraceset *ts;
+
+  LttvTraceContext *tc;
+
+  LttvTraceStats *tcs;
+
+  LttvTracefileContext *tfc;
+
+  LttvTracefileStats *tfcs;
+  
+  LttTime timestamp = {0,0};
+
+  lttv_attribute_recursive_free(self->stats);
+  ts = self->parent.parent.ts;
+  nb_trace = lttv_traceset_number(ts);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]);
+    lttv_attribute_recursive_free(tcs->stats);
+
+    nb_tracefile = ltt_trace_control_tracefile_number(tc->t);
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfcs = (LttvTracefileStats *)tfc = tc->control_tracefiles[j];
+      lttv_attribute_recursive_free(tfcs->stats);
+      tfcs->current_events_tree = NULL;
+      tfcs->current_event_types_tree = NULL;
+    }
+
+    nb_tracefile = ltt_trace_per_cpu_tracefile_number(tc->t);
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfcs = (LttvTracefileStats *)tfc = tc->per_cpu_tracefiles[j];
+      lttv_attribute_recursive_free(tfcs->stats);
+      tfcs->current_events_tree = NULL;
+      tfcs->current_event_types_tree = NULL;
+    }
+  }
+  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
+      fini((LttvTracesetContext *)self);
+}
+
+
+static LttvTracesetContext *
+new_traceset_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL));
+}
+
+
+static LttvTraceContext * 
+new_trace_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL));
+}
+
+
+static LttvTracefileContext *
+new_tracefile_context(LttvTracesetContext *self)
+{
+  return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL));
+}
+
+
+static void
+traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+traceset_stats_finalize (LttvTracesetStats *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+traceset_stats_class_init (LttvTracesetContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize;
+  klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
+  klass->fini = (void (*)(LttvTracesetContext *self))fini;
+  klass->new_traceset_context = new_traceset_context;
+  klass->new_trace_context = new_trace_context;
+  klass->new_tracefile_context = new_tracefile_context;
+}
+
+
+GType 
+lttv_traceset_stats_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracesetStatsClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) traceset_stats_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracesetContext),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) traceset_stats_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (LTTV_TRACESET_STATE_TYPE, "LttvTracesetStatsType", 
+        &info, 0);
+  }
+  return type;
+}
+
+
+static void
+trace_stats_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+trace_stats_finalize (LttvTraceStats *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+trace_stats_class_init (LttvTraceContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize;
+}
+
+
+GType 
+lttv_trace_stats_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTraceStatsClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) trace_stats_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTraceStats),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) trace_stats_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (LTTV_TRACE_STATE_TYPE, 
+        "LttvTraceStatsType", &info, 0);
+  }
+  return type;
+}
+
+
+static void
+tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+}
+
+
+static void
+tracefile_stats_finalize (LttvTracefileStats *self)
+{
+  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))->
+      finalize(G_OBJECT(self));
+}
+
+
+static void
+tracefile_stats_class_init (LttvTracefileStatsClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize;
+}
+
+
+GType 
+lttv_tracefile_stats_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (LttvTracefileStatsClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) tracefile_stats_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (LttvTracefileStats),
+      0,      /* n_preallocs */
+      (GInstanceInitFunc) tracefile_stats_instance_init    /* instance_init */
+    };
+
+    type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE, 
+        "LttvTracefileStatsType", &info, 0);
+  }
+  return type;
+}
+
+
+static void
+find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu,
+    GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, 
+    LttvAttribute **event_types_tree)
+{
+  LttvAttribute *a;
+
+  LttvTraceStats *tcs = LTTV_TRACE_STATS(tfcs->parent.parent.t_context);
+  a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES);
+  a = lttv_attribute_find_subdir(a, tfcs->parent.process->pid_time);
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU);
+  a = lttv_attribute_find_subdir(a, tfcs->parent.cpu_name);
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES);
+  a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->t);
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES);
+  a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->n);
+  *events_tree = a;
+  a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES);
+  *event_types_tree = a;
+}
+
+
+static void update_event_tree(LttvTracefileStats *tfcs) 
+{
+  LttvExecutionState *es = tfcs->parent.process->state;
+
+  find_event_tree(tfcs, tfcs->parent.process->pid_time, tfcs->parent.cpu_name, 
+      es->t, es->n, &(tfcs->current_events_tree), 
+      &(tfcs->current_event_types_tree));
+}
+
+
+static void mode_change(LttvTracefileStats *tfcs)
+{
+  LttvAttributeValue cpu_time; 
+
+  LttTime delta;
+
+  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, 
+      LTTV_TIME, &cpu_time);
+  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
+      tfcs->parent.process->state->change);
+  *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
+}
+
+
+static void mode_end(LttvTracefileStats *tfcs)
+{
+  LttvAttributeValue elapsed_time, cpu_time; 
+
+  LttTime delta;
+
+  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME, 
+      LTTV_TIME, &elapsed_time);
+  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
+      tfcs->parent.process->state->entry);
+  *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
+
+  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, 
+      LTTV_TIME, &cpu_time);
+  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
+      tfcs->parent.process->state->change);
+  *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
+}
+
+
+static gboolean before_syscall_entry(void *hook_data, void *call_data)
+{
+  mode_change((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+static gboolean after_syscall_entry(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_syscall_exit(void *hook_data, void *call_data)
+{
+  mode_end((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+static gboolean after_syscall_exit(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_trap_entry(void *hook_data, void *call_data)
+{
+  mode_change((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+static gboolean after_trap_entry(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_trap_exit(void *hook_data, void *call_data)
+{
+  mode_end((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean after_trap_exit(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_irq_entry(void *hook_data, void *call_data)
+{
+  mode_change((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean after_irq_entry(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_irq_exit(void *hook_data, void *call_data)
+{
+  mode_end((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean after_irq_exit(void *hook_data, void *call_data)
+{
+  update_event_tree((LttvTracefileStats *)call_data);
+  return FALSE;
+}
+
+
+gboolean before_schedchange(void *hook_data, void *call_data)
+{
+  LttvTraceHook *h = (LttvTraceHook *)hook_data;
+
+  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+
+  guint pid_in, pid_out, state_out;
+
+  LttvProcessState *process;
+
+  pid_in = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f1);
+  pid_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f2);
+  state_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f3);
+
+  /* compute the time for the process to schedule out */
+
+  mode_change(tfcs);
+
+  /* get the information for the process scheduled in */
+
+  process = lttv_state_find_process(&(tfcs->parent), pid_in);
+
+  find_event_tree(tfcs, process->pid_time, tfcs->parent.cpu_name, 
+      process->state->t, process->state->n, &(tfcs->current_events_tree), 
+      &(tfcs->current_event_types_tree));
+
+  /* compute the time waiting for the process to schedule in */
+
+  mode_change(tfcs);
+  return FALSE;
+}
+
+
+gboolean process_fork(void *hook_data, void *call_data)
+{
+  /* nothing to do for now */
+  return FALSE;
+}
+
+
+gboolean process_exit(void *hook_data, void *call_data)
+{
+  /* We should probably exit all modes here or we could do that at 
+     schedule out. */
+  return FALSE;
+}
+
+
+gboolean every_event(void *hook_data, void *call_data)
+{
+  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+
+  LttvAttributeValue v;
+
+  /* The current branch corresponds to the tracefile/process/interrupt state.
+     Statistics are added within it, to count the number of events of this
+     type occuring in this context. A quark has been pre-allocated for each
+     event type and is used as name. */
+
+  lttv_attribute_find(tfcs->current_event_types_tree, 
+      ((LttvTraceState *)(tfcs->parent.parent.t_context))->
+      eventtype_names[ltt_event_eventtype_id(tfcs->parent.parent.e)], 
+      LTTV_UINT, &v);
+  (*(v.v_uint))++;
+  return FALSE;
+}
+
+
+static gboolean 
+sum_stats(void *hook_data, void *call_data)
+{
+  LttvTracesetStats *tscs = (LttvTracesetStats *)call_data;
+
+  LttvTraceStats *tcs;
+
+  LttvTraceset *traceset = tscs->parent.parent.ts;
+
+  LttvAttributeType type;
+
+  LttvAttributeValue value;
+
+  LttvAttributeName name;
+
+  unsigned sum;
+
+  int i, j, k, l, m, n, nb_trace, nb_process, nb_cpu, nb_mode_type, nb_submode,
+      nb_event_type;
+
+  LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
+      *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
+      *submode_tree, *event_types_tree, *mode_events_tree,
+      *cpu_events_tree, *process_modes_tree, *trace_cpu_tree, 
+      *trace_modes_tree, *traceset_modes_tree;
+
+  traceset_modes_tree = lttv_attribute_find_subdir(tscs->stats, 
+      LTTV_STATS_MODES);
+  nb_trace = lttv_traceset_number(traceset);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]);
+    main_tree = tcs->stats;
+    processes_tree = lttv_attribute_find_subdir(main_tree, 
+        LTTV_STATS_PROCESSES);
+    trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES);
+    nb_process = lttv_attribute_get_number(processes_tree);
+
+    for(j = 0 ; j < nb_process ; j++) {
+      type = lttv_attribute_get(processes_tree, j, &name, &value);
+      process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+      cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
+      process_modes_tree = lttv_attribute_find_subdir(process_tree,
+          LTTV_STATS_MODES);
+      nb_cpu = lttv_attribute_get_number(cpus_tree);
+
+      for(k = 0 ; k < nb_cpu ; k++) {
+        type = lttv_attribute_get(cpus_tree, k, &name, &value);
+        cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+        mode_types_tree = lttv_attribute_find_subdir(cpu_tree, 
+            LTTV_STATS_MODE_TYPES);
+        cpu_events_tree = lttv_attribute_find_subdir(cpu_tree,
+            LTTV_STATS_EVENTS);
+        trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU);
+        trace_cpu_tree = lttv_attribute_find_subdir(trace_cpu_tree, name);
+        nb_mode_type = lttv_attribute_get_number(mode_types_tree);
+
+        for(l = 0 ; l < nb_mode_type ; l++) {
+          type = lttv_attribute_get(mode_types_tree, l, &name, &value);
+          mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+          submodes_tree = lttv_attribute_find_subdir(mode_tree, 
+              LTTV_STATS_SUBMODES);
+          mode_events_tree = lttv_attribute_find_subdir(mode_tree,
+             LTTV_STATS_EVENTS);
+          nb_submode = lttv_attribute_get_number(submodes_tree);
+
+          for(m = 0 ; m < nb_submode ; m++) {
+            type = lttv_attribute_get(submodes_tree, m, &name, &value);
+            submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+            event_types_tree = lttv_attribute_find_subdir(submode_tree, 
+              LTTV_STATS_EVENT_TYPES);
+            nb_event_type = lttv_attribute_get_number(event_types_tree);
+
+            sum = 0;
+            for(n = 0 ; n < nb_event_type ; n++) {
+              type = lttv_attribute_get(event_types_tree, n, &name, &value);
+              sum += *(value.v_uint);
+            }
+            lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT, 
+                LTTV_UINT, &value);
+            *(value.v_uint) = sum;
+            lttv_attribute_recursive_add(mode_events_tree, submode_tree);
+          }
+         lttv_attribute_recursive_add(cpu_events_tree, mode_events_tree);
+        }
+        lttv_attribute_recursive_add(process_modes_tree, cpu_tree);
+        lttv_attribute_recursive_add(trace_cpu_tree, cpu_tree);
+      }
+      lttv_attribute_recursive_add(trace_modes_tree, process_modes_tree);
+    }
+    lttv_attribute_recursive_add(traceset_modes_tree, trace_modes_tree);
+  }
+  return FALSE;
+}
+
+
+lttv_stats_add_event_hooks(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+
+  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttFacility *f;
+
+  LttEventType *et;
+
+  LttvTraceStats *ts;
+
+  LttvTracefileStats *tfs;
+
+  void *hook_data;
+
+  GArray *hooks, *before_hooks, *after_hooks;
+
+  LttvTraceHook hook;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceStats *)self->parent.parent.traces[i];
+
+    /* Find the eventtype id for the following events and register the
+       associated by id hooks. */
+
+    hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+    g_array_set_size(hooks, 7);
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry",
+        "syscall_id", NULL, NULL, before_syscall_entry, 
+        &g_array_index(hooks, LttvTraceHook, 0));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, 
+        NULL, NULL, before_syscall_exit, 
+        &g_array_index(hooks, LttvTraceHook, 1));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id",
+       NULL, NULL, before_trap_entry, 
+        &g_array_index(hooks, LttvTraceHook, 2));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL,
+       NULL, before_trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id",
+       NULL, NULL, before_irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL,
+       NULL, before_irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "schedchange", "in", 
+        "out", "out_state", before_schedchange, 
+         &g_array_index(hooks, LttvTraceHook, 6));
+
+    before_hooks = hooks;
+
+    hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+    g_array_set_size(hooks, 8);
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry",
+        "syscall_id", NULL, NULL, after_syscall_entry, 
+        &g_array_index(hooks, LttvTraceHook, 0));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, 
+        NULL, NULL, after_syscall_exit, 
+        &g_array_index(hooks, LttvTraceHook, 1));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id",
+       NULL, NULL, after_trap_entry, &g_array_index(hooks, LttvTraceHook, 2));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL,
+       NULL, after_trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id",
+       NULL, NULL, after_irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL,
+       NULL, after_irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "process_fork", 
+        "child_pid", NULL, NULL, process_fork, 
+        &g_array_index(hooks, LttvTraceHook, 6));
+
+    lttv_trace_find_hook(ts->parent.parent.t, "core", "process_exit", NULL, 
+        NULL, NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 7));
+
+    after_hooks = hooks;
+
+    /* Add these hooks to each before_event_by_id hooks list */
+
+    nb_control = ltt_trace_control_tracefile_number(ts->parent.parent.t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.control_tracefiles[j]);
+      }
+      else {
+        tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.per_cpu_tracefiles[
+            j-nb_control]);
+      }
+
+      lttv_hooks_add(tfs->parent.parent.after_event, every_event, NULL);
+
+      for(k = 0 ; k < before_hooks->len ; k++) {
+        hook = g_array_index(before_hooks, LttvTraceHook, k);
+        lttv_hooks_add(lttv_hooks_by_id_find(
+            tfs->parent.parent.before_event_by_id, 
+           hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k));
+      }
+      for(k = 0 ; k < after_hooks->len ; k++) {
+        hook = g_array_index(after_hooks, LttvTraceHook, k);
+        lttv_hooks_add(lttv_hooks_by_id_find(
+            tfs->parent.parent.after_event_by_id, 
+           hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k));
+      }
+    }
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
+        LTTV_POINTER, &val);
+    *(val.v_pointer) = before_hooks;
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, 
+        LTTV_POINTER, &val);
+    *(val.v_pointer) = after_hooks;
+  }
+  lttv_hooks_add(self->parent.parent.after, sum_stats, NULL);
+}
+
+
+lttv_stats_remove_event_hooks(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+
+  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
+
+  LttvTraceStats *ts;
+
+  LttvTracefileStats *tfs;
+
+  void *hook_data;
+
+  GArray *before_hooks, *after_hooks;
+
+  LttvTraceHook hook;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = LTTV_TRACE_STATS(self->parent.parent.traces[i]);
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
+        LTTV_POINTER, &val);
+    before_hooks = *(val.v_pointer);
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, 
+        LTTV_POINTER, &val);
+    after_hooks = *(val.v_pointer);
+
+    /* Add these hooks to each before_event_by_id hooks list */
+
+    nb_control = ltt_trace_control_tracefile_number(ts->parent.parent.t);
+    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t);
+    nb_tracefile = nb_control + nb_per_cpu;
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      if(j < nb_control) {
+        tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.control_tracefiles[j]);
+      }
+      else {
+        tfs =LTTV_TRACEFILE_STATS(ts->parent.parent.per_cpu_tracefiles[
+            j-nb_control]);
+      }
+
+      lttv_hooks_remove_data(tfs->parent.parent.after_event, every_event, 
+          NULL);
+
+      for(k = 0 ; k < before_hooks->len ; k++) {
+        hook = g_array_index(before_hooks, LttvTraceHook, k);
+        lttv_hooks_remove_data(
+            lttv_hooks_by_id_find(tfs->parent.parent.before_event_by_id, 
+           hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k));
+      }
+      for(k = 0 ; k < after_hooks->len ; k++) {
+        hook = g_array_index(after_hooks, LttvTraceHook, k);
+        lttv_hooks_remove_data(
+            lttv_hooks_by_id_find(tfs->parent.parent.after_event_by_id, 
+           hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k));
+      }
+    }
+    g_critical("lttv_stats_remove_event_hooks()");
+    g_array_free(before_hooks, TRUE);
+    g_array_free(after_hooks, TRUE);
+  }
+  lttv_hooks_remove_data(self->parent.parent.after, sum_stats, NULL);
+}
+
+
+void lttv_stats_init(int argc, char **argv)
+{
+  LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process");
+  LTTV_STATS_PROCESSES = g_quark_from_string("processes");
+  LTTV_STATS_CPU = g_quark_from_string("cpu");
+  LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types");
+  LTTV_STATS_MODES = g_quark_from_string("modes");
+  LTTV_STATS_SUBMODES = g_quark_from_string("submodes");
+  LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types");
+  LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time");
+  LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time");
+  LTTV_STATS_EVENTS = g_quark_from_string("events");
+  LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count");
+  LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks");
+  LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks");
+}
+
+void lttv_stats_destroy() 
+{
+}
+
+void lttv_stats_save_attribute(LttvAttribute *attr, char *indent, FILE * fp)
+{
+  LttvAttributeType type;
+  LttvAttributeValue value;
+  LttvAttributeName name;
+  char type_value[BUF_SIZE];
+  int i, nb_attr, flag;
+
+  nb_attr = lttv_attribute_get_number(attr);
+  for(i=0;i<nb_attr;i++){
+    flag = 1;
+    type = lttv_attribute_get(attr, i, &name, &value);
+    switch(type) {
+      case LTTV_INT:
+        sprintf(type_value, "%d\0", *value.v_int);
+        break;
+      case LTTV_UINT:
+        sprintf(type_value, "%u\0", *value.v_uint);
+        break;
+      case LTTV_LONG:
+        sprintf(type_value, "%ld\0", *value.v_long);
+        break;
+      case LTTV_ULONG:
+        sprintf(type_value, "%lu\0", *value.v_ulong);
+        break;
+      case LTTV_FLOAT:
+        sprintf(type_value, "%f\0", (double)*value.v_float);
+        break;
+      case LTTV_DOUBLE:
+        sprintf(type_value, "%f\0", *value.v_double);
+        break;
+      case LTTV_TIME:
+        sprintf(type_value, "%10u.%09u\0", value.v_time->tv_sec, 
+            value.v_time->tv_nsec);
+        break;
+      case LTTV_POINTER:
+        sprintf(type_value, "POINTER\0");
+        break;
+      case LTTV_STRING:
+        sprintf(type_value, "%s\0", *value.v_string);
+        break;
+      default:
+       flag = 0;
+        break;
+    }
+    if(flag == 0) continue;
+    fprintf(fp,"%s<VALUE type=\"%d\" name=\"%s\">",indent,type,g_quark_to_string(name));
+    fprintf(fp,"%s",type_value);
+    fprintf(fp,"</VALUE> \n");
+  }
+  
+}
+
+void lttv_stats_save_statistics(LttvTracesetStats *self)
+{
+  LttvTracesetStats *tscs = self;
+  LttvTraceStats *tcs;
+  LttvTraceset *traceset = tscs->parent.parent.ts;
+  LttvAttributeType type;
+  LttvAttributeValue value;
+  LttvAttributeName name;
+
+  char filename[BUF_SIZE];
+  FILE * fp;
+  char indent[10][24]= {"  ",
+                       "    ",
+                       "      ",
+                       "        ",
+                       "          ",
+                       "            ",
+                       "              ",
+                       "                ",
+                       "                  ",
+                       "                    "
+                       };
+  
+
+  int i, j, k, l, m, n, nb_trace, nb_process, nb_cpu, nb_mode_type, nb_submode;
+
+  LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
+      *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
+      *submode_tree, *event_types_tree;
+
+  nb_trace = lttv_traceset_number(traceset);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]);
+
+    filename[0] = '\0';
+    strcat(filename,ltt_trace_name(tcs->parent.parent.t));
+    strcat(filename,"/statistics.xml");
+    fp = fopen(filename,"w");
+    if(!fp){
+      g_warning("can not open the file %s for saving statistics\n", filename);
+      exit(1);
+    }    
+
+    main_tree = tcs->stats;
+    processes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_PROCESSES);
+    nb_process = lttv_attribute_get_number(processes_tree);
+
+    fprintf(fp, "<NODE name=\"%s\"> \n",g_quark_to_string(LTTV_STATS_PROCESSES)); //root NODE
+
+    for(j = 0 ; j < nb_process ; j++) {
+      type = lttv_attribute_get(processes_tree, j, &name, &value);
+      process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+      fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[0],g_quark_to_string(name)); //process NODE   
+      lttv_stats_save_attribute(process_tree,indent[1], fp);
+      fprintf(fp,"%s<NODE name=\"%s\"> \n", indent[1],g_quark_to_string(LTTV_STATS_CPU)); //cpus NODE
+      
+      cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
+      nb_cpu = lttv_attribute_get_number(cpus_tree);
+
+      for(k = 0 ; k < nb_cpu ; k++) {
+        type = lttv_attribute_get(cpus_tree, k, &name, &value);
+        cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+       fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[2],g_quark_to_string(name)); //cpu NODE
+       lttv_stats_save_attribute(cpu_tree,indent[3], fp);
+       fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[3],g_quark_to_string(LTTV_STATS_MODE_TYPES)); //mode_types NODE
+
+        mode_types_tree = lttv_attribute_find_subdir(cpu_tree,LTTV_STATS_MODE_TYPES);
+        nb_mode_type = lttv_attribute_get_number(mode_types_tree);
+
+        for(l = 0 ; l < nb_mode_type ; l++) {
+          type = lttv_attribute_get(mode_types_tree, l, &name, &value);
+          mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+
+         fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[4],g_quark_to_string(name)); //mode NODE
+         lttv_stats_save_attribute(mode_tree,indent[5], fp);
+         fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[5],g_quark_to_string(LTTV_STATS_SUBMODES)); //sub_modes NODE
+
+          submodes_tree = lttv_attribute_find_subdir(mode_tree,LTTV_STATS_SUBMODES);
+          nb_submode = lttv_attribute_get_number(submodes_tree);
+
+          for(m = 0 ; m < nb_submode ; m++) {
+            type = lttv_attribute_get(submodes_tree, m, &name, &value);
+            submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
+           fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[6],g_quark_to_string(name)); //sub_mode NODE
+           lttv_stats_save_attribute(submode_tree,indent[7], fp);
+           fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[7],g_quark_to_string(LTTV_STATS_EVENT_TYPES)); //event_types NODE
+
+            event_types_tree = lttv_attribute_find_subdir(submode_tree, LTTV_STATS_EVENT_TYPES);
+           lttv_stats_save_attribute(event_types_tree,indent[8], fp);
+
+           fprintf(fp,"%s</NODE> \n",indent[7]); //event_types NODE
+           fprintf(fp,"%s</NODE> \n",indent[6]); //sub_mode NODE
+          }
+         fprintf(fp,"%s</NODE> \n",indent[5]); //sub_modes NODE
+         fprintf(fp,"%s</NODE> \n",indent[4]); //mode NODE
+        }
+       fprintf(fp,"%s</NODE> \n",indent[3]); //mode_type NODE
+       fprintf(fp,"%s</NODE> \n",indent[2]); //cpu NODE
+      }
+      fprintf(fp,"%s</NODE> \n",indent[1]); //cpus NODE
+      fprintf(fp,"%s</NODE> \n", indent[0]); //process NODE
+    }
+    fprintf(fp, "</NODE>\n"); //root NODE
+    fclose(fp);
+  }
+}
+
+
+/* Functions to parse statistic.xml file (using glib xml parser) */
+
+typedef struct _ParserStruct{
+  GPtrArray * attribute;
+  LttvAttributeType type;
+  LttvAttributeName name;  
+} ParserStruct;
+
+static void stats_parser_start_element (GMarkupParseContext  *context,
+                                       const gchar          *element_name,
+                                       const gchar         **attribute_names,
+                                       const gchar         **attribute_values,
+                                       gpointer              user_data,
+                                       GError              **error)
+{
+  ParserStruct * parser = (ParserStruct *)user_data;
+  int len;
+  LttvAttributeType type;
+  LttvAttributeName name;
+  LttvAttribute * parent_att, *new_att;
+
+  len = parser->attribute->len;
+  parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1);
+
+  if(strcmp("NODE", element_name) == 0){
+    type = LTTV_GOBJECT;
+    name = g_quark_from_string(attribute_values[0]);
+    new_att = lttv_attribute_find_subdir(parent_att,name);
+    g_ptr_array_add(parser->attribute, (gpointer)new_att);
+  }else if(strcmp("VALUE", element_name) == 0){
+    parser->type = (LttvAttributeType) atoi(attribute_values[0]);
+    parser->name = g_quark_from_string(attribute_values[1]);    
+  }else{
+    g_warning("This is not statistics.xml file\n");
+    exit(1);
+  }
+}
+
+static void stats_parser_end_element   (GMarkupParseContext  *context,
+                                       const gchar          *element_name,
+                                       gpointer              user_data,
+                                       GError              **error)
+{
+  ParserStruct * parser = (ParserStruct *)user_data;
+  int len;
+  LttvAttribute * parent_att;
+
+  len = parser->attribute->len;
+  parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1);
+
+  if(strcmp("NODE", element_name) == 0){
+    g_ptr_array_remove_index(parser->attribute, len-1);
+  }else if(strcmp("VALUE", element_name) == 0){
+  }else{
+    g_warning("This is not statistics.xml file\n");
+    exit(1);
+  }
+  
+}
+
+static void  stats_parser_characters   (GMarkupParseContext  *context,
+                                       const gchar          *text,
+                                       gsize                 text_len,
+                                       gpointer              user_data,
+                                       GError              **error)
+{
+  ParserStruct * parser = (ParserStruct *)user_data;
+  LttvAttributeValue  value;
+  int len;
+  LttvAttribute * parent_att;
+  char *pos;
+
+  pos = (char*)text;
+  for(len=0;len<text_len;len++){
+    if(isspace(*pos)){
+      pos++;
+      continue;
+    }
+    break;
+  }
+  if(strlen(pos) == 0)return;
+
+  len = parser->attribute->len;
+  parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1);
+  if(!lttv_attribute_find(parent_att,parser->name, parser->type, &value)){
+    g_warning("can not find value\n");
+    exit(1);
+  }
+
+  switch(parser->type) {
+    case LTTV_INT:
+      *value.v_int = atoi(text);
+      break;
+    case LTTV_UINT:
+      *value.v_uint = (unsigned)atoi(text);
+      break;
+    case LTTV_LONG:
+      *value.v_long = atol(text);
+      break;
+    case LTTV_ULONG:
+      *value.v_ulong = (unsigned long)atol(text);
+      break;
+    case LTTV_FLOAT:
+      *value.v_float = atof(text);
+      break;
+    case LTTV_DOUBLE:
+      *value.v_float = atof(text);
+      break;
+    case LTTV_TIME:
+      pos = strrchr(text,'.');
+      if(pos){
+       *pos = '\0';
+       pos++;
+       value.v_time->tv_sec = atol(text);
+       value.v_time->tv_nsec = atol(pos);
+      }else{
+       g_warning("The time value format is wrong\n");
+       exit(1);
+      }
+      break;
+    case LTTV_POINTER:
+      break;
+    case LTTV_STRING:
+      *value.v_string = g_strdup(text);
+      break;
+    default:
+      break;
+  }
+
+}
+
+gboolean lttv_stats_load_statistics(LttvTracesetStats *self)
+{
+  FILE * fp;
+  char buf[BUF_SIZE];
+  LttvTracesetStats *tscs = self;
+  LttvTraceStats *tcs;
+  LttvTraceset *traceset = tscs->parent.parent.ts;
+  char filename[BUF_SIZE];
+
+  GMarkupParseContext * context;
+  GError * error;
+  GMarkupParser markup_parser =
+    {
+      stats_parser_start_element,
+      stats_parser_end_element,
+      stats_parser_characters,
+      NULL,  /*  passthrough  */
+      NULL   /*  error        */
+    };
+
+  int i, nb_trace;
+  LttvAttribute *main_tree;
+  ParserStruct a_parser_struct;
+  a_parser_struct.attribute = g_ptr_array_new(); 
+
+  nb_trace = lttv_traceset_number(traceset);
+
+  for(i = 0 ; i < nb_trace ; i++) {
+    tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]);
+
+    filename[0] = '\0';
+    strcat(filename,ltt_trace_name(tcs->parent.parent.t));
+    strcat(filename,"/statistics.xml");
+    fp = fopen(filename,"r");
+    if(!fp){
+      g_warning("can not open the file %s for reading statistics\n", filename);
+      return FALSE;
+    }    
+
+    main_tree = tcs->stats;
+    g_ptr_array_add(a_parser_struct.attribute,(gpointer)main_tree);
+
+    context = g_markup_parse_context_new(&markup_parser, 0, (gpointer)&a_parser_struct, NULL);
+    
+    while(fgets(buf,BUF_SIZE, fp) != NULL){
+      if(!g_markup_parse_context_parse(context, buf, BUF_SIZE, &error)){
+       g_warning("Can not parse xml file: \n%s\n", error->message);
+       exit(1);
+      }
+    }
+    fclose(fp);
+  }
+
+  sum_stats(NULL, (void *)self);
+
+  return TRUE;
+}
diff --git a/ltt/branches/poly/lttv/main/traceset.c b/ltt/branches/poly/lttv/main/traceset.c
new file mode 100644 (file)
index 0000000..ce96b99
--- /dev/null
@@ -0,0 +1,171 @@
+
+#include <lttv/traceset.h>
+#include <stdio.h>
+
+/* A trace is a sequence of events gathered in the same tracing session. The
+   events may be stored in several tracefiles in the same directory. 
+   A trace set is defined when several traces are to be analyzed together,
+   possibly to study the interactions between events in the different traces. 
+*/
+
+struct _LttvTraceset {
+  char * filename;
+  GPtrArray *traces;
+  LttvAttribute *a;
+};
+
+
+struct _LttvTrace {
+  LttTrace *t;
+  LttvAttribute *a;
+  guint ref_count;
+};
+
+
+LttvTraceset *lttv_traceset_new() 
+{
+  LttvTraceset *s;
+
+  s = g_new(LttvTraceset, 1);
+  s->filename = NULL;
+  s->traces = g_ptr_array_new();
+  s->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  return s;
+}
+
+char * lttv_traceset_name(LttvTraceset * s)
+{
+  return s->filename;
+}
+
+LttvTrace *lttv_trace_new(LttTrace *t) 
+{
+  LttvTrace *new_trace;
+
+  new_trace = g_new(LttvTrace, 1);
+  new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+  new_trace->t = t;
+  new_trace->ref_count = 0;
+  return new_trace;
+}
+
+
+LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig) 
+{
+  int i;
+  LttvTraceset *s;
+  LttvTrace * trace;
+
+  s = g_new(LttvTraceset, 1);
+  s->filename = NULL;
+  s->traces = g_ptr_array_new();
+  for(i=0;i<s_orig->traces->len;i++)
+  {
+    trace = g_ptr_array_index(s_orig->traces, i);
+    trace->ref_count++;
+
+    /*CHECK this used ltt_trace_copy while it may not be needed. Need to
+      define how traces and tracesets are shared */
+    g_ptr_array_add(
+        s->traces,
+       g_ptr_array_index(s_orig->traces, i));
+  }
+  s->a = LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig->a)));
+  return s;
+}
+
+
+LttvTraceset *lttv_traceset_load(const gchar *filename)
+{
+  LttvTraceset *s = g_new(LttvTraceset,1);
+  FILE *tf;
+  
+  s->filename = g_strdup(filename);
+  tf = fopen(filename,"r");
+
+  g_critical("NOT IMPLEMENTED : load traceset data from a XML file");
+  
+  fclose(tf);
+  return s;
+}
+
+gint lttv_traceset_save(LttvTraceset *s)
+{
+  FILE *tf;
+
+  tf = fopen(s->filename, "w");
+  
+  g_critical("NOT IMPLEMENTED : save traceset data in a XML file");
+
+  fclose(tf);
+  return 0;
+}
+
+void lttv_traceset_destroy(LttvTraceset *s) 
+{
+  g_ptr_array_free(s->traces, TRUE);
+  g_object_unref(s->a);
+  g_free(s);
+}
+
+void lttv_trace_destroy(LttvTrace *t) 
+{
+  g_object_unref(t->a);
+  g_free(t);
+}
+
+
+void lttv_traceset_add(LttvTraceset *s, LttvTrace *t) 
+{
+  t->ref_count++;
+  g_ptr_array_add(s->traces, t);
+}
+
+
+unsigned lttv_traceset_number(LttvTraceset *s) 
+{
+  return s->traces->len;
+}
+
+
+LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i) 
+{
+  g_assert(s->traces->len > i);
+  return ((LttvTrace *)s->traces->pdata[i]);
+}
+
+
+void lttv_traceset_remove(LttvTraceset *s, unsigned i) 
+{
+  LttvTrace * t;
+  g_assert(s->traces->len > i);
+  t = (LttvTrace *)s->traces->pdata[i];
+  t->ref_count--;
+  g_ptr_array_remove_index(s->traces, i);
+}
+
+
+/* A set of attributes is attached to each trace set, trace and tracefile
+   to store user defined data as needed. */
+
+LttvAttribute *lttv_traceset_attribute(LttvTraceset *s) 
+{
+  return s->a;
+}
+
+
+LttvAttribute *lttv_trace_attribute(LttvTrace *t)
+{
+  return t->a;
+}
+
+
+LttTrace *lttv_trace(LttvTrace *t)
+{
+  return t->t;
+}
+
+guint lttv_trace_get_ref_number(LttvTrace * t)
+{
+  return t->ref_count;
+}
diff --git a/ltt/branches/poly/lttv/mainLib/attribute.c b/ltt/branches/poly/lttv/mainLib/attribute.c
deleted file mode 100644 (file)
index 4b6938d..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-
-#include <lttv/attribute.h>
-#include <ltt/ltt.h>
-
-typedef union _AttributeValue {
-  int dv_int;
-  unsigned dv_uint;
-  long dv_long;
-  unsigned long dv_ulong;
-  float dv_float;
-  double dv_double;
-  LttTime dv_time;
-  gpointer dv_pointer;
-  char *dv_string;
-  GObject *dv_gobject;
-} AttributeValue;
-
-
-typedef struct _Attribute {
-  LttvAttributeName name;
-  LttvAttributeType type;
-  AttributeValue value;
-} Attribute;
-
-
-LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v)
-{
-  LttvAttributeValue va;
-
-  switch(t) {
-  case LTTV_INT: va.v_int = &v->dv_int; break;
-  case LTTV_UINT: va.v_uint = &v->dv_uint; break;
-  case LTTV_LONG: va.v_long = &v->dv_long; break;
-  case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break;
-  case LTTV_FLOAT: va.v_float = &v->dv_float; break;
-  case LTTV_DOUBLE: va.v_double = &v->dv_double; break;
-  case LTTV_TIME: va.v_time = &v->dv_time; break;
-  case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break;
-  case LTTV_STRING: va.v_string = &v->dv_string; break;
-  case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break;
-  }
-  return va;
-}
-
-
-AttributeValue init_value(LttvAttributeType t)
-{
-  AttributeValue v;
-
-  switch(t) {
-  case LTTV_INT: v.dv_int = 0; break;
-  case LTTV_UINT: v.dv_uint = 0; break;
-  case LTTV_LONG: v.dv_long = 0; break;
-  case LTTV_ULONG: v.dv_ulong = 0; break;
-  case LTTV_FLOAT: v.dv_float = 0; break;
-  case LTTV_DOUBLE: v.dv_double = 0; break;
-  case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break;
-  case LTTV_POINTER: v.dv_pointer = NULL; break;
-  case LTTV_STRING: v.dv_string = NULL; break;
-  case LTTV_GOBJECT: v.dv_gobject = NULL; break;
-  }
-  return v;
-}
-
-
-unsigned int 
-lttv_attribute_get_number(LttvAttribute *self)
-{
-  return self->attributes->len;
-}
-
-
-gboolean 
-lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous)
-{
-  *homogeneous = FALSE;
-  return TRUE;
-}
-
-
-LttvAttributeType 
-lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, 
-    LttvAttributeValue *v)
-{
-  Attribute *a;
-
-  a = &g_array_index(self->attributes, Attribute, i);
-  *name = a->name;
-  *v = address_of_value(a->type, &(a->value));
-  return a->type;
-}
-
-
-LttvAttributeType 
-lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name, 
-    LttvAttributeValue *v)
-{
-  Attribute *a;
-
-  unsigned i;
-
-  gpointer p;
-
-  p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(p == NULL) return LTTV_NONE;
-
-  i = GPOINTER_TO_UINT(p);
-  i--;
-  a = &g_array_index(self->attributes, Attribute, i);
-  *v = address_of_value(a->type, &(a->value));
-  return a->type;
-}
-
-
-LttvAttributeValue 
-lttv_attribute_add(LttvAttribute *self, LttvAttributeName name, 
-    LttvAttributeType t)
-{
-  unsigned i;
-
-  Attribute a, *pa;
-
-  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i != 0) g_error("duplicate entry in attribute table");
-
-  a.name = name;
-  a.type = t;
-  a.value = init_value(t);
-  g_array_append_val(self->attributes, a);
-  i = self->attributes->len - 1;
-  pa = &g_array_index(self->attributes, Attribute, i);
-  g_hash_table_insert(self->names, GUINT_TO_POINTER(name), 
-      GUINT_TO_POINTER(i + 1));
-  return address_of_value(t, &(pa->value));
-}
-
-
-/* Remove an attribute */
-
-void 
-lttv_attribute_remove(LttvAttribute *self, unsigned i)
-{
-  Attribute *a;
-
-  a = &g_array_index(self->attributes, Attribute, i);
-
-  /* Remove the array element and its entry in the name index */
-
-  g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
-  g_array_remove_index_fast(self->attributes, i);
-
-  /* The element used to replace the removed element has its index entry
-     all wrong now. Reinsert it with its new position. */
-
-  if(self->attributes->len != i){
-    g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name));
-    g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1));
-  }
-}
-
-void 
-lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name)
-{
-  unsigned i;
-
-  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i == 0) g_error("remove by name non existent attribute");
-
-  lttv_attribute_remove(self, i - 1);
-}
-
-/* Create an empty iattribute object and add it as an attribute under the
-   specified name, or return an existing iattribute attribute. If an
-   attribute of that name already exists but is not a GObject supporting the
-   iattribute interface, return NULL. */
-
-/*CHECK*/LttvAttribute* 
-lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name)
-{
-  unsigned i;
-
-  Attribute a;
-
-  LttvAttribute *new;
-
-  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i != 0) {
-    a = g_array_index(self->attributes, Attribute, i - 1);
-    if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) {
-      return LTTV_ATTRIBUTE(a.value.dv_gobject);
-    }
-    else return NULL;    
-  }
-  new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-  *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new);
-  return (LttvAttribute *)new;
-}
-
-gboolean 
-lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, 
-    LttvAttributeType t, LttvAttributeValue *v)
-{
-  unsigned i;
-
-  Attribute *a;
-
-  i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name));
-  if(i != 0) {
-    a = &g_array_index(self->attributes, Attribute, i - 1);
-    if(a->type != t) return FALSE;
-    *v = address_of_value(t, &(a->value));
-    return TRUE;
-  }
-
-  *v = lttv_attribute_add(self, name, t);
-  return TRUE;
-}
-
-
-void lttv_attribute_recursive_free(LttvAttribute *self)
-{
-  int i, nb;
-
-  Attribute *a;
-
-  nb = self->attributes->len;
-
-  for(i = 0 ; i < nb ; i++) {
-    a = &g_array_index(self->attributes, Attribute, i);
-    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
-      lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject));
-    }
-  }
-  g_object_unref(self);
-}
-
-
-void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src)
-{
-  int i, nb;
-
-  Attribute *a;
-
-  LttvAttributeValue value;
-
-  nb = src->attributes->len;
-
-  for(i = 0 ; i < nb ; i++) {
-    a = &g_array_index(src->attributes, Attribute, i);
-    if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) {
-      lttv_attribute_recursive_add(
-      /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name),
-          (LttvAttribute *)(a->value.dv_gobject));
-    }
-    else {
-      g_assert(lttv_attribute_find(dest, a->name, a->type, &value));
-      switch(a->type) {
-       case LTTV_INT:
-          *value.v_int += a->value.dv_int;
-          break;
-        case LTTV_UINT:
-          *value.v_uint += a->value.dv_uint;
-          break;
-        case LTTV_LONG:
-          *value.v_long += a->value.dv_long;
-          break;
-        case LTTV_ULONG:
-          *value.v_ulong += a->value.dv_ulong;
-          break;
-        case LTTV_FLOAT:
-          *value.v_float += a->value.dv_float;
-          break;
-        case LTTV_DOUBLE:
-          *value.v_double += a->value.dv_double;
-          break;
-        case LTTV_TIME:
-          *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time);
-          break;
-        case LTTV_POINTER:
-          break;
-        case LTTV_STRING:
-          break;
-        case LTTV_GOBJECT:
-          break;
-        case LTTV_NONE:
-          break;
-      }    
-    }
-  }
-}
-
-
-static void
-attribute_interface_init (gpointer g_iface, gpointer iface_data)
-{
-  LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface;
-
-  klass->get_number = (unsigned int (*) (LttvIAttribute *self)) 
-      lttv_attribute_get_number;
-
-  klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous))
-      lttv_attribute_named;
-
-  klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, 
-      LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get;
-
-  klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self,
-      LttvAttributeName name, LttvAttributeValue *v)) 
-      lttv_attribute_get_by_name;
-
-  klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, 
-      LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add;
-
-  klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) 
-      lttv_attribute_remove;
-
-  klass->remove_by_name = (void (*) (LttvIAttribute *self,
-      LttvAttributeName name)) lttv_attribute_remove_by_name;
-
-  klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, 
-      LttvAttributeName name)) lttv_attribute_find_subdir;
-}
-
-
-static void
-attribute_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-  LttvAttribute *self = (LttvAttribute *)instance;
-  self->names = g_hash_table_new(g_direct_hash, g_direct_equal);
-  self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute));
-}
-
-
-static void
-attribute_finalize (LttvAttribute *self)
-{
-  g_hash_table_destroy(self->names);
-  g_critical("attribute_finalize()");
-  g_array_free(self->attributes, TRUE);
-  G_OBJECT_CLASS(g_type_class_peek_parent(
-      g_type_class_peek(LTTV_ATTRIBUTE_TYPE)))->finalize(G_OBJECT(self));
-}
-
-
-static void
-attribute_class_init (LttvAttributeClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self))attribute_finalize;
-}
-
-GType 
-lttv_attribute_get_type (void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvAttributeClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) attribute_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvAttribute),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) attribute_instance_init    /* instance_init */
-    };
-
-    static const GInterfaceInfo iattribute_info = {
-      (GInterfaceInitFunc) attribute_interface_init,    /* interface_init */
-      NULL,                                       /* interface_finalize */
-      NULL                                        /* interface_data */
-    };
-
-    type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info, 
-        0);
-    g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info);
-  }
-  return type;
-}
-
-
diff --git a/ltt/branches/poly/lttv/mainLib/filter.c b/ltt/branches/poly/lttv/mainLib/filter.c
deleted file mode 100644 (file)
index c63940b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-
-   consist in AND, OR and NOT nested expressions, forming a tree with 
-   simple relations as leaves. The simple relations test is a field
-   in an event is equal, not equal, smaller, smaller or equal, larger, or
-   larger or equal to a specified value. */
-
-typedef enum _lttv_expression_op
-{ LTTV_FIELD_EQ,
-  LTTV_FIELD_NE,
-  LTTV_FIELD_LT,
-  LTTV_FIELD_LE,
-  LTTV_FIELD_GT,
-  LTTV_FIELD_GE
-} lttv_expression_op;
-
-typedef _lttv_simple_expression
-{ lttv_expression_op op;
-  char *field_name;
-  char *value;
-} lttv_simple_expression;
-
-typedef _lttv_expression_type
-{ LTTV_EXPRESSION,
-  LTTV_SIMPLE_EXPRESSION
-
-}
-typedef struct _lttv_expression 
-{ bool or;
-  bool not;
-  bool simple_expression;
-  union 
-  { lttv_expression *e;
-    lttv_field_relation *se;
-  } e;
-} lttv_expression;
-
-read_token
-
-read_expression
-  ( read expr )
-  simple expr [ op expr ]
-
-read_simple_expression
-  read_field_path [ rel value ]
-
-read_field_path
-  read_field_component [. field path]
-
-read_field_component
-  name [ \[ value \] ]
-
-data struct:
-and/or(left/right)
-not(child)
-op(left/right)
-path(component...) -> field
-
-
diff --git a/ltt/branches/poly/lttv/mainLib/hook.c b/ltt/branches/poly/lttv/mainLib/hook.c
deleted file mode 100644 (file)
index 8edbb2a..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-
-#include <lttv/hook.h>
-
-
-typedef struct _LttvHookClosure {
-  LttvHook hook;
-  void *hook_data;
-} LttvHookClosure;
-
-
-LttvHooks *lttv_hooks_new() 
-{
-  return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure));
-}
-
-
-void lttv_hooks_destroy(LttvHooks *h) 
-{
-  g_critical("lttv_hooks_destroy()");
-  g_array_free(h, TRUE);
-}
-
-
-void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) 
-{
-  LttvHookClosure c;
-
-  if(h == NULL)g_error("Null hook added");
-
-  c.hook = f;
-  c.hook_data = hook_data;
-  g_array_append_val(h,c);
-}
-
-
-void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) 
-{
-  guint i;
-
-  if(list == NULL) return;
-  for(i = 0 ; i < list->len; i++) {
-    g_array_append_val(h,g_array_index(list, LttvHookClosure, i));
-  }
-}
-
-
-void *lttv_hooks_remove(LttvHooks *h, LttvHook f)
-{
-  unsigned i;
-
-  void *hook_data;
-
-  LttvHookClosure *c;
-
-  for(i = 0 ; i < h->len ; i++) {
-    c = &g_array_index(h, LttvHookClosure, i);
-    if(c->hook == f) {
-      hook_data = c->hook_data;
-      lttv_hooks_remove_by_position(h, i);
-      return hook_data;
-    }
-  }
-  return NULL;
-}
-
-
-void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data)
-{
-  unsigned i;
-
-  LttvHookClosure *c;
-
-  for(i = 0 ; i < h->len ; i++) {
-    c = &g_array_index(h, LttvHookClosure, i);
-    if(c->hook == f && c->hook_data == hook_data) {
-      lttv_hooks_remove_by_position(h, i);
-      return;
-    }
-  }
-}
-
-
-void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list)
-{
-  guint i, j;
-
-  LttvHookClosure *c, *c_list;
-
-  if(list == NULL) return;
-  for(i = 0, j = 0 ; i < h->len && j < list->len ;) {
-    c = &g_array_index(h, LttvHookClosure, i);
-    c_list = &g_array_index(list, LttvHookClosure, j);
-    if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) {
-      lttv_hooks_remove_by_position(h, i);
-      j++;
-    }
-    else i++;
-  }
-
-  /* Normally the hooks in h are ordered as in list. If this is not the case,
-     try harder here. */
-
-  if(j < list->len) {
-    for(; j < list->len ; j++) {
-      c_list = &g_array_index(list, LttvHookClosure, j);
-      lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data);
-    }
-  }
-}
-
-
-unsigned lttv_hooks_number(LttvHooks *h)
-{
-  return h->len;
-}
-
-
-void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data)
-{
-  LttvHookClosure *c;
-
-  c = &g_array_index(h, LttvHookClosure, i);
-  *f = c->hook;
-  *hook_data = c->hook_data;
-}
-
-
-void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i)
-{
-  g_array_remove_index(h, i);
-}
-
-
-gboolean lttv_hooks_call(LttvHooks *h, void *call_data)
-{
-  gboolean ret, sum_ret = FALSE;
-
-  LttvHookClosure *c;
-
-  guint i;
-
-  if(h != NULL) {
-    for(i = 0 ; i < h->len ; i++) {
-      c = &g_array_index(h, LttvHookClosure, i);
-      ret = c->hook(c->hook_data,call_data);
-      sum_ret = sum_ret || ret;
-    }
-  }
-  return sum_ret;
-}
-
-
-gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data)
-{
-  LttvHookClosure *c;
-
-  guint i;
-
-  for(i = 0 ; i < h->len ; i++) {
-    c = &g_array_index(h, LttvHookClosure, i);
-    if(c->hook(c->hook_data,call_data)) return TRUE;
-  }
-  return FALSE;
-}
-
-
-LttvHooksById *lttv_hooks_by_id_new() 
-{
-  return g_ptr_array_new();
-}
-
-
-void lttv_hooks_by_id_destroy(LttvHooksById *h) 
-{
-  guint i;
-
-  for(i = 0 ; i < h->len ; i++) {
-    if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i]));
-  }
-  g_ptr_array_free(h, TRUE);
-}
-
-
-LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id)
-{
-  if(h->len <= id) g_ptr_array_set_size(h, id + 1);
-  if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new();
-  return h->pdata[id];
-}
-
-
-unsigned lttv_hooks_by_id_max_id(LttvHooksById *h)
-{
-  return h->len;
-}
-
-
-LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id)
-{
-  if(id < h->len) return h->pdata[id];
-  return NULL;
-}
-
-
-void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id)
-{
-  if(id < h->len && h->pdata[id] != NULL) {
-    lttv_hooks_destroy((LttvHooks *)h->pdata[id]);
-    h->pdata[id] = NULL;
-  }
-}
-
diff --git a/ltt/branches/poly/lttv/mainLib/iattribute.c b/ltt/branches/poly/lttv/mainLib/iattribute.c
deleted file mode 100644 (file)
index e39d7e0..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-
-#include <lttv/iattribute.h>
-
-static void
-lttv_iattribute_base_init (gpointer klass)
-{
-  static gboolean initialized = FALSE;
-
-  if (!initialized) {
-    initialized = TRUE;
-  }
-}
-
-
-GType
-lttv_iattribute_get_type (void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvIAttributeClass),
-      lttv_iattribute_base_init,   /* base_init */
-      NULL,   /* base_finalize */
-      NULL,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      0,
-      0,      /* n_preallocs */
-      NULL    /* instance_init */
-    };
-    type = g_type_register_static (G_TYPE_INTERFACE, "LttvIAttribute", 
-        &info, 0);
-  }
-  return type;
-}
-
-
-unsigned int lttv_iattribute_get_number(LttvIAttribute *self)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->get_number (self);
-}
-
-
-gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->named (self, homogeneous);
-}
-
-
-LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, 
-    LttvAttributeName *name, LttvAttributeValue *v)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->get (self, i, name, v);
-}
-
-LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self,
-    LttvAttributeName name, LttvAttributeValue *v)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->get_by_name (self, name, v);
-}
-
-
-LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, 
-    LttvAttributeName name, LttvAttributeType t)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->add (self, name, t);
-}
-
-
-void lttv_iattribute_remove(LttvIAttribute *self, unsigned i)
-{
-        return LTTV_IATTRIBUTE_GET_CLASS (self)->remove (self, i);
-}
-
-
-void lttv_iattribute_remove_by_name(LttvIAttribute *self,
-    LttvAttributeName name)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->remove_by_name (self, name);
-}
-
-LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, 
-      LttvAttributeName name)
-{
-  return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir (self, name);
-}
-
-
-/* Find the named attribute in the table, which must be of the specified type.
-   If it does not exist, it is created with a default value of 0 (NULL for
-   pointer types). Since the address of the value is obtained, it may be
-   changed easily afterwards. The function returns false when the attribute
-   exists but is of incorrect type. */
-
-gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, 
-    LttvAttributeType t, LttvAttributeValue *v)
-{
-  LttvAttributeType found_type;
-
-  found_type = lttv_iattribute_get_by_name(self, name, v);
-  if(found_type == t) return TRUE;
-
-  if(found_type == LTTV_NONE) {
-    *v = lttv_iattribute_add(self, name, t);
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-
-/* Trees of attribute tables may be accessed using a hierarchical path with
-   components separated by /, like in filesystems */
-
-gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, 
-    LttvAttributeType t, LttvAttributeValue *v)
-{
-  LttvIAttribute *node = self;
-
-  LttvAttributeType found_type;
-
-  LttvAttributeName name;
-
-  gchar **components, **cursor;
-
-  components = g_strsplit(path, "\"", G_MAXINT);
-
-  if(components == NULL || *components == NULL) {
-    g_strfreev(components);
-    return FALSE; 
-  }
-
-  for(cursor = components;;) {
-    name = g_quark_from_string(*cursor);
-    cursor++;
-
-    if(*cursor == NULL) {
-      g_strfreev(components);
-      return lttv_iattribute_find(node, name, t, v);
-    }
-    else {
-      found_type = lttv_iattribute_get_by_name(node, name, v);
-      if(found_type == LTTV_NONE) {
-        node = lttv_iattribute_find_subdir(node, name);
-      }
-      else if(found_type == LTTV_GOBJECT && 
-             LTTV_IS_IATTRIBUTE(*(v->v_gobject))) {
-        node = LTTV_IATTRIBUTE(*(v->v_gobject));
-      }
-      else {
-        g_strfreev(components);
-        return FALSE;
-      }
-    }
-  }
-}
-
-/* Shallow and deep copies */
-
-LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self)
-{
-  LttvIAttribute *copy;
-
-  LttvAttributeType t;
-
-  LttvAttributeValue v, v_copy;
-
-  LttvAttributeName name;
-
-  int i;
-
-  int nb_attributes = lttv_iattribute_get_number(self);
-
-  copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self),NULL));
-
-  for(i = 0 ; i < nb_attributes ; i++) {
-    t = lttv_iattribute_get(self, i, &name, &v);
-    v_copy = lttv_iattribute_add(copy, name, t);
-    lttv_iattribute_copy_value(t, v_copy, v);
-  }
-}
-
-LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self)
-{
-  LttvIAttribute *copy, *child;
-
-  LttvAttributeType t;
-
-  LttvAttributeValue v, v_copy;
-
-  LttvAttributeName name;
-
-  int i;
-
-  int nb_attributes = lttv_iattribute_get_number(self);
-
-  copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self), NULL));
-
-  for(i = 0 ; i < nb_attributes ; i++) {
-    t = lttv_iattribute_get(self, i, &name, &v);
-    v_copy = lttv_iattribute_add(copy, name, t);
-    if(t == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(*(v.v_gobject))) {
-      child = LTTV_IATTRIBUTE(*(v.v_gobject));
-      *(v_copy.v_gobject) = G_OBJECT(lttv_iattribute_deep_copy(child));
-    }
-    else lttv_iattribute_copy_value(t, v_copy, v);
-  }
-}
-
-void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, 
-    LttvAttributeValue src) 
-{
-  switch(t) {
-    case LTTV_INT:
-      *(dest.v_int) = *(src.v_int); 
-      break;
-
-    case LTTV_UINT:
-      *(dest.v_uint) = *(src.v_uint); 
-      break;
-
-    case LTTV_LONG:
-      *(dest.v_long) = *(src.v_long); 
-      break;
-
-    case LTTV_ULONG:
-      *(dest.v_ulong) = *(src.v_ulong); 
-      break;
-
-    case LTTV_FLOAT:
-      *(dest.v_float) = *(src.v_float); 
-      break;
-
-    case LTTV_DOUBLE: 
-      *(dest.v_double) = *(src.v_double); 
-      break;
-
-    case LTTV_TIME: 
-      *(dest.v_time) = *(src.v_time); 
-      break;
-
-    case LTTV_POINTER:
-      *(dest.v_pointer) = *(src.v_pointer); 
-      break;
-
-    case LTTV_STRING:
-      *(dest.v_string) = *(src.v_string); 
-      break;
-
-    case LTTV_GOBJECT:
-      *(dest.v_gobject) = *(src.v_gobject); 
-      break;
-
-    case LTTV_NONE:
-      break;
-  }
-}
-
-
diff --git a/ltt/branches/poly/lttv/mainLib/module.c b/ltt/branches/poly/lttv/mainLib/module.c
deleted file mode 100644 (file)
index e225992..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-
-/* module.c : Implementation of the module loading/unloading mechanism.
- * 
- */
-
-#include <lttv/module.h>
-
-#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
-#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
-
-struct _LttvModule
-{
-  GModule *module;
-  guint ref_count;
-  guint load_count;
-  GPtrArray *dependents;
-};
-
-
-/* Table of loaded modules and paths where to search for modules */
-
-static GHashTable *modules = NULL;
-
-static GPtrArray *modulesPaths = NULL;
-
-static void lttv_module_unload_all();
-
-
-void lttv_module_init(int argc, char **argv) 
-{
-  g_info("Init module.c");
-  modules = g_hash_table_new(g_str_hash, g_str_equal);
-  modulesPaths = g_ptr_array_new();
-}
-
-
-void lttv_module_destroy() 
-{  
-  int i;
-
-  g_info("Destroy module.c");
-
-  /* Unload all modules */
-  lttv_module_unload_all();
-
-  /* Free the modules paths pointer array as well as the elements */
-  for(i = 0; i < modulesPaths->len ; i++) {
-    g_free(modulesPaths->pdata[i]);
-  }
-  g_ptr_array_free(modulesPaths,TRUE) ;
-  modulesPaths = NULL;
-  
-  /* destroy the hash table */
-  g_hash_table_destroy(modules) ;
-  modules = NULL;
-}
-
-
-/* Add a new pathname to the modules loading search path */
-
-void lttv_module_path_add(const char *name) 
-{
-  g_info("Add module path %s", name);
-  g_ptr_array_add(modulesPaths,(char*)g_strdup(name));
-}
-
-
-static LttvModule *
-module_load(const char *name, int argc, char **argv) 
-{
-  GModule *gm;
-
-  LttvModule *m;
-
-  int i;
-
-  char *pathname;
-
-  const char *module_name;
-  
-  LttvModuleInit init_function;
-
-  g_info("Load module %s", name);
-
-  /* Try to find the module along all the user specified paths */
-
-  for(i = 0 ; i < modulesPaths->len ; i++) {
-    pathname = g_module_build_path(modulesPaths->pdata[i],name);
-    g_info("Try path %s", pathname);
-    gm = g_module_open(pathname,0);
-    g_free(pathname);    
-    
-    if(gm != NULL) break;
-    g_info("Trial failed, %s", g_module_error());
-  }
-
-  /* Try the default system path */
-
-  if(gm == NULL) {
-    pathname = g_module_build_path(NULL,name);
-    g_info("Try default path");
-    gm = g_module_open(pathname,0);
-    g_free(pathname);
-  }
-
-  /* Module cannot be found */
-  if(gm == NULL) {
-    g_info("Trial failed, %s", g_module_error());
-    g_info("Failed to load %s", name); 
-    return NULL;
-  }
-
-  /* Check if the module was already opened using the hopefully canonical name
-     returned by g_module_name. */
-
-  module_name = g_module_name(gm);
-
-  m = g_hash_table_lookup(modules, module_name);
-
-  if(m == NULL) {
-    g_info("Module %s (%s) loaded, call its init function", name, module_name);
-
-    /* Module loaded for the first time. Insert it in the table and call the
-       init function if any. */
-
-    m = g_new(LttvModule, 1);
-    m->module = gm;
-    m->ref_count = 0;
-    m->load_count = 0;
-    m->dependents = g_ptr_array_new();
-    g_hash_table_insert(modules, (gpointer)module_name, m);
-
-    if(!g_module_symbol(gm, "init", (gpointer)&init_function)) {
-      g_warning("module %s (%s) has no init function", name, pathname);
-    }
-    else init_function(m, argc, argv);
-  }
-  else {
-
-    /* Module was already opened, check that it really is the same and
-       undo the extra g_module_open */
-
-    g_info("Module %s (%s) was already loaded, no need to call init function",
-          name, module_name);
-    if(m->module != gm) g_error("Two gmodules with the same pathname");
-    g_module_close(gm);
-  }
-  m->ref_count++;
-  return m;
-}
-
-
-LttvModule *
-lttv_module_load(const char *name, int argc, char **argv) 
-{
-  g_info("Load module %s explicitly", name);
-  LttvModule *m = module_load(name, argc, argv);
-  if(m != NULL) m->load_count++;
-  return m;
-}
-
-
-LttvModule *
-lttv_module_require(LttvModule *m, const char *name, int argc, char **argv)
-{
-  LttvModule *module;
-
-  g_info("Load module %s, as %s is a dependent requiring it", name, 
-      g_module_name(m->module));
-  module = module_load(name, argc, argv);
-  if(module != NULL) g_ptr_array_add(module->dependents, m);
-  return module;
-}
-
-
-static void module_unload(LttvModule *m) 
-{
-  LttvModuleDestroy destroy_function;
-
-  char *pathname;
-
-  guint i, len;
-
-  /* Decrement the reference count */
-
-  g_info("Unload module %s", g_module_name(m->module));
-  m->ref_count--;
-  if(m->ref_count > 0) {
-    g_info("Module usage count decremented to %d", m->ref_count);
-    return;
-  }
-  /* We really have to unload the module, first unload its dependents */
-
-  len = m->dependents->len;
-  g_info("Unload dependent modules");
-
-  for(i = 0 ; i < len ; i++) {
-    module_unload(m->dependents->pdata[i]);
-  }
-
-  if(len != m->dependents->len) g_error("dependents list modified");
-
-  /* Unload the module itself */
-
-  g_info("Call the destroy function and unload the module");
-  if(!g_module_symbol(m->module, "destroy", (gpointer)&destroy_function)) {
-    g_warning("module (%s) has no destroy function", pathname);
-  }
-  else destroy_function();
-
-  g_hash_table_remove(modules, g_module_name(m->module));
-  g_ptr_array_free(m->dependents, TRUE);
-  g_module_close(m->module);
-  g_free(m);
-}
-
-
-void lttv_module_unload(LttvModule *m) 
-{
-  g_info("Explicitly unload module %s", g_module_name(m->module));
-  if(m->load_count <= 0) { 
-    g_error("more unload than load (%s)", g_module_name(m->module));
-    return;
-  }
-  m->load_count--;
-  module_unload(m);
-}
-
-
-static void
-list_modules(gpointer key, gpointer value, gpointer user_data)
-{
-  g_ptr_array_add((GPtrArray *)user_data, value);
-}
-
-
-LttvModule **
-lttv_module_list(guint *nb)
-{
-  GPtrArray *list = g_ptr_array_new();
-
-  LttvModule **array;
-
-  g_hash_table_foreach(modules, list_modules, list);
-  *nb = list->len;
-  array = (LttvModule **)list->pdata;
-  g_ptr_array_free(list, FALSE);
-  return array;
-}
-
-
-LttvModule **
-lttv_module_info(LttvModule *m, const char **name, 
-    guint *ref_count, guint *load_count, guint *nb_dependents)
-{
-  guint i, len = m->dependents->len;
-
-  LttvModule **array = g_new(LttvModule *, len);
-
-  *name = g_module_name(m->module);
-  *ref_count = m->ref_count;
-  *load_count = m->load_count;
-  *nb_dependents = len;
-  for(i = 0 ; i < len ; i++) array[i] = m->dependents->pdata[i];
-  return array;
-}
-
-char * 
-lttv_module_name(LttvModule *m)
-{
-  return g_module_name(m->module);
-}
-
-static void
-list_independent(gpointer key, gpointer value, gpointer user_data)
-{
-  LttvModule *m = (LttvModule *)value;
-
-  if(m->load_count > 0) g_ptr_array_add((GPtrArray *)user_data, m);
-}
-
-
-void
-lttv_module_unload_all()
-{
-  guint i;
-
-  LttvModule *m;
-
-  GPtrArray *independent_modules = g_ptr_array_new();
-
-  g_hash_table_foreach(modules, list_independent, independent_modules);
-
-  for(i = 0 ; i < independent_modules->len ; i++) {
-    m = (LttvModule *)independent_modules->pdata[i];
-    while(m->load_count > 0) lttv_module_unload(m);
-  }
-
-  g_ptr_array_free(independent_modules, TRUE);
-  if(g_hash_table_size(modules) != 0) g_warning("cannot unload all modules"); 
-}
diff --git a/ltt/branches/poly/lttv/mainLib/processTrace.c b/ltt/branches/poly/lttv/mainLib/processTrace.c
deleted file mode 100644 (file)
index 4a290dd..0000000
+++ /dev/null
@@ -1,812 +0,0 @@
-
-#include <lttv/processTrace.h>
-#include <ltt/event.h>
-#include <ltt/facility.h>
-#include <ltt/trace.h>
-#include <ltt/type.h>
-
-void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
-{
-  LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
-}
-
-
-void lttv_context_fini(LttvTracesetContext *self)
-{
-  LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
-}
-
-
-LttvTracesetContext *
-lttv_context_new_traceset_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
-}
-
-
-
-
-LttvTraceContext * 
-lttv_context_new_trace_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
-}
-
-
-LttvTracefileContext *
-lttv_context_new_tracefile_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
-}
-
-/****************************************************************************
- * lttv_traceset_context_compute_time_span
- *
- * Keep the Time_Span is sync with on the fly addition and removal of traces
- * in a trace set. It must be called each time a trace is added/removed from
- * the traceset. It could be more efficient to call it only once a bunch
- * of traces are loaded, but the calculation is not long, so it's not
- * critical.
- *
- * Author : Xang Xiu Yang
- * Imported from gtkTraceSet.c by Mathieu Desnoyers
- ***************************************************************************/
-static void lttv_traceset_context_compute_time_span(
-                                          LttvTracesetContext *self,
-                                         TimeInterval *Time_Span)
-{
-  LttvTraceset * traceset = self->ts;
-  int numTraces = lttv_traceset_number(traceset);
-  int i;
-  LttTime s, e;
-  LttvTraceContext *tc;
-  LttTrace * trace;
-
-  for(i=0; i<numTraces;i++){
-    tc = self->traces[i];
-    trace = tc->t;
-
-    ltt_trace_time_span_get(trace, &s, &e);
-
-    if(i==0){
-      Time_Span->startTime = s;
-      Time_Span->endTime   = e;
-    }else{
-      if(s.tv_sec < Time_Span->startTime.tv_sec ||
-        (s.tv_sec == Time_Span->startTime.tv_sec 
-          && s.tv_nsec < Time_Span->startTime.tv_nsec))
-       Time_Span->startTime = s;
-      if(e.tv_sec > Time_Span->endTime.tv_sec ||
-        (e.tv_sec == Time_Span->endTime.tv_sec &&
-          e.tv_nsec > Time_Span->endTime.tv_nsec))
-       Time_Span->endTime = e;      
-    }
-  }
-}
-
-
-static void
-init(LttvTracesetContext *self, LttvTraceset *ts)
-{
-  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceContext *tc;
-
-  LttvTracefileContext *tfc;
-
-  LttTime null_time = {0, 0};
-
-  nb_trace = lttv_traceset_number(ts);
-  self->ts = ts;
-  self->traces = g_new(LttvTraceContext *, nb_trace);
-  self->before = lttv_hooks_new();
-  self->after = lttv_hooks_new();
-  self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-  self->ts_a = lttv_traceset_attribute(ts);
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
-    self->traces[i] = tc;
-
-    tc->ts_context = self;
-    tc->index = i;
-    tc->vt = lttv_traceset_get(ts, i);
-    tc->t = lttv_trace(tc->vt);
-    tc->check = lttv_hooks_new();
-    tc->before = lttv_hooks_new();
-    tc->after = lttv_hooks_new();
-    tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-    tc->t_a = lttv_trace_attribute(tc->vt);
-    nb_control = ltt_trace_control_tracefile_number(tc->t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    tc->control_tracefiles = g_new(LttvTracefileContext *, nb_control);
-    tc->per_cpu_tracefiles = g_new(LttvTracefileContext *, nb_per_cpu);
-
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
-      if(j < nb_control) {
-        tc->control_tracefiles[j] = tfc;
-        tfc->control = TRUE;
-        tfc->index = j;
-        tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
-      }
-      else {
-        tc->per_cpu_tracefiles[j - nb_control] = tfc;
-        tfc->control = FALSE;
-        tfc->index = j - nb_control;
-        tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
-      }
-      tfc->t_context = tc;
-      tfc->check = lttv_hooks_new();
-      tfc->before = lttv_hooks_new();
-      tfc->after = lttv_hooks_new();
-      tfc->check_event = lttv_hooks_new();
-      tfc->before_event = lttv_hooks_new();
-      tfc->before_event_by_id = lttv_hooks_by_id_new();
-      tfc->after_event = lttv_hooks_new();
-      tfc->after_event_by_id = lttv_hooks_by_id_new();
-      tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-    }
-  }
-  lttv_process_traceset_seek_time(self, null_time);
-  /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
-  self->Time_Span = g_new(TimeInterval,1);
-  lttv_traceset_context_compute_time_span(self, self->Time_Span);
-}
-
-
-void fini(LttvTracesetContext *self)
-{
-  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceContext *tc;
-
-  LttvTracefileContext *tfc;
-
-  LttvTraceset *ts = self->ts;
-
-  g_free(self->Time_Span);
-
-  lttv_hooks_destroy(self->before);
-  lttv_hooks_destroy(self->after);
-  //FIXME : segfault
-  g_object_unref(self->a);
-
-  nb_trace = lttv_traceset_number(ts);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = self->traces[i];
-
-    lttv_hooks_destroy(tc->check);
-    lttv_hooks_destroy(tc->before);
-    lttv_hooks_destroy(tc->after);
-    g_object_unref(tc->a);
-
-    nb_control = ltt_trace_control_tracefile_number(tc->t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
-    nb_tracefile = nb_control + nb_per_cpu;
-
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) tfc = tc->control_tracefiles[j];
-      else tfc = tc->per_cpu_tracefiles[j - nb_control];
-
-      lttv_hooks_destroy(tfc->check);
-      lttv_hooks_destroy(tfc->before);
-      lttv_hooks_destroy(tfc->after);
-      lttv_hooks_destroy(tfc->check_event);
-      lttv_hooks_destroy(tfc->before_event);
-      lttv_hooks_by_id_destroy(tfc->before_event_by_id);
-      lttv_hooks_destroy(tfc->after_event);
-      lttv_hooks_by_id_destroy(tfc->after_event_by_id);
-      g_object_unref(tfc->a);
-      g_object_unref(tfc);
-    }
-    g_free(tc->control_tracefiles);
-    g_free(tc->per_cpu_tracefiles);
-    g_object_unref(tc);
-  }
-  g_free(self->traces);
-}
-
-
-void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
-    LttvHooks *before_traceset, 
-    LttvHooks *after_traceset,
-    LttvHooks *check_trace, 
-    LttvHooks *before_trace, 
-    LttvHooks *after_trace, 
-    LttvHooks *check_tracefile,
-    LttvHooks *before_tracefile,
-    LttvHooks *after_tracefile,
-    LttvHooks *check_event, 
-    LttvHooks *before_event, 
-    LttvHooks *after_event)
-{
-  LttvTraceset *ts = self->ts;
-
-  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceContext *tc;
-
-  LttvTracefileContext *tfc;
-
-  void *hook_data;
-
-  lttv_hooks_add_list(self->before, before_traceset);
-  lttv_hooks_add_list(self->after, after_traceset);
-  nb_trace = lttv_traceset_number(ts);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = self->traces[i];
-    lttv_hooks_add_list(tc->check, check_trace);
-    lttv_hooks_add_list(tc->before, before_trace);
-    lttv_hooks_add_list(tc->after, after_trace);
-    nb_control = ltt_trace_control_tracefile_number(tc->t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
-    nb_tracefile = nb_control + nb_per_cpu;
-
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfc = tc->control_tracefiles[j];
-      }
-      else {
-        tfc = tc->per_cpu_tracefiles[j-nb_control];
-      }
-      lttv_hooks_add_list(tfc->check, check_tracefile);
-      lttv_hooks_add_list(tfc->before, before_tracefile);
-      lttv_hooks_add_list(tfc->after, after_tracefile);
-      lttv_hooks_add_list(tfc->check_event, check_event);
-      lttv_hooks_add_list(tfc->before_event, before_event);
-      lttv_hooks_add_list(tfc->after_event, after_event);
-    }
-  }
-}
-
-
-void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
-    LttvHooks *before_traceset, 
-    LttvHooks *after_traceset,
-    LttvHooks *check_trace, 
-    LttvHooks *before_trace, 
-    LttvHooks *after_trace, 
-    LttvHooks *check_tracefile,
-    LttvHooks *before_tracefile,
-    LttvHooks *after_tracefile,
-    LttvHooks *check_event, 
-    LttvHooks *before_event, 
-    LttvHooks *after_event)
-{
-  LttvTraceset *ts = self->ts;
-
-  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceContext *tc;
-
-  LttvTracefileContext *tfc;
-
-  void *hook_data;
-
-  lttv_hooks_remove_list(self->before, before_traceset);
-  lttv_hooks_remove_list(self->after, after_traceset);
-  nb_trace = lttv_traceset_number(ts);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = self->traces[i];
-    lttv_hooks_remove_list(tc->check, check_trace);
-    lttv_hooks_remove_list(tc->before, before_trace);
-    lttv_hooks_remove_list(tc->after, after_trace);
-    nb_control = ltt_trace_control_tracefile_number(tc->t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
-    nb_tracefile = nb_control + nb_per_cpu;
-
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfc = tc->control_tracefiles[j];
-      }
-      else {
-        tfc = tc->per_cpu_tracefiles[j-nb_control];
-      }
-      lttv_hooks_remove_list(tfc->check, check_tracefile);
-      lttv_hooks_remove_list(tfc->before, before_tracefile);
-      lttv_hooks_remove_list(tfc->after, after_tracefile);
-      lttv_hooks_remove_list(tfc->check_event, check_event);
-      lttv_hooks_remove_list(tfc->before_event, before_event);
-      lttv_hooks_remove_list(tfc->after_event, after_event);
-    }
-  }
-}
-
-void lttv_trace_context_add_hooks(LttvTraceContext *tc,
-                                 LttvHooks *check_trace, 
-                                 LttvHooks *before_trace, 
-                                 LttvHooks *after_trace)
-{
-  lttv_hooks_add_list(tc->check, check_trace);
-  lttv_hooks_add_list(tc->before, before_trace);
-  lttv_hooks_add_list(tc->after, after_trace);
-}
-
-void lttv_trace_context_remove_hooks(LttvTraceContext *tc,
-                                    LttvHooks *check_trace, 
-                                    LttvHooks *before_trace, 
-                                    LttvHooks *after_trace)
-{
-  lttv_hooks_remove_list(tc->check, check_trace);
-  lttv_hooks_remove_list(tc->before, before_trace);
-  lttv_hooks_remove_list(tc->after, after_trace);
-}
-
-void lttv_tracefile_context_add_hooks(LttvTracefileContext *tfc,
-                                     LttvHooks *check_tracefile,
-                                     LttvHooks *before_tracefile,
-                                     LttvHooks *after_tracefile,
-                                     LttvHooks *check_event, 
-                                     LttvHooks *before_event, 
-                                     LttvHooks *after_event)
-{
-  lttv_hooks_add_list(tfc->check, check_tracefile);
-  lttv_hooks_add_list(tfc->before, before_tracefile);
-  lttv_hooks_add_list(tfc->after, after_tracefile);
-  lttv_hooks_add_list(tfc->check_event, check_event);
-  lttv_hooks_add_list(tfc->before_event, before_event);
-  lttv_hooks_add_list(tfc->after_event, after_event);
-}
-
-void lttv_tracefile_context_remove_hooks(LttvTracefileContext *tfc,
-                                        LttvHooks *check_tracefile,
-                                        LttvHooks *before_tracefile,
-                                        LttvHooks *after_tracefile,
-                                        LttvHooks *check_event, 
-                                        LttvHooks *before_event, 
-                                        LttvHooks *after_event)
-{
-  lttv_hooks_remove_list(tfc->check, check_tracefile);
-  lttv_hooks_remove_list(tfc->before, before_tracefile);
-  lttv_hooks_remove_list(tfc->after, after_tracefile);
-  lttv_hooks_remove_list(tfc->check_event, check_event);
-  lttv_hooks_remove_list(tfc->before_event, before_event);
-  lttv_hooks_remove_list(tfc->after_event, after_event);
-}
-
-void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
-                                           unsigned i,
-                                           LttvHooks *before_event_by_id, 
-                                           LttvHooks *after_event_by_id)
-{
-  LttvHooks * h;
-  h = lttv_hooks_by_id_find(tfc->before_event_by_id, i);
-  lttv_hooks_add_list(h, before_event_by_id);
-  h = lttv_hooks_by_id_find(tfc->after_event_by_id, i);
-  lttv_hooks_add_list(h, after_event_by_id);
-}
-
-void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
-                                              unsigned i)
-{
-  lttv_hooks_by_id_remove(tfc->before_event_by_id, i);
-  lttv_hooks_by_id_remove(tfc->after_event_by_id, i);
-}
-
-static LttvTracesetContext *
-new_traceset_context(LttvTracesetContext *self)
-{
-  return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
-}
-
-
-static LttvTraceContext * 
-new_trace_context(LttvTracesetContext *self)
-{
-  return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
-}
-
-
-static LttvTracefileContext *
-new_tracefile_context(LttvTracesetContext *self)
-{
-  return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
-}
-
-
-static void
-traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-  /* Be careful of anything which would not work well with shallow copies */
-}
-
-
-static void
-traceset_context_finalize (LttvTracesetContext *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
-      ->finalize(G_OBJECT(self));
-}
-
-
-static void
-traceset_context_class_init (LttvTracesetContextClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
-  klass->init = init;
-  klass->fini = fini;
-  klass->new_traceset_context = new_traceset_context;
-  klass->new_trace_context = new_trace_context;
-  klass->new_tracefile_context = new_tracefile_context;
-}
-
-
-GType 
-lttv_traceset_context_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTracesetContextClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) traceset_context_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTracesetContext),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
-    };
-
-    type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType", 
-        &info, 0);
-  }
-  return type;
-}
-
-
-static void
-trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-  /* Be careful of anything which would not work well with shallow copies */
-}
-
-
-static void
-trace_context_finalize (LttvTraceContext *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-trace_context_class_init (LttvTraceContextClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
-}
-
-
-GType 
-lttv_trace_context_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTraceContextClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) trace_context_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTraceContext),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) trace_context_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType", 
-        &info, 0);
-  }
-  return type;
-}
-
-
-static void
-tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-  /* Be careful of anything which would not work well with shallow copies */
-}
-
-
-static void
-tracefile_context_finalize (LttvTracefileContext *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
-      ->finalize(G_OBJECT(self));
-}
-
-
-static void
-tracefile_context_class_init (LttvTracefileContextClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
-}
-
-
-GType 
-lttv_tracefile_context_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTracefileContextClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) tracefile_context_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTracefileContext),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) tracefile_context_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType", 
-        &info, 0);
-  }
-  return type;
-}
-
-
-gint compare_tracefile(gconstpointer a, gconstpointer b)
-{
-  return ltt_time_compare(*((LttTime *)a), *((LttTime *)b));
-}
-
-
-gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
-  *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
-  return TRUE;
-}
-
-
-void lttv_process_traceset(LttvTracesetContext *self, LttTime end, 
-    unsigned maxNumEvents)
-{
-  GPtrArray *traces = g_ptr_array_new();
-
-  GPtrArray *tracefiles = g_ptr_array_new();
-
-  GTree *pqueue = g_tree_new(compare_tracefile);
-
-  guint i, j, nbi, nbj, id, nb_control, nb_cpu;
-
-  LttTrace *trace;
-
-  LttvTraceContext *tc;
-
-  LttTracefile *tracefile;
-
-  LttvTracefileContext *tfc;
-
-  LttEvent *event;
-
-  unsigned count = 0;
-
-  LttTime previous_timestamp = {0, 0};
-
-  /* Call all before_traceset, before_trace, and before_tracefile hooks.
-     For all qualifying tracefiles, seek to the start time, create a context,
-     read one event and insert in the pqueue based on the event time. */
-
-  lttv_hooks_call(self->before, self);
-  nbi = lttv_traceset_number(self->ts);
-
-  for(i = 0 ; i < nbi ; i++) {
-    tc = self->traces[i];
-    trace = tc->t;
-
-    if(!lttv_hooks_call_check(tc->check, tc)) {
-      g_ptr_array_add(traces, tc);
-      lttv_hooks_call(tc->before, tc);
-      nb_control = ltt_trace_control_tracefile_number(trace);
-      nb_cpu = ltt_trace_per_cpu_tracefile_number(trace);
-      nbj = nb_control + nb_cpu;
-
-      for(j = 0 ; j < nbj ; j++) {
-        if(j < nb_control) {
-          tfc = tc->control_tracefiles[j];
-        }
-        else {
-          tfc = tc->per_cpu_tracefiles[j - nb_control];
-        }
-
-        tracefile = tfc->tf;
-
-        if(!lttv_hooks_call_check(tfc->check, tfc)) {
-          g_ptr_array_add(tracefiles, tfc);
-          lttv_hooks_call(tfc->before, tfc);
-
-          if(tfc->e != NULL) {
-           if(tfc->timestamp.tv_sec < end.tv_sec ||
-              (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec)){
-             g_tree_insert(pqueue, &(tfc->timestamp), tfc);
-           }
-          }
-        }
-      }
-    }
-  }
-
-  /* Get the next event from the pqueue, call its hooks, 
-     reinsert in the pqueue the following event from the same tracefile 
-     unless the tracefile is finished or the event is later than the 
-     start time. */
-
-  while(TRUE) {
-    tfc = NULL;
-    g_tree_foreach(pqueue, get_first, &tfc);
-    if(tfc == NULL) break;
-
-    /* Have we reached the maximum number of events specified? However,
-       continue for all the events with the same time stamp (CHECK?). Then,
-       empty the queue and break from the loop. */
-
-    count++;
-    if(count > maxNumEvents){
-      if(tfc->timestamp.tv_sec == previous_timestamp.tv_sec &&
-        tfc->timestamp.tv_nsec == previous_timestamp.tv_nsec) {
-       count--;
-      }else{   
-       while(TRUE){
-         tfc = NULL;
-         g_tree_foreach(pqueue, get_first, &tfc);
-         if(tfc == NULL) break;
-         g_tree_remove(pqueue, &(tfc->timestamp));
-       }
-       break;
-      }
-    }
-    previous_timestamp = tfc->timestamp;
-
-
-    /* Get the tracefile with an event for the smallest time found. If two
-       or more tracefiles have events for the same time, hope that lookup
-       and remove are consistent. */
-
-    tfc = g_tree_lookup(pqueue, &(tfc->timestamp));
-    g_tree_remove(pqueue, &(tfc->timestamp));
-
-    if(!lttv_hooks_call(tfc->check_event, tfc)) {
-      id = ltt_event_eventtype_id(tfc->e);
-      lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
-      lttv_hooks_call(tfc->before_event, tfc);
-      lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
-      lttv_hooks_call(tfc->after_event, tfc);
-    }
-
-    event = ltt_tracefile_read(tfc->tf);
-    if(event != NULL) {
-      tfc->e = event;
-      tfc->timestamp = ltt_event_time(event);
-      if(tfc->timestamp.tv_sec < end.tv_sec ||
-        (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec))
-       g_tree_insert(pqueue, &(tfc->timestamp), tfc);
-    }
-  }
-
-  /* Call all the after_tracefile, after_trace and after_traceset hooks. */
-
-  for(i = 0, j = 0 ; i < traces->len ; i++) {
-    tc = traces->pdata[i];
-    while(j < tracefiles->len) {
-      tfc = tracefiles->pdata[j];
-
-      if(tfc->t_context == tc) {
-        lttv_hooks_call(tfc->after, tfc);
-        j++;
-      }
-      else break;
-    }
-    lttv_hooks_call(tc->after, tc);
-  }
-
-  g_assert(j == tracefiles->len);
-  lttv_hooks_call(self->after, self);
-
-  /* Free the traces, tracefiles and pqueue */
-
-  g_ptr_array_free(tracefiles, TRUE);
-  g_ptr_array_free(traces, TRUE);
-  g_tree_destroy(pqueue);
-}
-
-
-void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
-{
-  guint i, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTracefileContext *tfc;
-
-  LttEvent *event;
-
-  nb_control = ltt_trace_control_tracefile_number(self->t);
-  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->t);
-  nb_tracefile = nb_control + nb_per_cpu;
-  for(i = 0 ; i < nb_tracefile ; i++) {
-    if(i < nb_control) tfc = self->control_tracefiles[i];
-    else tfc = self->per_cpu_tracefiles[i - nb_control];
-
-    ltt_tracefile_seek_time(tfc->tf, start);
-    event = ltt_tracefile_read(tfc->tf);
-    tfc->e = event;
-    if(event != NULL) tfc->timestamp = ltt_event_time(event);
-  }
-}
-
-
-void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
-{
-  guint i, nb_trace;
-
-  LttvTraceContext *tc;
-
-  nb_trace = lttv_traceset_number(self->ts);
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = self->traces[i];
-    lttv_process_trace_seek_time(tc, start);
-  }
-}
-
-
-static LttField *
-find_field(LttEventType *et, const char *field)
-{
-  LttType *t;
-
-  LttField *f;
-
-  guint i, nb;
-
-  char *name;
-
-  if(field == NULL) return NULL;
-
-  f = ltt_eventtype_field(et);
-  t = ltt_eventtype_type(et);
-  g_assert(ltt_type_class(t) == LTT_STRUCT);
-  nb = ltt_type_member_number(t);
-  for(i = 0 ; i < nb ; i++) {
-    ltt_type_member_type(t, i, &name);
-    if(strcmp(name, field) == 0) break;
-  }
-  g_assert(i < nb);
-  return ltt_field_member(f, i);
-}
-
-
-void 
-lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, 
-    char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
-{
-  LttFacility *f;
-
-  LttEventType *et;
-
-  guint nb, pos, i;
-
-  char *name;
-
-  nb = ltt_trace_facility_find(t, facility, &pos);
-  if(nb < 1) g_error("No %s facility", facility);
-  f = ltt_trace_facility_get(t, pos);
-  et = ltt_facility_eventtype_get_by_name(f, event_type);
-  if(et == NULL) g_error("Event %s does not exist", event_type);
-
-  th->h = h;
-  th->id = ltt_eventtype_id(et);
-  th->f1 = find_field(et, field1);
-  th->f2 = find_field(et, field2);
-  th->f3 = find_field(et, field3);
-}
-
-
diff --git a/ltt/branches/poly/lttv/mainLib/state.c b/ltt/branches/poly/lttv/mainLib/state.c
deleted file mode 100644 (file)
index dbdb11c..0000000
+++ /dev/null
@@ -1,1198 +0,0 @@
-
-#include <lttv/state.h>
-#include <ltt/facility.h>
-#include <ltt/trace.h>
-#include <ltt/event.h>
-#include <ltt/type.h>
-
-LttvExecutionMode
-  LTTV_STATE_MODE_UNKNOWN,
-  LTTV_STATE_USER_MODE,
-  LTTV_STATE_SYSCALL,
-  LTTV_STATE_TRAP,
-  LTTV_STATE_IRQ;
-
-LttvExecutionSubmode
-  LTTV_STATE_SUBMODE_UNKNOWN,
-  LTTV_STATE_SUBMODE_NONE;
-
-LttvProcessStatus
-  LTTV_STATE_UNNAMED,
-  LTTV_STATE_WAIT_FORK,
-  LTTV_STATE_WAIT_CPU,
-  LTTV_STATE_EXIT,
-  LTTV_STATE_WAIT,
-  LTTV_STATE_RUN;
-
-static GQuark
-  LTTV_STATE_TRACEFILES,
-  LTTV_STATE_PROCESSES,
-  LTTV_STATE_PROCESS,
-  LTTV_STATE_EVENT,
-  LTTV_STATE_SAVED_STATES,
-  LTTV_STATE_TIME,
-  LTTV_STATE_HOOKS;
-
-
-static void fill_name_tables(LttvTraceState *tcs);
-
-static void free_name_tables(LttvTraceState *tcs);
-
-static void lttv_state_free_process_table(GHashTable *processes);
-
-static LttvProcessState *create_process(LttvTracefileState *tfs, 
-                                LttvProcessState *parent, guint pid);
-
-void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
-{
-  LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container);
-}
-
-
-void lttv_state_restore(LttvTraceState *self, LttvAttribute *container)
-{
-  LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
-}
-
-
-void lttv_state_saved_state_free(LttvTraceState *self, 
-    LttvAttribute *container)
-{
-  LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
-}
-
-
-static void
-restore_init_state(LttvTraceState *self)
-{
-  guint i, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTracefileState *tfcs;
-  
-  LttTime null_time = {0,0};
-
-  if(self->processes != NULL) lttv_state_free_process_table(self->processes);
-  self->processes = g_hash_table_new(g_direct_hash, g_direct_equal);
-  self->nb_event = 0;
-
-  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
-  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
-  nb_tracefile = nb_control + nb_per_cpu;
-  for(i = 0 ; i < nb_tracefile ; i++) {
-    if(i < nb_control) {
-      tfcs = LTTV_TRACEFILE_STATE(self->parent.control_tracefiles[i]);
-    }
-    else {
-      tfcs = LTTV_TRACEFILE_STATE(self->parent.per_cpu_tracefiles[i - nb_control]);
-    }
-
-    tfcs->parent.timestamp = null_time;
-    tfcs->saved_position = 0;
-    tfcs->process = create_process(tfcs, NULL,0);
-  }
-}
-
-
-static void
-init(LttvTracesetState *self, LttvTraceset *ts)
-{
-  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceContext *tc;
-
-  LttvTraceState *tcs;
-
-  LttvTracefileState *tfcs;
-  
-  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
-      init((LttvTracesetContext *)self, ts);
-
-  nb_trace = lttv_traceset_number(ts);
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = self->parent.traces[i];
-    tcs = (LttvTraceState *)tc;
-    tcs->save_interval = 100000;
-    fill_name_tables(tcs);
-
-    nb_control = ltt_trace_control_tracefile_number(tc->t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfcs = LTTV_TRACEFILE_STATE(tc->control_tracefiles[j]);
-      }
-      else {
-        tfcs = LTTV_TRACEFILE_STATE(tc->per_cpu_tracefiles[j - nb_control]);
-      }
-      tfcs->cpu_name= g_quark_from_string(ltt_tracefile_name(tfcs->parent.tf));
-    }
-    tcs->processes = NULL;
-    restore_init_state(tcs);
-  }
-}
-
-
-static void
-fini(LttvTracesetState *self)
-{
-  guint i, j, nb_trace, nb_tracefile;
-
-  LttvTraceState *tcs;
-
-  LttvTracefileState *tfcs;
-
-  nb_trace = lttv_traceset_number(LTTV_TRACESET_CONTEXT(self)->ts);
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]);
-    lttv_state_free_process_table(tcs->processes);
-    tcs->processes = NULL;
-    free_name_tables(tcs);
-  }
-  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
-      fini((LttvTracesetContext *)self);
-}
-
-
-static LttvTracesetContext *
-new_traceset_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATE_TYPE, NULL));
-}
-
-
-static LttvTraceContext * 
-new_trace_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATE_TYPE, NULL));
-}
-
-
-static LttvTracefileContext *
-new_tracefile_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATE_TYPE, NULL));
-}
-
-
-static void copy_process_state(gpointer key, gpointer value,gpointer user_data)
-{
-  LttvProcessState *process, *new_process;
-
-  GHashTable *new_processes = (GHashTable *)user_data;
-
-  guint i;
-
-  process = (LttvProcessState *)value;
-  new_process = g_new(LttvProcessState, 1);
-  *new_process = *process;
-  new_process->execution_stack = g_array_new(FALSE, FALSE, 
-      sizeof(LttvExecutionState));
-  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) =
-        g_array_index(process->execution_stack, LttvExecutionState, i);
-  }
-  new_process->state = &g_array_index(new_process->execution_stack, 
-      LttvExecutionState, new_process->execution_stack->len - 1);
-  g_hash_table_insert(new_processes, GUINT_TO_POINTER(new_process->pid), 
-      new_process);
-}
-
-
-static GHashTable *lttv_state_copy_process_table(GHashTable *processes)
-{
-  GHashTable *new_processes = g_hash_table_new(g_direct_hash, g_direct_equal);
-
-  g_hash_table_foreach(processes, copy_process_state, new_processes);
-  return new_processes;
-}
-
-
-/* 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
-   to the current process and a "position" member storing the tracefile
-   position (needed to seek to the current "next" event. */
-
-static void state_save(LttvTraceState *self, LttvAttribute *container)
-{
-  guint i, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTracefileState *tfcs;
-
-  LttvAttribute *tracefiles_tree, *tracefile_tree;
-
-  LttvAttributeType type;
-
-  LttvAttributeValue value;
-
-  LttvAttributeName name;
-
-  LttEventPosition *ep;
-
-  tracefiles_tree = lttv_attribute_find_subdir(container, 
-      LTTV_STATE_TRACEFILES);
-
-  value = lttv_attribute_add(container, LTTV_STATE_PROCESSES,
-      LTTV_POINTER);
-  *(value.v_pointer) = lttv_state_copy_process_table(self->processes);
-
-  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
-  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
-  nb_tracefile = nb_control + nb_per_cpu;
-
-  for(i = 0 ; i < nb_tracefile ; i++) {
-    if(i < nb_control) 
-        tfcs = (LttvTracefileState *)self->parent.control_tracefiles[i];
-    else tfcs = (LttvTracefileState *)
-        self->parent.per_cpu_tracefiles[i - nb_control];
-
-    tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-    value = lttv_attribute_add(tracefiles_tree, i, 
-        LTTV_GOBJECT);
-    *(value.v_gobject) = (GObject *)tracefile_tree;
-    value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS, 
-        LTTV_UINT);
-    *(value.v_uint) = tfcs->process->pid;
-    value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT, 
-        LTTV_POINTER);
-    if(tfcs->parent.e == NULL) *(value.v_pointer) = NULL;
-    else {
-      ep = ltt_event_position_new();
-      ltt_event_position(tfcs->parent.e, ep);
-      *(value.v_pointer) = ep;
-    }
-  }
-}
-
-
-static void state_restore(LttvTraceState *self, LttvAttribute *container)
-{
-  guint i, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTracefileState *tfcs;
-
-  LttvAttribute *tracefiles_tree, *tracefile_tree;
-
-  LttvAttributeType type;
-
-  LttvAttributeValue value;
-
-  LttvAttributeName name;
-
-  LttEventPosition *ep;
-
-  tracefiles_tree = lttv_attribute_find_subdir(container, 
-      LTTV_STATE_TRACEFILES);
-
-  type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, 
-      &value);
-  g_assert(type == LTTV_POINTER);
-  lttv_state_free_process_table(self->processes);
-  self->processes = lttv_state_copy_process_table(*(value.v_pointer));
-
-  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
-  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
-  nb_tracefile = nb_control + nb_per_cpu;
-
-  for(i = 0 ; i < nb_tracefile ; i++) {
-    if(i < nb_control) tfcs = (LttvTracefileState *)
-        self->parent.control_tracefiles[i];
-    else tfcs = (LttvTracefileState *)
-        self->parent.per_cpu_tracefiles[i - nb_control];
-
-    type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
-    g_assert(type == LTTV_GOBJECT);
-    tracefile_tree = *((LttvAttribute **)(value.v_gobject));
-
-    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS, 
-        &value);
-    g_assert(type == LTTV_UINT);
-    tfcs->process = lttv_state_find_process(tfcs, *(value.v_uint));
-    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, 
-        &value);
-    g_assert(type == LTTV_POINTER);
-    if(*(value.v_pointer) == NULL) tfcs->parent.e = NULL;
-    else {
-      ep = *(value.v_pointer);
-      ltt_tracefile_seek_position(tfcs->parent.tf, ep);
-      tfcs->parent.e = ltt_tracefile_read(tfcs->parent.tf);
-      tfcs->parent.timestamp = ltt_event_time(tfcs->parent.e);
-    }
-  }
-}
-
-
-static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
-{
-  guint i, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTracefileState *tfcs;
-
-  LttvAttribute *tracefiles_tree, *tracefile_tree;
-
-  LttvAttributeType type;
-
-  LttvAttributeValue value;
-
-  LttvAttributeName name;
-
-  LttEventPosition *ep;
-
-  tracefiles_tree = lttv_attribute_find_subdir(container, 
-      LTTV_STATE_TRACEFILES);
-  lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES);
-
-  type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, 
-      &value);
-  g_assert(type == LTTV_POINTER);
-  lttv_state_free_process_table(*(value.v_pointer));
-  *(value.v_pointer) = NULL;
-  lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
-
-  nb_control = ltt_trace_control_tracefile_number(self->parent.t);
-  nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
-  nb_tracefile = nb_control + nb_per_cpu;
-
-  for(i = 0 ; i < nb_tracefile ; i++) {
-    if(i < nb_control) tfcs = (LttvTracefileState *)
-        self->parent.control_tracefiles[i];
-    else tfcs = (LttvTracefileState *)
-        self->parent.per_cpu_tracefiles[i - nb_control];
-
-    type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
-    g_assert(type == LTTV_GOBJECT);
-    tracefile_tree = *((LttvAttribute **)(value.v_gobject));
-
-    type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, 
-        &value);
-    g_assert(type == LTTV_POINTER);
-    if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer));
-  }
-  lttv_attribute_recursive_free(tracefiles_tree);
-}
-
-
-static void 
-fill_name_tables(LttvTraceState *tcs) 
-{
-  int i, nb;
-
-  char *f_name, *e_name;
-
-  LttvTraceHook h;
-
-  LttEventType *et;
-
-  LttType *t;
-
-  GString *fe_name = g_string_new("");
-
-  nb = ltt_trace_eventtype_number(tcs->parent.t);
-  tcs->eventtype_names = g_new(GQuark, nb);
-  for(i = 0 ; i < nb ; i++) {
-    et = ltt_trace_eventtype_get(tcs->parent.t, i);
-    e_name = ltt_eventtype_name(et);
-    f_name = ltt_facility_name(ltt_eventtype_facility(et));
-    g_string_printf(fe_name, "%s.%s", f_name, e_name);
-    tcs->eventtype_names[i] = g_quark_from_string(fe_name->str);    
-  }
-
-  lttv_trace_find_hook(tcs->parent.t, "core", "syscall_entry",
-      "syscall_id", NULL, NULL, NULL, &h);
-  t = ltt_field_type(h.f1);
-  nb = ltt_type_element_number(t);
-
-  /* CHECK syscalls should be an emun but currently are not!  
-  tcs->syscall_names = g_new(GQuark, nb);
-
-  for(i = 0 ; i < nb ; i++) {
-    tcs->syscall_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
-  }
-  */
-
-  tcs->syscall_names = g_new(GQuark, 256);
-  for(i = 0 ; i < 256 ; i++) {
-    g_string_printf(fe_name, "syscall %d", i);
-    tcs->syscall_names[i] = g_quark_from_string(fe_name->str);
-  }
-
-  lttv_trace_find_hook(tcs->parent.t, "core", "trap_entry",
-      "trap_id", NULL, NULL, NULL, &h);
-  t = ltt_field_type(h.f1);
-  nb = ltt_type_element_number(t);
-
-  /*
-  tcs->trap_names = g_new(GQuark, nb);
-  for(i = 0 ; i < nb ; i++) {
-    tcs->trap_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
-  }
-  */
-
-  tcs->trap_names = g_new(GQuark, 256);
-  for(i = 0 ; i < 256 ; i++) {
-    g_string_printf(fe_name, "trap %d", i);
-    tcs->trap_names[i] = g_quark_from_string(fe_name->str);
-  }
-
-  lttv_trace_find_hook(tcs->parent.t, "core", "irq_entry",
-      "irq_id", NULL, NULL, NULL, &h);
-  t = ltt_field_type(h.f1);
-  nb = ltt_type_element_number(t);
-
-  /*
-  tcs->irq_names = g_new(GQuark, nb);
-  for(i = 0 ; i < nb ; i++) {
-    tcs->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
-  }
-  */
-
-  tcs->irq_names = g_new(GQuark, 256);
-  for(i = 0 ; i < 256 ; i++) {
-    g_string_printf(fe_name, "irq %d", i);
-    tcs->irq_names[i] = g_quark_from_string(fe_name->str);
-  }
-
-  g_string_free(fe_name, TRUE);
-}
-
-
-static void 
-free_name_tables(LttvTraceState *tcs) 
-{
-  g_free(tcs->eventtype_names);
-  g_free(tcs->syscall_names);
-  g_free(tcs->trap_names);
-  g_free(tcs->irq_names);
-} 
-
-
-static void push_state(LttvTracefileState *tfs, LttvExecutionMode t, 
-    guint state_id)
-{
-  LttvExecutionState *es;
-
-  LttvProcessState *process = tfs->process;
-
-  guint depth = process->execution_stack->len;
-
-  g_array_set_size(process->execution_stack, depth + 1);
-  es = &g_array_index(process->execution_stack, LttvExecutionState, depth);
-  es->t = t;
-  es->n = state_id;
-  es->entry = es->change = tfs->parent.timestamp;
-  es->s = process->state->s;
-  process->state = es;
-}
-
-
-static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t)
-{
-  LttvProcessState *process = tfs->process;
-
-  guint depth = process->execution_stack->len - 1;
-
-  if(process->state->t != t){
-    g_warning("Different execution mode type (%d.%09d): ignore it\n",
-        tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
-    g_warning("process state has %s when pop_int is %s\n",
-                   g_quark_to_string(process->state->t),
-                   g_quark_to_string(t));
-    g_warning("{ %u, %u, %s, %s }\n",
-                   process->pid,
-                   process->ppid,
-                   g_quark_to_string(process->name),
-                   g_quark_to_string(process->state->s));
-    return;
-  }
-
-  if(depth == 0){
-    g_warning("Trying to pop last state on stack (%d.%09d): ignore it\n",
-        tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
-    return;
-  }
-
-  g_array_remove_index(process->execution_stack, depth);
-  depth--;
-  process->state = &g_array_index(process->execution_stack, LttvExecutionState,
-      depth);
-  process->state->change = tfs->parent.timestamp;
-}
-
-
-static LttvProcessState *create_process(LttvTracefileState *tfs, 
-    LttvProcessState *parent, guint pid)
-{
-  LttvProcessState *process = g_new(LttvProcessState, 1);
-
-  LttvExecutionState *es;
-
-  LttvTraceContext *tc;
-
-  LttvTraceState *tcs;
-
-  char buffer[128];
-
-  tcs = (LttvTraceState *)tc = tfs->parent.t_context;
-       
-  g_hash_table_insert(tcs->processes, GUINT_TO_POINTER(pid), process);
-  process->pid = pid;
-
-  if(parent) {
-    process->ppid = parent->pid;
-    process->name = parent->name;
-  }
-  else {
-    process->ppid = 0;
-    process->name = LTTV_STATE_UNNAMED;
-  }
-
-  process->creation_time = tfs->parent.timestamp;
-  sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec, 
-         process->creation_time.tv_nsec);
-  process->pid_time = g_quark_from_string(buffer);
-  process->execution_stack = g_array_new(FALSE, FALSE, 
-      sizeof(LttvExecutionState));
-  g_array_set_size(process->execution_stack, 1);
-  es = process->state = &g_array_index(process->execution_stack, 
-      LttvExecutionState, 0);
-  es->t = LTTV_STATE_USER_MODE;
-  es->n = LTTV_STATE_SUBMODE_NONE;
-  es->entry = tfs->parent.timestamp;
-  es->change = tfs->parent.timestamp;
-  es->s = LTTV_STATE_WAIT_FORK;
-
-  return process;
-}
-
-
-LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs, 
-    guint pid)
-{
-  LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
-  LttvProcessState *process = g_hash_table_lookup(ts->processes, 
-      GUINT_TO_POINTER(pid));
-  if(process == NULL) process = create_process(tfs, NULL, pid);
-  return process;
-}
-
-
-static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) 
-{
-  LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context);
-
-  g_hash_table_remove(ts->processes, GUINT_TO_POINTER(process->pid));
-  g_array_free(process->execution_stack, TRUE);
-  g_free(process);
-}
-
-
-static void free_process_state(gpointer key, gpointer value,gpointer user_data)
-{
-  g_array_free(((LttvProcessState *)value)->execution_stack, TRUE);
-  g_free(value);
-}
-
-
-static void lttv_state_free_process_table(GHashTable *processes)
-{
-  g_hash_table_foreach(processes, free_process_state, NULL);
-  g_hash_table_destroy(processes);
-}
-
-
-static gboolean syscall_entry(void *hook_data, void *call_data)
-{
-  LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  LttvExecutionSubmode submode;
-
-  submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[
-      ltt_event_get_unsigned(s->parent.e, f)];
-  push_state(s, LTTV_STATE_SYSCALL, submode);
-  return FALSE;
-}
-
-
-static gboolean syscall_exit(void *hook_data, void *call_data)
-{
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  pop_state(s, LTTV_STATE_SYSCALL);
-  return FALSE;
-}
-
-
-static gboolean trap_entry(void *hook_data, void *call_data)
-{
-  LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  LttvExecutionSubmode submode;
-
-  submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[
-      ltt_event_get_unsigned(s->parent.e, f)];
-  push_state(s, LTTV_STATE_TRAP, submode);
-  return FALSE;
-}
-
-
-static gboolean trap_exit(void *hook_data, void *call_data)
-{
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  pop_state(s, LTTV_STATE_TRAP);
-  return FALSE;
-}
-
-
-static gboolean irq_entry(void *hook_data, void *call_data)
-{
-  LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  LttvExecutionSubmode submode;
-
-  submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[
-      ltt_event_get_unsigned(s->parent.e, f)];
-
-  /* Do something with the info about being in user or system mode when int? */
-  push_state(s, LTTV_STATE_IRQ, submode);
-  return FALSE;
-}
-
-
-static gboolean irq_exit(void *hook_data, void *call_data)
-{
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  pop_state(s, LTTV_STATE_IRQ);
-  return FALSE;
-}
-
-
-static gboolean schedchange(void *hook_data, void *call_data)
-{
-  LttvTraceHook *h = (LttvTraceHook *)hook_data;
-
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  guint pid_in, pid_out, state_out;
-
-  pid_in = ltt_event_get_unsigned(s->parent.e, h->f1);
-  pid_out = ltt_event_get_unsigned(s->parent.e, h->f2);
-  state_out = ltt_event_get_unsigned(s->parent.e, h->f3);
-
-  if(s->process != NULL) {
-
-    if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
-    else if(s->process->state->s == LTTV_STATE_EXIT) 
-        exit_process(s, s->process);
-    else s->process->state->s = LTTV_STATE_WAIT;
-
-    if(s->process->pid == 0)
-      s->process->pid = pid_out;
-
-    s->process->state->change = s->parent.timestamp;
-  }
-  s->process = lttv_state_find_process(s, pid_in);
-  s->process->state->s = LTTV_STATE_RUN;
-  s->process->state->change = s->parent.timestamp;
-  return FALSE;
-}
-
-
-static gboolean process_fork(void *hook_data, void *call_data)
-{
-  LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  guint child_pid;
-
-  child_pid = ltt_event_get_unsigned(s->parent.e, f);
-  create_process(s, s->process, child_pid);
-  return FALSE;
-}
-
-
-static gboolean process_exit(void *hook_data, void *call_data)
-{
-  LttvTracefileState *s = (LttvTracefileState *)call_data;
-
-  if(s->process != NULL) {
-    s->process->state->s = LTTV_STATE_EXIT;
-  }
-  return FALSE;
-}
-
-
-void lttv_state_add_event_hooks(LttvTracesetState *self)
-{
-  LttvTraceset *traceset = self->parent.ts;
-
-  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceState *ts;
-
-  LttvTracefileState *tfs;
-
-  GArray *hooks;
-
-  LttvTraceHook hook;
-
-  LttvAttributeValue val;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    ts = (LttvTraceState *)self->parent.traces[i];
-
-    /* Find the eventtype id for the following events and register the
-       associated by id hooks. */
-
-    hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
-    g_array_set_size(hooks, 9);
-
-    lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id", 
-       NULL, NULL, syscall_entry, &g_array_index(hooks, LttvTraceHook, 0));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL, 
-        NULL, syscall_exit, &g_array_index(hooks, LttvTraceHook, 1));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
-       NULL, NULL, trap_entry, &g_array_index(hooks, LttvTraceHook, 2));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL, 
-        trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL, 
-        NULL, irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL, 
-        irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out", 
-        "out_state", schedchange, &g_array_index(hooks, LttvTraceHook, 6));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid", 
-        NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
-
-    lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL, 
-        NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
-
-    /* Add these hooks to each before_event_by_id hooks list */
-
-    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
-      }
-      else {
-        tfs = LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
-      }
-
-      for(k = 0 ; k < hooks->len ; k++) {
-        hook = g_array_index(hooks, LttvTraceHook, k);
-        lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, 
-         hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
-      }
-    }
-    lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
-    *(val.v_pointer) = hooks;
-  }
-}
-
-
-void lttv_state_remove_event_hooks(LttvTracesetState *self)
-{
-  LttvTraceset *traceset = self->parent.ts;
-
-  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceState *ts;
-
-  LttvTracefileState *tfs;
-
-  GArray *hooks;
-
-  LttvTraceHook hook;
-
-  LttvAttributeValue val;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    ts = LTTV_TRACE_STATE(self->parent.traces[i]);
-    lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
-    hooks = *(val.v_pointer);
-
-    /* Add these hooks to each before_event_by_id hooks list */
-
-    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
-      }
-      else {
-        tfs = LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
-      }
-
-      for(k = 0 ; k < hooks->len ; k++) {
-        hook = g_array_index(hooks, LttvTraceHook, k);
-        lttv_hooks_remove_data(
-            lttv_hooks_by_id_find(tfs->parent.after_event_by_id, 
-           hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
-      }
-    }
-    g_array_free(hooks, TRUE);
-  }
-}
-
-
-static gboolean block_end(void *hook_data, void *call_data)
-{
-  LttvTracefileState *tfcs = (LttvTracefileState *)call_data;
-
-  LttvTraceState *tcs = (LttvTraceState *)(tfcs->parent.t_context);
-
-  LttEventPosition *ep = ltt_event_position_new();
-
-  guint nb_block, nb_event;
-
-  LttTracefile *tf;
-
-  LttvAttribute *saved_states_tree, *saved_state_tree;
-
-  LttvAttributeValue value;
-
-  ltt_event_position(tfcs->parent.e, ep);
-
-  ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
-  tcs->nb_event += nb_event - tfcs->saved_position;
-  tfcs->saved_position = 0;
-  if(tcs->nb_event >= tcs->save_interval) {
-    saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, 
-        LTTV_STATE_SAVED_STATES);
-    saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-    value = lttv_attribute_add(saved_states_tree, 
-        lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT);
-    *(value.v_gobject) = (GObject *)saved_state_tree;
-    value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
-    *(value.v_time) = tfcs->parent.timestamp;
-    lttv_state_save(tcs, saved_state_tree);
-    tcs->nb_event = 0;
-  }
-  return FALSE;
-}
-
-
-void lttv_state_save_add_event_hooks(LttvTracesetState *self)
-{
-  LttvTraceset *traceset = self->parent.ts;
-
-  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceState *ts;
-
-  LttvTracefileState *tfs;
-
-  LttvTraceHook hook;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    ts = (LttvTraceState *)self->parent.traces[i];
-    lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, 
-       NULL, NULL, block_end, &hook);
-
-    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
-      }
-      else {
-        tfs =LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
-      }
-
-      lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, 
-         hook.id), hook.h, NULL);
-    }
-  }
-}
-
-
-void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
-{
-  LttvTraceset *traceset = self->parent.ts;
-
-  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceState *ts;
-
-  LttvTracefileState *tfs;
-
-  LttvTraceHook hook;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    ts = LTTV_TRACE_STATE(self->parent.traces[i]);
-    lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, 
-       NULL, NULL, block_end, &hook);
-
-    nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
-      }
-      else {
-        tfs =LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
-      }
-
-      lttv_hooks_remove_data(lttv_hooks_by_id_find(
-          tfs->parent.after_event_by_id, hook.id), hook.h, NULL);
-    }
-  }
-}
-
-
-void lttv_state_restore_closest_state(LttvTracesetState *self, LttTime t)
-{
-  LttvTraceset *traceset = self->parent.ts;
-
-  guint i, j, nb_trace, nb_saved_state;
-
-  int min_pos, mid_pos, max_pos;
-
-  LttvTraceState *tcs;
-
-  LttvAttributeValue value;
-
-  LttvAttributeType type;
-
-  LttvAttributeName name;
-
-  LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceState *)self->parent.traces[i];
-
-    saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
-        LTTV_STATE_SAVED_STATES);
-    min_pos = -1;
-    max_pos = lttv_attribute_get_number(saved_states_tree) - 1;
-    mid_pos = max_pos / 2;
-    while(min_pos < max_pos) {
-      type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value);
-      g_assert(type == LTTV_GOBJECT);
-      saved_state_tree = *((LttvAttribute **)(value.v_gobject));
-      type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME, 
-          &value);
-      g_assert(type == LTTV_TIME);
-      if(ltt_time_compare(*(value.v_time), t) < 0) {
-        min_pos = mid_pos;
-        closest_tree = saved_state_tree;
-      }
-      else max_pos = mid_pos - 1;
-
-      mid_pos = (min_pos + max_pos + 1) / 2;
-    }
-    if(min_pos == -1) {
-      restore_init_state(tcs);
-      lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
-    }
-    else lttv_state_restore(tcs, closest_tree);
-  }
-}
-
-
-static void
-traceset_state_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-}
-
-
-static void
-traceset_state_finalize (LttvTracesetState *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-traceset_state_class_init (LttvTracesetContextClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) traceset_state_finalize;
-  klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
-  klass->fini = (void (*)(LttvTracesetContext *self))fini;
-  klass->new_traceset_context = new_traceset_context;
-  klass->new_trace_context = new_trace_context;
-  klass->new_tracefile_context = new_tracefile_context;
-}
-
-
-GType 
-lttv_traceset_state_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTracesetStateClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) traceset_state_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTracesetContext),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) traceset_state_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType", 
-        &info, 0);
-  }
-  return type;
-}
-
-
-static void
-trace_state_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-}
-
-
-static void
-trace_state_finalize (LttvTraceState *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_CONTEXT_TYPE))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-trace_state_class_init (LttvTraceStateClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) trace_state_finalize;
-  klass->state_save = state_save;
-  klass->state_restore = state_restore;
-  klass->state_saved_free = state_saved_free;
-}
-
-
-GType 
-lttv_trace_state_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTraceStateClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) trace_state_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTraceState),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) trace_state_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE, 
-        "LttvTraceStateType", &info, 0);
-  }
-  return type;
-}
-
-
-static void
-tracefile_state_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-}
-
-
-static void
-tracefile_state_finalize (LttvTracefileState *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_CONTEXT_TYPE))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-tracefile_state_class_init (LttvTracefileStateClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) tracefile_state_finalize;
-}
-
-
-GType 
-lttv_tracefile_state_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTracefileStateClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) tracefile_state_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTracefileState),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) tracefile_state_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE, 
-        "LttvTracefileStateType", &info, 0);
-  }
-  return type;
-}
-
-
-void lttv_state_init(int argc, char **argv)
-{
-  LTTV_STATE_UNNAMED = g_quark_from_string("unnamed");
-  LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("unknown execution mode");
-  LTTV_STATE_USER_MODE = g_quark_from_string("user mode");
-  LTTV_STATE_WAIT_FORK = g_quark_from_string("wait fork");
-  LTTV_STATE_SYSCALL = g_quark_from_string("system call");
-  LTTV_STATE_TRAP = g_quark_from_string("trap");
-  LTTV_STATE_IRQ = g_quark_from_string("irq");
-  LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("unknown submode");
-  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_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");
-  LTTV_STATE_PROCESSES = g_quark_from_string("processes");
-  LTTV_STATE_PROCESS = g_quark_from_string("process");
-  LTTV_STATE_EVENT = g_quark_from_string("event");
-  LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states");
-  LTTV_STATE_TIME = g_quark_from_string("time");
-  LTTV_STATE_HOOKS = g_quark_from_string("saved state hooks");
-}
-
-void lttv_state_destroy() 
-{
-}
-
-
-
-
diff --git a/ltt/branches/poly/lttv/mainLib/stats.c b/ltt/branches/poly/lttv/mainLib/stats.c
deleted file mode 100644 (file)
index 4265853..0000000
+++ /dev/null
@@ -1,1180 +0,0 @@
-
-#include <stdio.h>
-#include <lttv/stats.h>
-#include <ltt/facility.h>
-#include <ltt/trace.h>
-#include <ltt/event.h>
-
-#define BUF_SIZE 256
-
-GQuark
-  LTTV_STATS_PROCESS_UNKNOWN,
-  LTTV_STATS_PROCESSES,
-  LTTV_STATS_CPU,
-  LTTV_STATS_MODE_TYPES,
-  LTTV_STATS_MODES,
-  LTTV_STATS_SUBMODES,
-  LTTV_STATS_EVENT_TYPES,
-  LTTV_STATS_CPU_TIME,
-  LTTV_STATS_ELAPSED_TIME,
-  LTTV_STATS_EVENTS,
-  LTTV_STATS_EVENTS_COUNT;
-
-static GQuark
-  LTTV_STATS_BEFORE_HOOKS,
-  LTTV_STATS_AFTER_HOOKS;
-
-static void remove_all_processes(GHashTable *processes);
-
-static void
-find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu,
-    GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, 
-    LttvAttribute **event_types_tree);
-
-static void
-init(LttvTracesetStats *self, LttvTraceset *ts)
-{
-  guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceContext *tc;
-
-  LttvTraceStats *tcs;
-
-  LttvTracefileContext *tfc;
-
-  LttvTracefileStats *tfcs;
-  
-  LttTime timestamp = {0,0};
-
-  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
-      init((LttvTracesetContext *)self, ts);
-
-  self->stats = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-  nb_trace = lttv_traceset_number(ts);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceStats *)tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]);
-    tcs->stats = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-
-    nb_control = ltt_trace_control_tracefile_number(tc->t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfcs = LTTV_TRACEFILE_STATS(tc->control_tracefiles[j]);
-      }
-      else {
-        tfcs = LTTV_TRACEFILE_STATS(tc->per_cpu_tracefiles[j - nb_control]);
-      }
-
-      tfcs->stats = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-      find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
-          tfcs->parent.cpu_name, LTTV_STATE_MODE_UNKNOWN, 
-          LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
-          &tfcs->current_event_types_tree);
-    }
-  }
-}
-
-
-static void
-fini(LttvTracesetStats *self)
-{
-  guint i, j, nb_trace, nb_tracefile;
-
-  LttvTraceset *ts;
-
-  LttvTraceContext *tc;
-
-  LttvTraceStats *tcs;
-
-  LttvTracefileContext *tfc;
-
-  LttvTracefileStats *tfcs;
-  
-  LttTime timestamp = {0,0};
-
-  lttv_attribute_recursive_free(self->stats);
-  ts = self->parent.parent.ts;
-  nb_trace = lttv_traceset_number(ts);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceStats *)tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]);
-    lttv_attribute_recursive_free(tcs->stats);
-
-    nb_tracefile = ltt_trace_control_tracefile_number(tc->t);
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      tfcs = (LttvTracefileStats *)tfc = tc->control_tracefiles[j];
-      lttv_attribute_recursive_free(tfcs->stats);
-      tfcs->current_events_tree = NULL;
-      tfcs->current_event_types_tree = NULL;
-    }
-
-    nb_tracefile = ltt_trace_per_cpu_tracefile_number(tc->t);
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      tfcs = (LttvTracefileStats *)tfc = tc->per_cpu_tracefiles[j];
-      lttv_attribute_recursive_free(tfcs->stats);
-      tfcs->current_events_tree = NULL;
-      tfcs->current_event_types_tree = NULL;
-    }
-  }
-  LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
-      fini((LttvTracesetContext *)self);
-}
-
-
-static LttvTracesetContext *
-new_traceset_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL));
-}
-
-
-static LttvTraceContext * 
-new_trace_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL));
-}
-
-
-static LttvTracefileContext *
-new_tracefile_context(LttvTracesetContext *self)
-{
-  return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL));
-}
-
-
-static void
-traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-}
-
-
-static void
-traceset_stats_finalize (LttvTracesetStats *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-traceset_stats_class_init (LttvTracesetContextClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize;
-  klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
-  klass->fini = (void (*)(LttvTracesetContext *self))fini;
-  klass->new_traceset_context = new_traceset_context;
-  klass->new_trace_context = new_trace_context;
-  klass->new_tracefile_context = new_tracefile_context;
-}
-
-
-GType 
-lttv_traceset_stats_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTracesetStatsClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) traceset_stats_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTracesetContext),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) traceset_stats_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (LTTV_TRACESET_STATE_TYPE, "LttvTracesetStatsType", 
-        &info, 0);
-  }
-  return type;
-}
-
-
-static void
-trace_stats_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-}
-
-
-static void
-trace_stats_finalize (LttvTraceStats *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-trace_stats_class_init (LttvTraceContextClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize;
-}
-
-
-GType 
-lttv_trace_stats_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTraceStatsClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) trace_stats_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTraceStats),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) trace_stats_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (LTTV_TRACE_STATE_TYPE, 
-        "LttvTraceStatsType", &info, 0);
-  }
-  return type;
-}
-
-
-static void
-tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class)
-{
-}
-
-
-static void
-tracefile_stats_finalize (LttvTracefileStats *self)
-{
-  G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))->
-      finalize(G_OBJECT(self));
-}
-
-
-static void
-tracefile_stats_class_init (LttvTracefileStatsClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
-  gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize;
-}
-
-
-GType 
-lttv_tracefile_stats_get_type(void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (LttvTracefileStatsClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      (GClassInitFunc) tracefile_stats_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (LttvTracefileStats),
-      0,      /* n_preallocs */
-      (GInstanceInitFunc) tracefile_stats_instance_init    /* instance_init */
-    };
-
-    type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE, 
-        "LttvTracefileStatsType", &info, 0);
-  }
-  return type;
-}
-
-
-static void
-find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu,
-    GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, 
-    LttvAttribute **event_types_tree)
-{
-  LttvAttribute *a;
-
-  LttvTraceStats *tcs = LTTV_TRACE_STATS(tfcs->parent.parent.t_context);
-  a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES);
-  a = lttv_attribute_find_subdir(a, tfcs->parent.process->pid_time);
-  a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU);
-  a = lttv_attribute_find_subdir(a, tfcs->parent.cpu_name);
-  a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES);
-  a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->t);
-  a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES);
-  a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->n);
-  *events_tree = a;
-  a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES);
-  *event_types_tree = a;
-}
-
-
-static void update_event_tree(LttvTracefileStats *tfcs) 
-{
-  LttvExecutionState *es = tfcs->parent.process->state;
-
-  find_event_tree(tfcs, tfcs->parent.process->pid_time, tfcs->parent.cpu_name, 
-      es->t, es->n, &(tfcs->current_events_tree), 
-      &(tfcs->current_event_types_tree));
-}
-
-
-static void mode_change(LttvTracefileStats *tfcs)
-{
-  LttvAttributeValue cpu_time; 
-
-  LttTime delta;
-
-  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, 
-      LTTV_TIME, &cpu_time);
-  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
-      tfcs->parent.process->state->change);
-  *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
-}
-
-
-static void mode_end(LttvTracefileStats *tfcs)
-{
-  LttvAttributeValue elapsed_time, cpu_time; 
-
-  LttTime delta;
-
-  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME, 
-      LTTV_TIME, &elapsed_time);
-  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
-      tfcs->parent.process->state->entry);
-  *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
-
-  lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, 
-      LTTV_TIME, &cpu_time);
-  delta = ltt_time_sub(tfcs->parent.parent.timestamp, 
-      tfcs->parent.process->state->change);
-  *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
-}
-
-
-static gboolean before_syscall_entry(void *hook_data, void *call_data)
-{
-  mode_change((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-static gboolean after_syscall_entry(void *hook_data, void *call_data)
-{
-  update_event_tree((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean before_syscall_exit(void *hook_data, void *call_data)
-{
-  mode_end((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-static gboolean after_syscall_exit(void *hook_data, void *call_data)
-{
-  update_event_tree((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean before_trap_entry(void *hook_data, void *call_data)
-{
-  mode_change((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-static gboolean after_trap_entry(void *hook_data, void *call_data)
-{
-  update_event_tree((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean before_trap_exit(void *hook_data, void *call_data)
-{
-  mode_end((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean after_trap_exit(void *hook_data, void *call_data)
-{
-  update_event_tree((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean before_irq_entry(void *hook_data, void *call_data)
-{
-  mode_change((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean after_irq_entry(void *hook_data, void *call_data)
-{
-  update_event_tree((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean before_irq_exit(void *hook_data, void *call_data)
-{
-  mode_end((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean after_irq_exit(void *hook_data, void *call_data)
-{
-  update_event_tree((LttvTracefileStats *)call_data);
-  return FALSE;
-}
-
-
-gboolean before_schedchange(void *hook_data, void *call_data)
-{
-  LttvTraceHook *h = (LttvTraceHook *)hook_data;
-
-  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
-
-  guint pid_in, pid_out, state_out;
-
-  LttvProcessState *process;
-
-  pid_in = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f1);
-  pid_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f2);
-  state_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f3);
-
-  /* compute the time for the process to schedule out */
-
-  mode_change(tfcs);
-
-  /* get the information for the process scheduled in */
-
-  process = lttv_state_find_process(&(tfcs->parent), pid_in);
-
-  find_event_tree(tfcs, process->pid_time, tfcs->parent.cpu_name, 
-      process->state->t, process->state->n, &(tfcs->current_events_tree), 
-      &(tfcs->current_event_types_tree));
-
-  /* compute the time waiting for the process to schedule in */
-
-  mode_change(tfcs);
-  return FALSE;
-}
-
-
-gboolean process_fork(void *hook_data, void *call_data)
-{
-  /* nothing to do for now */
-  return FALSE;
-}
-
-
-gboolean process_exit(void *hook_data, void *call_data)
-{
-  /* We should probably exit all modes here or we could do that at 
-     schedule out. */
-  return FALSE;
-}
-
-
-gboolean every_event(void *hook_data, void *call_data)
-{
-  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
-
-  LttvAttributeValue v;
-
-  /* The current branch corresponds to the tracefile/process/interrupt state.
-     Statistics are added within it, to count the number of events of this
-     type occuring in this context. A quark has been pre-allocated for each
-     event type and is used as name. */
-
-  lttv_attribute_find(tfcs->current_event_types_tree, 
-      ((LttvTraceState *)(tfcs->parent.parent.t_context))->
-      eventtype_names[ltt_event_eventtype_id(tfcs->parent.parent.e)], 
-      LTTV_UINT, &v);
-  (*(v.v_uint))++;
-  return FALSE;
-}
-
-
-static gboolean 
-sum_stats(void *hook_data, void *call_data)
-{
-  LttvTracesetStats *tscs = (LttvTracesetStats *)call_data;
-
-  LttvTraceStats *tcs;
-
-  LttvTraceset *traceset = tscs->parent.parent.ts;
-
-  LttvAttributeType type;
-
-  LttvAttributeValue value;
-
-  LttvAttributeName name;
-
-  unsigned sum;
-
-  int i, j, k, l, m, n, nb_trace, nb_process, nb_cpu, nb_mode_type, nb_submode,
-      nb_event_type;
-
-  LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
-      *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
-      *submode_tree, *event_types_tree, *mode_events_tree,
-      *cpu_events_tree, *process_modes_tree, *trace_cpu_tree, 
-      *trace_modes_tree, *traceset_modes_tree;
-
-  traceset_modes_tree = lttv_attribute_find_subdir(tscs->stats, 
-      LTTV_STATS_MODES);
-  nb_trace = lttv_traceset_number(traceset);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]);
-    main_tree = tcs->stats;
-    processes_tree = lttv_attribute_find_subdir(main_tree, 
-        LTTV_STATS_PROCESSES);
-    trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES);
-    nb_process = lttv_attribute_get_number(processes_tree);
-
-    for(j = 0 ; j < nb_process ; j++) {
-      type = lttv_attribute_get(processes_tree, j, &name, &value);
-      process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-      cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
-      process_modes_tree = lttv_attribute_find_subdir(process_tree,
-          LTTV_STATS_MODES);
-      nb_cpu = lttv_attribute_get_number(cpus_tree);
-
-      for(k = 0 ; k < nb_cpu ; k++) {
-        type = lttv_attribute_get(cpus_tree, k, &name, &value);
-        cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-        mode_types_tree = lttv_attribute_find_subdir(cpu_tree, 
-            LTTV_STATS_MODE_TYPES);
-        cpu_events_tree = lttv_attribute_find_subdir(cpu_tree,
-            LTTV_STATS_EVENTS);
-        trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU);
-        trace_cpu_tree = lttv_attribute_find_subdir(trace_cpu_tree, name);
-        nb_mode_type = lttv_attribute_get_number(mode_types_tree);
-
-        for(l = 0 ; l < nb_mode_type ; l++) {
-          type = lttv_attribute_get(mode_types_tree, l, &name, &value);
-          mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-          submodes_tree = lttv_attribute_find_subdir(mode_tree, 
-              LTTV_STATS_SUBMODES);
-          mode_events_tree = lttv_attribute_find_subdir(mode_tree,
-             LTTV_STATS_EVENTS);
-          nb_submode = lttv_attribute_get_number(submodes_tree);
-
-          for(m = 0 ; m < nb_submode ; m++) {
-            type = lttv_attribute_get(submodes_tree, m, &name, &value);
-            submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-            event_types_tree = lttv_attribute_find_subdir(submode_tree, 
-              LTTV_STATS_EVENT_TYPES);
-            nb_event_type = lttv_attribute_get_number(event_types_tree);
-
-            sum = 0;
-            for(n = 0 ; n < nb_event_type ; n++) {
-              type = lttv_attribute_get(event_types_tree, n, &name, &value);
-              sum += *(value.v_uint);
-            }
-            lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT, 
-                LTTV_UINT, &value);
-            *(value.v_uint) = sum;
-            lttv_attribute_recursive_add(mode_events_tree, submode_tree);
-          }
-         lttv_attribute_recursive_add(cpu_events_tree, mode_events_tree);
-        }
-        lttv_attribute_recursive_add(process_modes_tree, cpu_tree);
-        lttv_attribute_recursive_add(trace_cpu_tree, cpu_tree);
-      }
-      lttv_attribute_recursive_add(trace_modes_tree, process_modes_tree);
-    }
-    lttv_attribute_recursive_add(traceset_modes_tree, trace_modes_tree);
-  }
-  return FALSE;
-}
-
-
-lttv_stats_add_event_hooks(LttvTracesetStats *self)
-{
-  LttvTraceset *traceset = self->parent.parent.ts;
-
-  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttFacility *f;
-
-  LttEventType *et;
-
-  LttvTraceStats *ts;
-
-  LttvTracefileStats *tfs;
-
-  void *hook_data;
-
-  GArray *hooks, *before_hooks, *after_hooks;
-
-  LttvTraceHook hook;
-
-  LttvAttributeValue val;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    ts = (LttvTraceStats *)self->parent.parent.traces[i];
-
-    /* Find the eventtype id for the following events and register the
-       associated by id hooks. */
-
-    hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
-    g_array_set_size(hooks, 7);
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry",
-        "syscall_id", NULL, NULL, before_syscall_entry, 
-        &g_array_index(hooks, LttvTraceHook, 0));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, 
-        NULL, NULL, before_syscall_exit, 
-        &g_array_index(hooks, LttvTraceHook, 1));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id",
-       NULL, NULL, before_trap_entry, 
-        &g_array_index(hooks, LttvTraceHook, 2));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL,
-       NULL, before_trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id",
-       NULL, NULL, before_irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL,
-       NULL, before_irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "schedchange", "in", 
-        "out", "out_state", before_schedchange, 
-         &g_array_index(hooks, LttvTraceHook, 6));
-
-    before_hooks = hooks;
-
-    hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
-    g_array_set_size(hooks, 8);
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry",
-        "syscall_id", NULL, NULL, after_syscall_entry, 
-        &g_array_index(hooks, LttvTraceHook, 0));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, 
-        NULL, NULL, after_syscall_exit, 
-        &g_array_index(hooks, LttvTraceHook, 1));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id",
-       NULL, NULL, after_trap_entry, &g_array_index(hooks, LttvTraceHook, 2));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL,
-       NULL, after_trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id",
-       NULL, NULL, after_irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL,
-       NULL, after_irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "process_fork", 
-        "child_pid", NULL, NULL, process_fork, 
-        &g_array_index(hooks, LttvTraceHook, 6));
-
-    lttv_trace_find_hook(ts->parent.parent.t, "core", "process_exit", NULL, 
-        NULL, NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 7));
-
-    after_hooks = hooks;
-
-    /* Add these hooks to each before_event_by_id hooks list */
-
-    nb_control = ltt_trace_control_tracefile_number(ts->parent.parent.t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.control_tracefiles[j]);
-      }
-      else {
-        tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.per_cpu_tracefiles[
-            j-nb_control]);
-      }
-
-      lttv_hooks_add(tfs->parent.parent.after_event, every_event, NULL);
-
-      for(k = 0 ; k < before_hooks->len ; k++) {
-        hook = g_array_index(before_hooks, LttvTraceHook, k);
-        lttv_hooks_add(lttv_hooks_by_id_find(
-            tfs->parent.parent.before_event_by_id, 
-           hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k));
-      }
-      for(k = 0 ; k < after_hooks->len ; k++) {
-        hook = g_array_index(after_hooks, LttvTraceHook, k);
-        lttv_hooks_add(lttv_hooks_by_id_find(
-            tfs->parent.parent.after_event_by_id, 
-           hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k));
-      }
-    }
-    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
-        LTTV_POINTER, &val);
-    *(val.v_pointer) = before_hooks;
-    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, 
-        LTTV_POINTER, &val);
-    *(val.v_pointer) = after_hooks;
-  }
-  lttv_hooks_add(self->parent.parent.after, sum_stats, NULL);
-}
-
-
-lttv_stats_remove_event_hooks(LttvTracesetStats *self)
-{
-  LttvTraceset *traceset = self->parent.parent.ts;
-
-  guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
-
-  LttvTraceStats *ts;
-
-  LttvTracefileStats *tfs;
-
-  void *hook_data;
-
-  GArray *before_hooks, *after_hooks;
-
-  LttvTraceHook hook;
-
-  LttvAttributeValue val;
-
-  nb_trace = lttv_traceset_number(traceset);
-  for(i = 0 ; i < nb_trace ; i++) {
-    ts = LTTV_TRACE_STATS(self->parent.parent.traces[i]);
-    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
-        LTTV_POINTER, &val);
-    before_hooks = *(val.v_pointer);
-    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, 
-        LTTV_POINTER, &val);
-    after_hooks = *(val.v_pointer);
-
-    /* Add these hooks to each before_event_by_id hooks list */
-
-    nb_control = ltt_trace_control_tracefile_number(ts->parent.parent.t);
-    nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t);
-    nb_tracefile = nb_control + nb_per_cpu;
-    for(j = 0 ; j < nb_tracefile ; j++) {
-      if(j < nb_control) {
-        tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.control_tracefiles[j]);
-      }
-      else {
-        tfs =LTTV_TRACEFILE_STATS(ts->parent.parent.per_cpu_tracefiles[
-            j-nb_control]);
-      }
-
-      lttv_hooks_remove_data(tfs->parent.parent.after_event, every_event, 
-          NULL);
-
-      for(k = 0 ; k < before_hooks->len ; k++) {
-        hook = g_array_index(before_hooks, LttvTraceHook, k);
-        lttv_hooks_remove_data(
-            lttv_hooks_by_id_find(tfs->parent.parent.before_event_by_id, 
-           hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k));
-      }
-      for(k = 0 ; k < after_hooks->len ; k++) {
-        hook = g_array_index(after_hooks, LttvTraceHook, k);
-        lttv_hooks_remove_data(
-            lttv_hooks_by_id_find(tfs->parent.parent.after_event_by_id, 
-           hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k));
-      }
-    }
-    g_critical("lttv_stats_remove_event_hooks()");
-    g_array_free(before_hooks, TRUE);
-    g_array_free(after_hooks, TRUE);
-  }
-  lttv_hooks_remove_data(self->parent.parent.after, sum_stats, NULL);
-}
-
-
-void lttv_stats_init(int argc, char **argv)
-{
-  LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process");
-  LTTV_STATS_PROCESSES = g_quark_from_string("processes");
-  LTTV_STATS_CPU = g_quark_from_string("cpu");
-  LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types");
-  LTTV_STATS_MODES = g_quark_from_string("modes");
-  LTTV_STATS_SUBMODES = g_quark_from_string("submodes");
-  LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types");
-  LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time");
-  LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time");
-  LTTV_STATS_EVENTS = g_quark_from_string("events");
-  LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count");
-  LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks");
-  LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks");
-}
-
-void lttv_stats_destroy() 
-{
-}
-
-void lttv_stats_save_attribute(LttvAttribute *attr, char *indent, FILE * fp)
-{
-  LttvAttributeType type;
-  LttvAttributeValue value;
-  LttvAttributeName name;
-  char type_value[BUF_SIZE];
-  int i, nb_attr, flag;
-
-  nb_attr = lttv_attribute_get_number(attr);
-  for(i=0;i<nb_attr;i++){
-    flag = 1;
-    type = lttv_attribute_get(attr, i, &name, &value);
-    switch(type) {
-      case LTTV_INT:
-        sprintf(type_value, "%d\0", *value.v_int);
-        break;
-      case LTTV_UINT:
-        sprintf(type_value, "%u\0", *value.v_uint);
-        break;
-      case LTTV_LONG:
-        sprintf(type_value, "%ld\0", *value.v_long);
-        break;
-      case LTTV_ULONG:
-        sprintf(type_value, "%lu\0", *value.v_ulong);
-        break;
-      case LTTV_FLOAT:
-        sprintf(type_value, "%f\0", (double)*value.v_float);
-        break;
-      case LTTV_DOUBLE:
-        sprintf(type_value, "%f\0", *value.v_double);
-        break;
-      case LTTV_TIME:
-        sprintf(type_value, "%10u.%09u\0", value.v_time->tv_sec, 
-            value.v_time->tv_nsec);
-        break;
-      case LTTV_POINTER:
-        sprintf(type_value, "POINTER\0");
-        break;
-      case LTTV_STRING:
-        sprintf(type_value, "%s\0", *value.v_string);
-        break;
-      default:
-       flag = 0;
-        break;
-    }
-    if(flag == 0) continue;
-    fprintf(fp,"%s<VALUE type=\"%d\" name=\"%s\">",indent,type,g_quark_to_string(name));
-    fprintf(fp,"%s",type_value);
-    fprintf(fp,"</VALUE> \n");
-  }
-  
-}
-
-void lttv_stats_save_statistics(LttvTracesetStats *self)
-{
-  LttvTracesetStats *tscs = self;
-  LttvTraceStats *tcs;
-  LttvTraceset *traceset = tscs->parent.parent.ts;
-  LttvAttributeType type;
-  LttvAttributeValue value;
-  LttvAttributeName name;
-
-  char filename[BUF_SIZE];
-  FILE * fp;
-  char indent[10][24]= {"  ",
-                       "    ",
-                       "      ",
-                       "        ",
-                       "          ",
-                       "            ",
-                       "              ",
-                       "                ",
-                       "                  ",
-                       "                    "
-                       };
-  
-
-  int i, j, k, l, m, n, nb_trace, nb_process, nb_cpu, nb_mode_type, nb_submode;
-
-  LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
-      *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
-      *submode_tree, *event_types_tree;
-
-  nb_trace = lttv_traceset_number(traceset);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]);
-
-    filename[0] = '\0';
-    strcat(filename,ltt_trace_name(tcs->parent.parent.t));
-    strcat(filename,"/statistics.xml");
-    fp = fopen(filename,"w");
-    if(!fp){
-      g_warning("can not open the file %s for saving statistics\n", filename);
-      exit(1);
-    }    
-
-    main_tree = tcs->stats;
-    processes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_PROCESSES);
-    nb_process = lttv_attribute_get_number(processes_tree);
-
-    fprintf(fp, "<NODE name=\"%s\"> \n",g_quark_to_string(LTTV_STATS_PROCESSES)); //root NODE
-
-    for(j = 0 ; j < nb_process ; j++) {
-      type = lttv_attribute_get(processes_tree, j, &name, &value);
-      process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-      fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[0],g_quark_to_string(name)); //process NODE   
-      lttv_stats_save_attribute(process_tree,indent[1], fp);
-      fprintf(fp,"%s<NODE name=\"%s\"> \n", indent[1],g_quark_to_string(LTTV_STATS_CPU)); //cpus NODE
-      
-      cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
-      nb_cpu = lttv_attribute_get_number(cpus_tree);
-
-      for(k = 0 ; k < nb_cpu ; k++) {
-        type = lttv_attribute_get(cpus_tree, k, &name, &value);
-        cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-       fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[2],g_quark_to_string(name)); //cpu NODE
-       lttv_stats_save_attribute(cpu_tree,indent[3], fp);
-       fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[3],g_quark_to_string(LTTV_STATS_MODE_TYPES)); //mode_types NODE
-
-        mode_types_tree = lttv_attribute_find_subdir(cpu_tree,LTTV_STATS_MODE_TYPES);
-        nb_mode_type = lttv_attribute_get_number(mode_types_tree);
-
-        for(l = 0 ; l < nb_mode_type ; l++) {
-          type = lttv_attribute_get(mode_types_tree, l, &name, &value);
-          mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-
-         fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[4],g_quark_to_string(name)); //mode NODE
-         lttv_stats_save_attribute(mode_tree,indent[5], fp);
-         fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[5],g_quark_to_string(LTTV_STATS_SUBMODES)); //sub_modes NODE
-
-          submodes_tree = lttv_attribute_find_subdir(mode_tree,LTTV_STATS_SUBMODES);
-          nb_submode = lttv_attribute_get_number(submodes_tree);
-
-          for(m = 0 ; m < nb_submode ; m++) {
-            type = lttv_attribute_get(submodes_tree, m, &name, &value);
-            submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
-           fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[6],g_quark_to_string(name)); //sub_mode NODE
-           lttv_stats_save_attribute(submode_tree,indent[7], fp);
-           fprintf(fp,"%s<NODE name=\"%s\"> \n",indent[7],g_quark_to_string(LTTV_STATS_EVENT_TYPES)); //event_types NODE
-
-            event_types_tree = lttv_attribute_find_subdir(submode_tree, LTTV_STATS_EVENT_TYPES);
-           lttv_stats_save_attribute(event_types_tree,indent[8], fp);
-
-           fprintf(fp,"%s</NODE> \n",indent[7]); //event_types NODE
-           fprintf(fp,"%s</NODE> \n",indent[6]); //sub_mode NODE
-          }
-         fprintf(fp,"%s</NODE> \n",indent[5]); //sub_modes NODE
-         fprintf(fp,"%s</NODE> \n",indent[4]); //mode NODE
-        }
-       fprintf(fp,"%s</NODE> \n",indent[3]); //mode_type NODE
-       fprintf(fp,"%s</NODE> \n",indent[2]); //cpu NODE
-      }
-      fprintf(fp,"%s</NODE> \n",indent[1]); //cpus NODE
-      fprintf(fp,"%s</NODE> \n", indent[0]); //process NODE
-    }
-    fprintf(fp, "</NODE>\n"); //root NODE
-    fclose(fp);
-  }
-}
-
-
-/* Functions to parse statistic.xml file (using glib xml parser) */
-
-typedef struct _ParserStruct{
-  GPtrArray * attribute;
-  LttvAttributeType type;
-  LttvAttributeName name;  
-} ParserStruct;
-
-static void stats_parser_start_element (GMarkupParseContext  *context,
-                                       const gchar          *element_name,
-                                       const gchar         **attribute_names,
-                                       const gchar         **attribute_values,
-                                       gpointer              user_data,
-                                       GError              **error)
-{
-  ParserStruct * parser = (ParserStruct *)user_data;
-  int len;
-  LttvAttributeType type;
-  LttvAttributeName name;
-  LttvAttribute * parent_att, *new_att;
-
-  len = parser->attribute->len;
-  parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1);
-
-  if(strcmp("NODE", element_name) == 0){
-    type = LTTV_GOBJECT;
-    name = g_quark_from_string(attribute_values[0]);
-    new_att = lttv_attribute_find_subdir(parent_att,name);
-    g_ptr_array_add(parser->attribute, (gpointer)new_att);
-  }else if(strcmp("VALUE", element_name) == 0){
-    parser->type = (LttvAttributeType) atoi(attribute_values[0]);
-    parser->name = g_quark_from_string(attribute_values[1]);    
-  }else{
-    g_warning("This is not statistics.xml file\n");
-    exit(1);
-  }
-}
-
-static void stats_parser_end_element   (GMarkupParseContext  *context,
-                                       const gchar          *element_name,
-                                       gpointer              user_data,
-                                       GError              **error)
-{
-  ParserStruct * parser = (ParserStruct *)user_data;
-  int len;
-  LttvAttribute * parent_att;
-
-  len = parser->attribute->len;
-  parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1);
-
-  if(strcmp("NODE", element_name) == 0){
-    g_ptr_array_remove_index(parser->attribute, len-1);
-  }else if(strcmp("VALUE", element_name) == 0){
-  }else{
-    g_warning("This is not statistics.xml file\n");
-    exit(1);
-  }
-  
-}
-
-static void  stats_parser_characters   (GMarkupParseContext  *context,
-                                       const gchar          *text,
-                                       gsize                 text_len,
-                                       gpointer              user_data,
-                                       GError              **error)
-{
-  ParserStruct * parser = (ParserStruct *)user_data;
-  LttvAttributeValue  value;
-  int len;
-  LttvAttribute * parent_att;
-  char *pos;
-
-  pos = (char*)text;
-  for(len=0;len<text_len;len++){
-    if(isspace(*pos)){
-      pos++;
-      continue;
-    }
-    break;
-  }
-  if(strlen(pos) == 0)return;
-
-  len = parser->attribute->len;
-  parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1);
-  if(!lttv_attribute_find(parent_att,parser->name, parser->type, &value)){
-    g_warning("can not find value\n");
-    exit(1);
-  }
-
-  switch(parser->type) {
-    case LTTV_INT:
-      *value.v_int = atoi(text);
-      break;
-    case LTTV_UINT:
-      *value.v_uint = (unsigned)atoi(text);
-      break;
-    case LTTV_LONG:
-      *value.v_long = atol(text);
-      break;
-    case LTTV_ULONG:
-      *value.v_ulong = (unsigned long)atol(text);
-      break;
-    case LTTV_FLOAT:
-      *value.v_float = atof(text);
-      break;
-    case LTTV_DOUBLE:
-      *value.v_float = atof(text);
-      break;
-    case LTTV_TIME:
-      pos = strrchr(text,'.');
-      if(pos){
-       *pos = '\0';
-       pos++;
-       value.v_time->tv_sec = atol(text);
-       value.v_time->tv_nsec = atol(pos);
-      }else{
-       g_warning("The time value format is wrong\n");
-       exit(1);
-      }
-      break;
-    case LTTV_POINTER:
-      break;
-    case LTTV_STRING:
-      *value.v_string = g_strdup(text);
-      break;
-    default:
-      break;
-  }
-
-}
-
-gboolean lttv_stats_load_statistics(LttvTracesetStats *self)
-{
-  FILE * fp;
-  char buf[BUF_SIZE];
-  LttvTracesetStats *tscs = self;
-  LttvTraceStats *tcs;
-  LttvTraceset *traceset = tscs->parent.parent.ts;
-  char filename[BUF_SIZE];
-
-  GMarkupParseContext * context;
-  GError * error;
-  GMarkupParser markup_parser =
-    {
-      stats_parser_start_element,
-      stats_parser_end_element,
-      stats_parser_characters,
-      NULL,  /*  passthrough  */
-      NULL   /*  error        */
-    };
-
-  int i, nb_trace;
-  LttvAttribute *main_tree;
-  ParserStruct a_parser_struct;
-  a_parser_struct.attribute = g_ptr_array_new(); 
-
-  nb_trace = lttv_traceset_number(traceset);
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]);
-
-    filename[0] = '\0';
-    strcat(filename,ltt_trace_name(tcs->parent.parent.t));
-    strcat(filename,"/statistics.xml");
-    fp = fopen(filename,"r");
-    if(!fp){
-      g_warning("can not open the file %s for reading statistics\n", filename);
-      return FALSE;
-    }    
-
-    main_tree = tcs->stats;
-    g_ptr_array_add(a_parser_struct.attribute,(gpointer)main_tree);
-
-    context = g_markup_parse_context_new(&markup_parser, 0, (gpointer)&a_parser_struct, NULL);
-    
-    while(fgets(buf,BUF_SIZE, fp) != NULL){
-      if(!g_markup_parse_context_parse(context, buf, BUF_SIZE, &error)){
-       g_warning("Can not parse xml file: \n%s\n", error->message);
-       exit(1);
-      }
-    }
-    fclose(fp);
-  }
-
-  sum_stats(NULL, (void *)self);
-
-  return TRUE;
-}
diff --git a/ltt/branches/poly/lttv/mainLib/traceset.c b/ltt/branches/poly/lttv/mainLib/traceset.c
deleted file mode 100644 (file)
index ce96b99..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-
-#include <lttv/traceset.h>
-#include <stdio.h>
-
-/* A trace is a sequence of events gathered in the same tracing session. The
-   events may be stored in several tracefiles in the same directory. 
-   A trace set is defined when several traces are to be analyzed together,
-   possibly to study the interactions between events in the different traces. 
-*/
-
-struct _LttvTraceset {
-  char * filename;
-  GPtrArray *traces;
-  LttvAttribute *a;
-};
-
-
-struct _LttvTrace {
-  LttTrace *t;
-  LttvAttribute *a;
-  guint ref_count;
-};
-
-
-LttvTraceset *lttv_traceset_new() 
-{
-  LttvTraceset *s;
-
-  s = g_new(LttvTraceset, 1);
-  s->filename = NULL;
-  s->traces = g_ptr_array_new();
-  s->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-  return s;
-}
-
-char * lttv_traceset_name(LttvTraceset * s)
-{
-  return s->filename;
-}
-
-LttvTrace *lttv_trace_new(LttTrace *t) 
-{
-  LttvTrace *new_trace;
-
-  new_trace = g_new(LttvTrace, 1);
-  new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-  new_trace->t = t;
-  new_trace->ref_count = 0;
-  return new_trace;
-}
-
-
-LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig) 
-{
-  int i;
-  LttvTraceset *s;
-  LttvTrace * trace;
-
-  s = g_new(LttvTraceset, 1);
-  s->filename = NULL;
-  s->traces = g_ptr_array_new();
-  for(i=0;i<s_orig->traces->len;i++)
-  {
-    trace = g_ptr_array_index(s_orig->traces, i);
-    trace->ref_count++;
-
-    /*CHECK this used ltt_trace_copy while it may not be needed. Need to
-      define how traces and tracesets are shared */
-    g_ptr_array_add(
-        s->traces,
-       g_ptr_array_index(s_orig->traces, i));
-  }
-  s->a = LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig->a)));
-  return s;
-}
-
-
-LttvTraceset *lttv_traceset_load(const gchar *filename)
-{
-  LttvTraceset *s = g_new(LttvTraceset,1);
-  FILE *tf;
-  
-  s->filename = g_strdup(filename);
-  tf = fopen(filename,"r");
-
-  g_critical("NOT IMPLEMENTED : load traceset data from a XML file");
-  
-  fclose(tf);
-  return s;
-}
-
-gint lttv_traceset_save(LttvTraceset *s)
-{
-  FILE *tf;
-
-  tf = fopen(s->filename, "w");
-  
-  g_critical("NOT IMPLEMENTED : save traceset data in a XML file");
-
-  fclose(tf);
-  return 0;
-}
-
-void lttv_traceset_destroy(LttvTraceset *s) 
-{
-  g_ptr_array_free(s->traces, TRUE);
-  g_object_unref(s->a);
-  g_free(s);
-}
-
-void lttv_trace_destroy(LttvTrace *t) 
-{
-  g_object_unref(t->a);
-  g_free(t);
-}
-
-
-void lttv_traceset_add(LttvTraceset *s, LttvTrace *t) 
-{
-  t->ref_count++;
-  g_ptr_array_add(s->traces, t);
-}
-
-
-unsigned lttv_traceset_number(LttvTraceset *s) 
-{
-  return s->traces->len;
-}
-
-
-LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i) 
-{
-  g_assert(s->traces->len > i);
-  return ((LttvTrace *)s->traces->pdata[i]);
-}
-
-
-void lttv_traceset_remove(LttvTraceset *s, unsigned i) 
-{
-  LttvTrace * t;
-  g_assert(s->traces->len > i);
-  t = (LttvTrace *)s->traces->pdata[i];
-  t->ref_count--;
-  g_ptr_array_remove_index(s->traces, i);
-}
-
-
-/* A set of attributes is attached to each trace set, trace and tracefile
-   to store user defined data as needed. */
-
-LttvAttribute *lttv_traceset_attribute(LttvTraceset *s) 
-{
-  return s->a;
-}
-
-
-LttvAttribute *lttv_trace_attribute(LttvTrace *t)
-{
-  return t->a;
-}
-
-
-LttTrace *lttv_trace(LttvTrace *t)
-{
-  return t->t;
-}
-
-guint lttv_trace_get_ref_number(LttvTrace * t)
-{
-  return t->ref_count;
-}
This page took 0.103737 seconds and 4 git commands to generate.