fix note reserving byte order in calc_nsec_per_cycle
[lttv.git] / ltt / branches / poly / lttv / lttv / tracecontext.c
index 5b6cdba7f379122440a57b3aa212ff5547d4315b..a73e3d6ce608e12a8e66ecdab293f8afd23a9371 100644 (file)
  * MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
+#include <string.h>
 #include <lttv/tracecontext.h>
 #include <ltt/event.h>
 #include <ltt/facility.h>
 #include <ltt/trace.h>
 #include <ltt/type.h>
+#include <errno.h>
 
 
 
 
 gint compare_tracefile(gconstpointer a, gconstpointer b)
 {
-  gint comparison;
-
-  LttvTracefileContext *trace_a = (LttvTracefileContext *)a;
-
-  LttvTracefileContext *trace_b = (LttvTracefileContext *)b;
+  gint comparison = 0;
+
+  const LttvTracefileContext *trace_a = (const LttvTracefileContext *)a;
+  const LttvTracefileContext *trace_b = (const LttvTracefileContext *)b;
+
+  if(likely(trace_a != trace_b)) {
+    comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp);
+    if(unlikely(comparison == 0)) {
+      if(trace_a->index < trace_b->index) comparison = -1;
+      else if(trace_a->index > trace_b->index) comparison = 1;
+      else if(trace_a->t_context->index < trace_b->t_context->index) 
+        comparison = -1;
+      else if(trace_a->t_context->index > trace_b->t_context->index)
+        comparison = 1;
+    }
+  } else {
+    comparison = 0;
+  }
 
-  if(trace_a == trace_b) return 0;
-  comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp);
-  if(comparison != 0) return comparison;
-  if(trace_a->index < trace_b->index) return -1;
-  else if(trace_a->index > trace_b->index) return 1;
-  if(trace_a->t_context->index < trace_b->t_context->index) return -1;
-  else if(trace_a->t_context->index > trace_b->t_context->index) return 1;
-  g_assert(FALSE);
+  return comparison;
 }
 
-struct _LttvTraceContextPosition {
-  LttEventPosition **tf_pos;          /* Position in each trace           */
-  guint nb_tracefile;                /* Number of tracefiles (check)     */
-};
-
 struct _LttvTracesetContextPosition {
-  LttvTraceContextPosition *t_pos;    /* Position in each trace           */
-  guint nb_trace;                    /* Number of traces (check)         */
+  GArray *ep;                        /* Array of LttEventPosition */
+  GArray *tfc;                       /* Array of corresponding
+                                        TracefileContext* */
+  LttTime timestamp;                 /* Current time at the saved position */
 };
 
 void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
@@ -101,7 +109,7 @@ lttv_context_new_tracefile_context(LttvTracesetContext *self)
  ***************************************************************************/
 static void lttv_traceset_context_compute_time_span(
                                           LttvTracesetContext *self,
-                                                                 TimeInterval time_span)
+                                                                 TimeInterval *time_span)
 {
   LttvTraceset * traceset = self->ts;
   int numTraces = lttv_traceset_number(traceset);
@@ -110,10 +118,10 @@ static void lttv_traceset_context_compute_time_span(
   LttvTraceContext *tc;
   LttTrace * trace;
 
-  time_span.startTime.tv_sec = 0;
-  time_span.startTime.tv_nsec = 0;
-  time_span.endTime.tv_sec = 0;
-  time_span.endTime.tv_nsec = 0;
+  time_span->start_time.tv_sec = 0;
+  time_span->start_time.tv_nsec = 0;
+  time_span->end_time.tv_sec = 0;
+  time_span->end_time.tv_nsec = 0;
   
   for(i=0; i<numTraces;i++){
     tc = self->traces[i];
@@ -122,21 +130,40 @@ static void lttv_traceset_context_compute_time_span(
     ltt_trace_time_span_get(trace, &s, &e);
 
     if(i==0){
-      time_span.startTime = s;
-      time_span.endTime   = e;
+      time_span->start_time = s;
+      time_span->end_time   = 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;      
+      if(s.tv_sec < time_span->start_time.tv_sec 
+          || (s.tv_sec == time_span->start_time.tv_sec 
+               && s.tv_nsec < time_span->start_time.tv_nsec))
+             time_span->start_time = s;
+      if(e.tv_sec > time_span->end_time.tv_sec
+          || (e.tv_sec == time_span->end_time.tv_sec 
+               && e.tv_nsec > time_span->end_time.tv_nsec))
+        time_span->end_time = e;      
     }
   }
 }
 
+static void init_tracefile_context(LttTracefile *tracefile,
+                                    LttvTraceContext *tc)
+{
+  LttvTracefileContext *tfc;
+  LttvTracesetContext *tsc = tc->ts_context;
+  
+  tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->new_tracefile_context(tsc);
+
+  tfc->index = tc->tracefiles->len;
+  tc->tracefiles = g_array_append_val(tc->tracefiles, tfc);
+
+  tfc->tf = tracefile;
+
+  tfc->t_context = tc;
+  tfc->event = lttv_hooks_new();
+  tfc->event_by_id = lttv_hooks_by_id_new();
+  tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+}
+
 
 static void
 init(LttvTracesetContext *self, LttvTraceset *ts)
@@ -145,9 +172,9 @@ init(LttvTracesetContext *self, LttvTraceset *ts)
 
   LttvTraceContext *tc;
 
-  LttvTracefileContext *tfc;
+  GData **tracefiles_groups;
 
-  LttTime null_time = {0, 0};
+  struct compute_tracefile_group_args args;
 
   nb_trace = lttv_traceset_number(ts);
   self->ts = ts;
@@ -164,6 +191,19 @@ init(LttvTracesetContext *self, LttvTraceset *ts)
     tc->t = lttv_trace(tc->vt);
     tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
     tc->t_a = lttv_trace_attribute(tc->vt);
+    tc->tracefiles = g_array_sized_new(FALSE, TRUE,
+                        sizeof(LttvTracefileContext*), 10);
+
+    tracefiles_groups = ltt_trace_get_tracefiles_groups(tc->t);
+
+    args.func = (ForEachTraceFileFunc)init_tracefile_context;
+    args.func_args = tc;
+
+    g_datalist_foreach(tracefiles_groups, 
+                          (GDataForeachFunc)compute_tracefile_group,
+                          &args);
+      
+#if 0
     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;
@@ -182,17 +222,20 @@ init(LttvTracesetContext *self, LttvTraceset *ts)
         tfc->control = FALSE;
         tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
       }
+
       tfc->t_context = tc;
+      tfc->e = ltt_event_new();
       tfc->event = lttv_hooks_new();
       tfc->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);
-  lttv_traceset_context_compute_time_span(self, self->time_span);
-  self->e = NULL;
+#endif //0
 
+  }
   self->pqueue = g_tree_new(compare_tracefile);
+  lttv_process_traceset_seek_time(self, ltt_time_zero);
+  lttv_traceset_context_compute_time_span(self, &self->time_span);
+
 }
 
 
@@ -218,17 +261,16 @@ void fini(LttvTracesetContext *self)
 
     g_object_unref(tc->a);
 
-    nb_tracefile = ltt_trace_control_tracefile_number(tc->t) +
-        ltt_trace_per_cpu_tracefile_number(tc->t);
+    nb_tracefile = tc->tracefiles->len;
 
     for(j = 0 ; j < nb_tracefile ; j++) {
-      tfc = tc->tracefiles[j];
+      tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, j);
       lttv_hooks_destroy(tfc->event);
       lttv_hooks_by_id_destroy(tfc->event_by_id);
       g_object_unref(tfc->a);
       g_object_unref(tfc);
     }
-    g_free(tc->tracefiles);
+    g_array_free(tc->tracefiles, TRUE);
     g_object_unref(tc);
   }
   g_free(self->traces);
@@ -304,11 +346,11 @@ void lttv_trace_context_add_hooks(LttvTraceContext *self,
   LttvTracefileContext *tfc;
 
   lttv_hooks_call(before_trace, self);
-  nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
-      ltt_trace_per_cpu_tracefile_number(self->t);
+
+  nb_tracefile = self->tracefiles->len;
 
   for(i = 0 ; i < nb_tracefile ; i++) {
-    tfc = self->tracefiles[i];
+    tfc = g_array_index(self->tracefiles, LttvTracefileContext*, i);
     lttv_tracefile_context_add_hooks(tfc,
                                      before_tracefile,
                                      event,
@@ -328,11 +370,10 @@ void lttv_trace_context_remove_hooks(LttvTraceContext *self,
 
   LttvTracefileContext *tfc;
 
-  nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
-      ltt_trace_per_cpu_tracefile_number(self->t);
+  nb_tracefile = self->tracefiles->len;
 
   for(i = 0 ; i < nb_tracefile ; i++) {
-    tfc = self->tracefiles[i];
+    tfc = g_array_index(self->tracefiles, LttvTracefileContext*, i);
     lttv_tracefile_context_remove_hooks(tfc,
                                         after_tracefile,
                                         event,
@@ -347,19 +388,19 @@ void lttv_tracefile_context_add_hooks(LttvTracefileContext *self,
           LttvHooks *event, 
           LttvHooksById *event_by_id)
 {
-  guint i;
+  guint i, index;
 
   LttvHooks *hook;
   
   lttv_hooks_call(before_tracefile, self);
   lttv_hooks_add_list(self->event, event);
-  if(event_by_id != NULL)
-    for(i = 0; i < lttv_hooks_by_id_max_id(event_by_id); i++) {
-      hook = lttv_hooks_by_id_get(self->event_by_id, i);
-      if(hook != NULL)
-        lttv_hooks_remove_list(hook, lttv_hooks_by_id_get(event_by_id, i));
+  if(event_by_id != NULL) {
+    for(i = 0; i < event_by_id->array->len; i++) {
+      index = g_array_index(event_by_id->array, guint, i);
+      hook = lttv_hooks_by_id_find(self->event_by_id, index);
+      lttv_hooks_add_list(hook, lttv_hooks_by_id_get(event_by_id, index));
     }
-
+  }
 }
 
 void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self,
@@ -367,17 +408,19 @@ void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self,
            LttvHooks *event, 
            LttvHooksById *event_by_id)
 {
-  guint i;
+  guint i, index;
 
   LttvHooks *hook;
   
-
   lttv_hooks_remove_list(self->event, event);
-  if(event_by_id != NULL)
-    for(i = 0; i < lttv_hooks_by_id_max_id(event_by_id); i++) {
-      hook = lttv_hooks_by_id_find(self->event_by_id, i);
-      lttv_hooks_add_list(hook, lttv_hooks_by_id_get(event_by_id, i));
+  if(event_by_id != NULL) {
+    for(i = 0; i < event_by_id->array->len; i++) {
+      index = g_array_index(event_by_id->array, guint, i);
+      hook = lttv_hooks_by_id_get(self->event_by_id, index);
+      if(hook != NULL)
+        lttv_hooks_remove_list(hook, lttv_hooks_by_id_get(event_by_id, index));
     }
+  }
 
   lttv_hooks_call(after_tracefile, self);
 }
@@ -463,7 +506,8 @@ lttv_traceset_context_get_type(void)
       NULL,   /* class_data */
       sizeof (LttvTracesetContext),
       0,      /* n_preallocs */
-      (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
+      (GInstanceInitFunc) traceset_context_instance_init, /* instance_init */
+      NULL    /* Value handling */
     };
 
     type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType", 
@@ -511,7 +555,8 @@ lttv_trace_context_get_type(void)
       NULL,   /* class_data */
       sizeof (LttvTraceContext),
       0,      /* n_preallocs */
-      (GInstanceInitFunc) trace_context_instance_init    /* instance_init */
+      (GInstanceInitFunc) trace_context_instance_init,    /* instance_init */
+      NULL    /* Value handling */
     };
 
     type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType", 
@@ -559,7 +604,8 @@ lttv_tracefile_context_get_type(void)
       NULL,   /* class_data */
       sizeof (LttvTracefileContext),
       0,      /* n_preallocs */
-      (GInstanceInitFunc) tracefile_context_instance_init    /* instance_init */
+      (GInstanceInitFunc) tracefile_context_instance_init,    /* instance_init */
+      NULL    /* Value handling */
     };
 
     type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType", 
@@ -570,11 +616,17 @@ lttv_tracefile_context_get_type(void)
 
 
 
-gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
+static gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
   *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
   return TRUE;
 }
 
+static gboolean test_tree(gpointer key, gpointer value, gpointer user_data) {
+
+  g_assert(((LttvTracefileContext *)user_data) != (LttvTracefileContext *)value);
+  return FALSE;
+}
+
 
 
 void lttv_process_traceset_begin(LttvTracesetContext *self,
@@ -599,19 +651,23 @@ void lttv_process_traceset_begin(LttvTracesetContext *self,
 /* Note : a _middle must be preceded from a _seek or another middle */
 guint lttv_process_traceset_middle(LttvTracesetContext *self,
                               LttTime end,
-                              unsigned nb_events,
+                              guint nb_events,
                               const LttvTracesetContextPosition *end_position)
 {
   GTree *pqueue = self->pqueue;
 
-  guint id;
+  guint fac_id, ev_id, id;
 
   LttvTracefileContext *tfc;
 
-  LttEvent *event;
-
+  LttEvent *e;
+  
   unsigned count = 0;
 
+  guint read_ret = FALSE;
+
+  gboolean last_ret = FALSE; /* return value of the last hook list called */
+
   /* 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 
@@ -620,9 +676,9 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
   while(TRUE) {
     tfc = NULL;
     g_tree_foreach(pqueue, get_first, &tfc);
-    if(tfc == NULL)
+    /* End of traceset : tfc is NULL */
+    if(unlikely(tfc == NULL))
     {
-      self->e = event;
       return count;
     }
 
@@ -634,34 +690,42 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
      * break the loop.
      */
 
-    if(count >= nb_events ||
-       lttv_traceset_context_ctx_pos_compare(self,
-                                             end_position) >= 0 ||
-       ltt_time_compare(tfc->timestamp, end) >= 0)
+    if(unlikely(last_ret == TRUE ||
+                ((count >= nb_events) && (nb_events != G_MAXULONG)) ||
+     (end_position!=NULL&&lttv_traceset_context_ctx_pos_compare(self,
+                                                          end_position) == 0)||
+       ltt_time_compare(end, tfc->timestamp) <= 0))
     {
-      self->e = event;
       return count;
     }
 
     /* 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. */
-
+    
     g_tree_remove(pqueue, tfc);
-    count++;
 
-    id = ltt_event_eventtype_id(tfc->e);
-    lttv_hooks_call_merge(tfc->event, tfc,
+    g_tree_foreach(pqueue, test_tree, tfc);
+    count++;
+    
+    e = ltt_tracefile_get_event(tfc->tf);
+    fac_id = ltt_event_facility_id(e);
+    ev_id = ltt_event_eventtype_id(e);
+    id = GET_HOOK_ID(fac_id, ev_id);
+    last_ret = lttv_hooks_call_merge(tfc->event, tfc,
                         lttv_hooks_by_id_get(tfc->event_by_id, id), 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, tfc);
+    read_ret = ltt_tracefile_read(tfc->tf);
+
+    if(likely(!read_ret)) {
+      g_debug("got someting");
+      tfc->timestamp = ltt_event_time(e);
+           g_tree_insert(pqueue, tfc, tfc);
+    } else {
+      if(read_ret == ERANGE)
+        g_debug("End of trace");
+      else
+        g_error("Error happened in lttv_process_traceset_middle");
     }
   }
 }
@@ -684,25 +748,30 @@ void lttv_process_traceset_end(LttvTracesetContext *self,
                                      event_by_id);
 }
 
+/* Subtile modification : 
+ * if tracefile has no event at or after the time requested, it is not put in
+ * the queue, as the next read would fail. */
 void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
 {
   guint i, nb_tracefile;
 
+  gint ret;
+  
   LttvTracefileContext *tfc;
 
-  LttEvent *event;
+  GTree *pqueue = self->ts_context->pqueue;
 
-  nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
-      ltt_trace_per_cpu_tracefile_number(self->t);
+  nb_tracefile = self->tracefiles->len;
 
   for(i = 0 ; i < nb_tracefile ; i++) {
-    tfc = self->tracefiles[i];
-    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);
-      g_tree_insert(self->ts_context->pqueue, tfc, tfc);
+    tfc = g_array_index(self->tracefiles, LttvTracefileContext*, i);
+    ret = ltt_tracefile_seek_time(tfc->tf, start);
+    if(ret == EPERM) g_error("error in lttv_process_trace_seek_time seek");
+    g_tree_remove(pqueue, tfc);
+
+    if(ret == 0) { /* not ERANGE especially */
+      tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf));
+      g_tree_insert(pqueue, tfc, tfc);
     }
   }
 }
@@ -714,17 +783,6 @@ void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
 
   LttvTraceContext *tc;
 
-  LttvTracefileContext *tfc;
-
-  /* Empty the pqueue */
-
-  while(TRUE){
-    tfc = NULL;
-    g_tree_foreach(self->pqueue, get_first, &tfc);
-    if(tfc == NULL) break;
-    g_tree_remove(self->pqueue, &(tfc->timestamp));
-  }
-
   nb_trace = lttv_traceset_number(self->ts);
   for(i = 0 ; i < nb_trace ; i++) {
     tc = self->traces[i];
@@ -733,73 +791,31 @@ void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
 }
 
 
-gboolean lttv_process_trace_seek_position(LttvTraceContext *self, 
-                                        const LttvTraceContextPosition *pos)
-{
-  guint i, nb_tracefile;
-
-  LttvTracefileContext *tfc;
-
-  LttEvent *event;
-
-  nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
-      ltt_trace_per_cpu_tracefile_number(self->t);
-
-  if(nb_tracefile != pos->nb_tracefile)
-    return FALSE; /* Error */
-
-  for(i = 0 ; i < nb_tracefile ; i++) {
-    tfc = self->tracefiles[i];
-    ltt_tracefile_seek_position(tfc->tf, pos->tf_pos[i]);
-    event = ltt_tracefile_read(tfc->tf);
-    tfc->e = event;
-    if(event != NULL) {
-      tfc->timestamp = ltt_event_time(event);
-      g_tree_insert(self->ts_context->pqueue, tfc, tfc);
-    }
-  }
-
-  return TRUE;
-}
-
-
-
 gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, 
                                         const LttvTracesetContextPosition *pos)
 {
-  guint i, nb_trace;
-  gboolean sum_ret = TRUE;
-
+  guint i;
   LttvTraceContext *tc;
-
   LttvTracefileContext *tfc;
 
-  nb_trace = lttv_traceset_number(self->ts);
+  g_tree_destroy(self->pqueue);
+  self->pqueue = g_tree_new(compare_tracefile);
   
-  if(nb_trace != pos->nb_trace)
-    return FALSE; /* Error */
-
-  /* Empty the pqueue */
-
-  while(TRUE){
-    tfc = NULL;
-    g_tree_foreach(self->pqueue, get_first, &tfc);
-    if(tfc == NULL) break;
-    g_tree_remove(self->pqueue, &(tfc->timestamp));
+  for(i=0;i<pos->ep->len; i++) {
+    LttEventPosition *ep = g_array_index(pos->ep, LttEventPosition*, i);
+    LttvTracefileContext *tfc = 
+      g_array_index(pos->tfc, LttvTracefileContext*, i);
+    g_assert(ltt_tracefile_seek_position(tfc->tf, ep) == 0);
+    tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf));
+    g_tree_insert(self->pqueue, tfc, tfc);
   }
-
-  for(i = 0 ; i < nb_trace ; i++) {
-    tc = self->traces[i];
-    sum_ret = sum_ret && lttv_process_trace_seek_position(tc, &pos->t_pos[i]);
-  }
-
-  return sum_ret;
+  return TRUE;
 }
 
 
 
 static LttField *
-find_field(LttEventType *et, const char *field)
+find_field(LttEventType *et, const GQuark field)
 {
   LttType *t;
 
@@ -807,138 +823,231 @@ find_field(LttEventType *et, const char *field)
 
   guint i, nb;
 
-  char *name;
-
-  if(field == NULL) return NULL;
+  GQuark name;
 
+  /* Field is unset */
+  if(field == 0) 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;
+    if(name == field) break;
   }
   g_assert(i < nb);
   return ltt_field_member(f, i);
 }
 
+LttvTraceHookByFacility *lttv_trace_hook_get_fac(LttvTraceHook *th, 
+                                                 guint facility_id)
+{
+  return &g_array_index(th->fac_index, LttvTraceHookByFacility, facility_id);
+}
+
+/* Get the first facility corresponding to the name. As the types must be
+ * compatible, it is relevant to use the field name and sizes of the first
+ * facility to create data structures and assume the data will be compatible
+ * thorough the trace */
+LttvTraceHookByFacility *lttv_trace_hook_get_first(LttvTraceHook *th)
+{
+  g_assert(th->fac_list->len > 0);
+  return g_array_index(th->fac_list, LttvTraceHookByFacility*, 0);
+}
+
 
-void 
-lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, 
-    char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
+/* Returns 0 on success, -1 if fails. */
+gint
+lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, 
+    GQuark field1, GQuark field2, GQuark field3, LttvHook h, LttvTraceHook *th)
 {
   LttFacility *f;
 
-  LttEventType *et;
+  LttEventType *et, *first_et;
+
+  GArray *facilities;
+
+  guint i, fac_id, ev_id;
+
+  LttvTraceHookByFacility *thf, *first_thf;
+
+  facilities = ltt_trace_facility_get_by_name(t, facility);
+  
+  if(unlikely(facilities == NULL)) goto facility_error;
+
+  th->fac_index = g_array_sized_new(FALSE, TRUE,
+             sizeof(LttvTraceHookByFacility),
+             NUM_FACILITIES);
+  th->fac_index = g_array_set_size(th->fac_index, NUM_FACILITIES);
+
+  th->fac_list = g_array_sized_new(FALSE, TRUE,
+             sizeof(LttvTraceHookByFacility*),
+             facilities->len);
+  th->fac_list = g_array_set_size(th->fac_list, facilities->len);
+  
+  fac_id = g_array_index(facilities, guint, 0);
+  f = ltt_trace_get_facility_by_num(t, fac_id);
 
-  guint nb, pos, i;
+  et = ltt_facility_eventtype_get_by_name(f, event);
+  if(unlikely(et == NULL)) goto event_error;
+  
+  thf = &g_array_index(th->fac_index, LttvTraceHookByFacility, fac_id);
+  g_array_index(th->fac_list, LttvTraceHookByFacility*, 0)
+        = thf;
 
-  char *name;
+  ev_id = ltt_eventtype_id(et);
+  
+  thf->h = h;
+  thf->id = GET_HOOK_ID(fac_id, ev_id);
+  thf->f1 = find_field(et, field1);
+  thf->f2 = find_field(et, field2);
+  thf->f3 = find_field(et, field3);
+  
+  first_thf = thf;
+
+  /* Check for type compatibility too */
+  for(i=1;i<facilities->len;i++) {
+    fac_id = g_array_index(facilities, guint, i);
+    f = ltt_trace_get_facility_by_num(t, fac_id);
+
+    et = ltt_facility_eventtype_get_by_name(f, ltt_eventtype_name(et));
+    if(unlikely(et == NULL)) goto event_error;
+    
+    thf = &g_array_index(th->fac_index, LttvTraceHookByFacility, fac_id);
+    g_array_index(th->fac_list, LttvTraceHookByFacility*, i)
+          = thf;
+    ev_id = ltt_eventtype_id(et);
+    thf->h = h;
+    thf->id = GET_HOOK_ID(fac_id, ev_id);
+    thf->f1 = find_field(et, field1);
+    if(check_fields_compatibility(first_et, et,
+        first_thf->f1, thf->f1))
+      goto type_error;
+        
+    thf->f2 = find_field(et, field2);
+    if(check_fields_compatibility(first_et, et,
+        first_thf->f2, thf->f2))
+      goto type_error;
+
+    thf->f3 = find_field(et, field3);
+    if(check_fields_compatibility(first_et, et,
+        first_thf->f3, thf->f3))
+      goto type_error;
+  }
 
-  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);
+  return 0;
 
-  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);
+type_error:
+  goto free;
+event_error:
+  g_error("Event type %s does not exist", 
+      g_quark_to_string(ltt_eventtype_name(et)));
+  goto free;
+facility_error:
+  g_error("No %s facility", g_quark_to_string(facility));
+  goto free;
+free:
+  g_array_free(th->fac_index, TRUE);
+  g_array_free(th->fac_list, TRUE);
+  th->fac_index = NULL;
+  th->fac_list = NULL;
+  return -1;
 }
 
+void lttv_trace_hook_destroy(LttvTraceHook *th)
+{
+  g_array_free(th->fac_index, TRUE);
+  g_array_free(th->fac_list, TRUE);
+}
 
-void lttv_traceset_context_position_save(const LttvTracesetContext *self,
-                                    LttvTracesetContextPosition *pos)
+
+LttvTracesetContextPosition *lttv_traceset_context_position_new()
 {
-  guint nb_trace, nb_tracefile;
-  guint iter_trace, iter_tracefile;
-  
-  LttvTraceContext *tc;
+  LttvTracesetContextPosition *pos = g_new(LttvTracesetContextPosition,1);
+  pos->ep = g_array_sized_new(FALSE, TRUE, sizeof(LttEventPosition*),
+                              10);
+  pos->tfc = g_array_sized_new(FALSE, TRUE, sizeof(LttvTracefileContext*),
+                              10);
+  pos->timestamp = ltt_time_infinite;
+  return pos;
+}
+
+gboolean traverse_get_tfc(gpointer key, gpointer value, gpointer data)
+{
+  LttvTracefileContext *tfc = (LttvTracefileContext *)value;
+  LttvTracesetContextPosition *pos = (LttvTracesetContextPosition *)data;
+
+  LttEvent *event = ltt_tracefile_get_event(tfc->tf);
+  LttEventPosition *ep = ltt_event_position_new();
   
-  LttvTracefileContext *tfc;
+  ltt_event_position(event, ep);
 
-  LttEvent *event;
+  g_array_append_val(pos->ep, ep);
+  g_array_append_val(pos->tfc, tfc);
 
-  pos->nb_trace = nb_trace = lttv_traceset_number(self->ts);
-  pos->t_pos = g_new(LttvTraceContextPosition, nb_trace);
+  if(ltt_time_compare(tfc->timestamp, pos->timestamp) < 0)
+    pos->timestamp = tfc->timestamp;
   
-  for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
-    tc = self->traces[iter_trace];
-    pos->t_pos[iter_trace].nb_tracefile = nb_tracefile =
-                    ltt_trace_control_tracefile_number(tc->t) +
-                    ltt_trace_per_cpu_tracefile_number(tc->t);
-
-    pos->t_pos[iter_trace].tf_pos = g_new(LttEventPosition*, nb_tracefile);
-    for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
-      pos->t_pos[iter_trace].tf_pos[iter_tracefile] 
-                                                = ltt_event_position_new();
-      tfc = tc->tracefiles[iter_tracefile];
-      event = tfc->e;
-      ltt_event_position(event, 
-                         pos->t_pos[iter_trace].tf_pos[iter_tracefile]);
-    }
-  }
+  return 0;
+}
+
+/* Subtile modification :
+ * only save the tracefiles that are loaded in the pqueue */
+void lttv_traceset_context_position_save(const LttvTracesetContext *self,
+                                    LttvTracesetContextPosition *pos)
+{
+  g_tree_foreach(self->pqueue, traverse_get_tfc, pos);
 }
 
 void lttv_traceset_context_position_destroy(LttvTracesetContextPosition *pos)
 {
-  guint nb_trace, nb_tracefile;
-  guint iter_trace, iter_tracefile;
+  int i;
+  for(i=0;i<pos->ep->len;i++)
+    g_free(g_array_index(pos->ep, LttEventPosition*, i));
+  g_array_free(pos->ep, TRUE);
+  g_array_free(pos->tfc, TRUE);
+  g_free(pos);
+}
+
+void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest,
+                                   const LttvTracesetContextPosition *src)
+{
+  int i;
   
-  nb_trace = pos->nb_trace;
+  g_array_set_size(dest->ep, src->ep->len);
+  g_array_set_size(dest->tfc, src->tfc->len);
   
-  for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
-    for(iter_tracefile = 0; iter_tracefile < 
-                        pos->t_pos[iter_trace].nb_tracefile;
-                        iter_tracefile++) {
-      
-      g_free(pos->t_pos[iter_trace].tf_pos[iter_tracefile]);
-    }
-    g_free(pos->t_pos[iter_trace].tf_pos);
+  for(i=0;i<src->ep->len;i++) {
+    g_array_index(dest->ep, LttEventPosition*, i) = ltt_event_position_new();
+    ltt_event_position_copy(
+        g_array_index(dest->ep, LttEventPosition*, i),
+        g_array_index(src->ep, LttEventPosition*, i));
   }
-  g_free(pos->t_pos);
-
+  for(i=0;i<src->tfc->len;i++) {
+    g_array_index(dest->tfc, LttvTracefileContext*, i) =
+                    g_array_index(src->tfc, LttvTracefileContext*, i);
+  }
+  dest->timestamp = src->timestamp;
 }
 
 gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self,
                                         const LttvTracesetContextPosition *pos)
 {
-  guint nb_trace, nb_tracefile;
-  guint iter_trace, iter_tracefile;
-  gint ret;
+  int i;
+  int ret;
 
-  LttvTraceContext *tc;
-  
-  LttvTracefileContext *tfc;
+  for(i=0;i<pos->ep->len;i++) {
+    LttEventPosition *ep = g_array_index(pos->ep, LttEventPosition*, i);
+    LttvTracefileContext *tfc = 
+      g_array_index(pos->tfc, LttvTracefileContext*, i);
 
-  LttEvent *event;
+    LttEvent *event = ltt_tracefile_get_event(tfc->tf);
 
-  nb_trace = lttv_traceset_number(self->ts);
+    ret = ltt_event_position_compare((LttEventPosition*)event, 
+                                      ep);
+    if(ret != 0) return ret;
 
-  if(pos->nb_trace != nb_trace)
-    g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match.");
-  
-  for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
-    tc = self->traces[iter_trace];
-    nb_tracefile =  ltt_trace_control_tracefile_number(tc->t) +
-                    ltt_trace_per_cpu_tracefile_number(tc->t);
-
-    if(pos->t_pos[iter_trace].nb_tracefile != nb_tracefile)
-      g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
-
-    for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
-      tfc = tc->tracefiles[iter_tracefile];
-      event = tfc->e;
-      if(
-          ret =
-            ltt_event_event_position_compare(event, 
-                            pos->t_pos[iter_trace].tf_pos[iter_tracefile])
-          != 0)
-        return ret;
-    }
   }
   return 0;
 }
@@ -948,31 +1057,41 @@ gint lttv_traceset_context_pos_pos_compare(
                                   const LttvTracesetContextPosition *pos1,
                                   const LttvTracesetContextPosition *pos2)
 {
-  guint nb_trace, nb_tracefile;
-  guint iter_trace, iter_tracefile;
+  int i, j;
+  int ret;
   
-  gint ret;
-
-  nb_trace = pos1->nb_trace;
-  if(nb_trace != pos2->nb_trace)
-    g_error("lttv_traceset_context_pos_pos_compare : nb_trace does not match.");
-
-  for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
-
-    nb_tracefile = pos1->t_pos[iter_trace].nb_tracefile;
-    if(nb_tracefile != pos2->t_pos[iter_trace].nb_tracefile)
-      g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
-
-    for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
-      if(ret = 
-          ltt_event_position_compare(
-                pos1->t_pos[iter_trace].tf_pos[iter_tracefile],
-                pos2->t_pos[iter_trace].tf_pos[iter_tracefile])
-          != 0)
-        return ret;
+  for(i=0;i<pos1->ep->len;i++) {
+    LttEventPosition *ep1 = g_array_index(pos1->ep, LttEventPosition*, i);
+    LttTracefile *tf1 = ltt_event_position_tracefile(ep1);
+    
+    for(j=0;j<pos2->ep->len;j++) {
+      LttEventPosition *ep2 = g_array_index(pos2->ep, LttEventPosition*, j);
+      LttTracefile *tf2 = ltt_event_position_tracefile(ep2);
+
+      if(tf1 == tf2) {
+        ret = ltt_event_position_compare(ep1, ep2);
+        if(ret != 0) return ret;
+      }
     }
   }
   return 0;
+
 }
 
 
+LttTime lttv_traceset_context_position_get_time(
+                                  const LttvTracesetContextPosition *pos)
+{
+  return pos->timestamp;
+}
+
+
+LttvTracefileContext *lttv_traceset_context_get_current_tfc(LttvTracesetContext *self)
+{
+  GTree *pqueue = self->pqueue;
+  LttvTracefileContext *tfc = NULL;
+
+  g_tree_foreach(pqueue, get_first, &tfc);
+
+  return tfc;
+}
This page took 0.048307 seconds and 4 git commands to generate.