fix trace_find_hook
[lttv.git] / ltt / branches / poly / lttv / lttv / tracecontext.c
index c800b924d1114c91be7fc564d7d29165a9d7a5f6..39ee2950b66c443350c6dafb23c7e5e309c543d6 100644 (file)
@@ -24,9 +24,7 @@
 #include <lttv/lttv.h>
 #include <lttv/tracecontext.h>
 #include <ltt/event.h>
-#include <ltt/facility.h>
 #include <ltt/trace.h>
-#include <ltt/type.h>
 #include <lttv/filter.h>
 #include <errno.h>
 
@@ -171,7 +169,7 @@ static void init_tracefile_context(LttTracefile *tracefile,
   tfc->event = lttv_hooks_new();
   tfc->event_by_id = lttv_hooks_by_id_new();
   tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
-  tfc->target_pid = 0;
+  tfc->target_pid = -1;
 }
 
 
@@ -693,8 +691,6 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
 {
   GTree *pqueue = self->pqueue;
 
-  guint fac_id, ev_id, id;
-
   LttvTracefileContext *tfc;
 
   LttEvent *e;
@@ -765,15 +761,12 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
      * first pass (not if last read returned end of tracefile) */
     count++;
     
-    fac_id = ltt_event_facility_id(e);
-    ev_id = ltt_event_eventtype_id(e);
-    id = GET_HOOK_ID(fac_id, ev_id);
-    tfc->target_pid = 0; /* unset target PID */
+    tfc->target_pid = -1; /* unset target PID */
     /* Hooks : 
      * return values : 0 : continue read, 1 : go to next position and stop read,
      * 2 : stay at the current position and stop read */
     last_ret = lttv_hooks_call_merge(tfc->event, tfc,
-                        lttv_hooks_by_id_get(tfc->event_by_id, id), tfc);
+                        lttv_hooks_by_id_get(tfc->event_by_id, e->event_id), tfc);
 
 #if 0
     /* This is buggy : it won't work well with state computation */
@@ -951,144 +944,98 @@ gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self,
 }
 
 
-
+#if 0 // pmf: temporary disable
 static LttField *
 find_field(LttEventType *et, const GQuark field)
 {
-  GQuark name;
+  LttField *f;
 
   if(field == 0) return NULL;
   
-  return ltt_eventtype_field_by_name(et, field);
-}
+  f = ltt_eventtype_field_by_name(et, field);
+  if (!f) {
+    g_warning("Cannot find field %s in event %s.%s", g_quark_to_string(field),
+       g_quark_to_string(ltt_facility_name(ltt_eventtype_facility(et))),
+       g_quark_to_string(ltt_eventtype_name(et)));
+  }
 
-LttvTraceHookByFacility *lttv_trace_hook_get_fac(LttvTraceHook *th, 
-                                                 guint facility_id)
-{
-  return &g_array_index(th->fac_index, LttvTraceHookByFacility, facility_id);
+  return f;
 }
+#endif
 
-/* 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)
+struct marker_info *lttv_trace_hook_get_marker(LttTrace *t, LttvTraceHook *th)
 {
-  g_assert(th->fac_list->len > 0);
-  return g_array_index(th->fac_list, LttvTraceHookByFacility*, 0);
+  return marker_get_info_from_id(t, th->id);
 }
 
 
-/* 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, gpointer hook_data,
-    LttvTraceHook *th)
+int lttv_trace_find_hook(LttTrace *t, GQuark marker_name,
+    GQuark fields[], LttvHook h, gpointer hook_data, GArray **trace_hooks)
 {
-  LttFacility *f;
-
-  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);
-
-  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;
-
-  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);
-  thf->hook_data = hook_data;
-  
-  first_thf = thf;
-  first_et = et;
-
-  /* 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, 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*, 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;
-    thf->hook_data = hook_data;
+  struct marker_info *info;
+  struct marker_field *field;
+  guint16 marker_id;
+  int init_array_size;
+
+  info = marker_get_info_from_name(t, marker_name);
+  if(unlikely(info == NULL)) {
+    return NULL;
   }
 
-  return 0;
-
-type_error:
-  goto free;
-event_error:
-  g_error("Event type does not exist for event %s", 
-      g_quark_to_string(event));
-  goto free;
-facility_error:
-  //Ignore this type of error : some facilities are not required.
-       //g_error("No %s facility", g_quark_to_string(facility));
-  return -1;
-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;
+  init_array_size = (*trace_hooks)->len;
+
+  /* for each marker with the requested name */
+  do {
+    LttvTraceHook tmpth;
+    int found;
+    GQuark f;
+
+    marker_id = marker_get_id_from_info(t, info);
+
+    tmpth.h = h;
+    tmpth.id = marker_id;
+    tmpth.hook_data = hook_data;
+    tmpth.fields = g_ptr_array_new();
+
+    /* for each field requested */
+    for(f = fields; *f != 0; f++) {
+      found = 0;
+      for_each_marker_field(marker_field, info) {
+        if(marker_fieldfield->name == *f) {
+          found = 1;
+          g_ptr_array_add(tmpth.fields, marker_field);
+          break;
+        }
+      }
+      if(!found) {
+        /* Did not find the one of the fields in this instance of the
+           marker. Print a warning and skip this marker completely.
+          Still iterate on other markers with same name. */
+        g_ptr_array_free(tmpth.fields, TRUE);
+        g_warning("Field %s cannot be found in marker %s",
+                g_quark_to_string(*f), g_quark_to_string(marker_name));
+        goto skip_marker;
+      }
+    }
+    /* all fields were found: add the tracehook to the array */
+    *trace_hooks = g_array_append_val(*trace_hooks, tmpth);
+skip_marker:
+    info = info->next;
+  } while(info != NULL);
+
+  /* Error if no new trace hook has been added */
+  return (init_array_size == (*trace_hooks)->len);
 }
 
-void lttv_trace_hook_destroy(LttvTraceHook *th)
+void lttv_trace_hook_destroy(GArray **th)
 {
-  g_array_free(th->fac_index, TRUE);
-  g_array_free(th->fac_list, TRUE);
+  int i;
+  for(i=0; i<th->len; i++) {
+    g_ptr_array_free(g_array_index(th, LttvTraceHook, i).fields, TRUE);
+  }
+  *th = g_array_remove_range(*th, 0, th->len);
 }
 
-
-
-
 LttvTracesetContextPosition *lttv_traceset_context_position_new(
                                         const LttvTracesetContext *self)
 {
@@ -1337,7 +1284,13 @@ struct seek_back_data {
   guint events_found;
   guint n;             /* number of events requested */
   GPtrArray *array; /* array of LttvTracesetContextPositions pointers */
-  LttvFilter *filter;
+  LttvFilter *filter1;
+  LttvFilter *filter2;
+  LttvFilter *filter3;
+  gpointer data;
+  check_handler *check;
+  gboolean *stop_flag;
+  guint raw_event_count;
 };
 
 static gint seek_back_event_hook(void *hook_data, void* call_data)
@@ -1347,15 +1300,35 @@ static gint seek_back_event_hook(void *hook_data, void* call_data)
   LttvTracesetContext *tsc = tfc->t_context->ts_context;
   LttvTracesetContextPosition *pos;
 
-  if(sd->filter != NULL && sd->filter->head != NULL) {
-    if(!lttv_filter_tree_parse(sd->filter->head,
+  if(sd->check && sd->check(sd->raw_event_count, sd->stop_flag, sd->data))
+    return TRUE;
+  sd->raw_event_count++;
+
+  if(sd->filter1 != NULL && sd->filter1->head != NULL && 
+    !lttv_filter_tree_parse(sd->filter1->head,
           ltt_tracefile_get_event(tfc->tf),
           tfc->tf,
           tfc->t_context->t,
-          tfc))
-      return FALSE;
+          tfc,NULL,NULL)) {
+         return FALSE;
   }
-  
+  if(sd->filter2 != NULL && sd->filter2->head != NULL && 
+    !lttv_filter_tree_parse(sd->filter2->head,
+          ltt_tracefile_get_event(tfc->tf),
+          tfc->tf,
+          tfc->t_context->t,
+          tfc,NULL,NULL)) {
+         return FALSE;
+  }
+  if(sd->filter3 != NULL && sd->filter3->head != NULL && 
+    !lttv_filter_tree_parse(sd->filter3->head,
+          ltt_tracefile_get_event(tfc->tf),
+          tfc->tf,
+          tfc->t_context->t,
+          tfc,NULL,NULL)) {
+         return FALSE;
+  }
+
   pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd->array,
                                                          sd->first_event);
 
@@ -1398,7 +1371,12 @@ static gint seek_back_event_hook(void *hook_data, void* call_data)
 guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self,
                                             guint n, LttTime first_offset,
                                             seek_time_fct time_seeker,
-                                            LttvFilter *filter)
+                                            check_handler *check,
+                                            gboolean *stop_flag,
+                                           LttvFilter *filter1,
+                                           LttvFilter *filter2,
+                                           LttvFilter *filter3,
+                                           gpointer data)
 {
   if(lttv_traceset_number(self->ts) == 0) return 0;
   g_assert(ltt_time_compare(first_offset, ltt_time_zero) != 0);
@@ -1419,8 +1397,14 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self,
   sd.first_event = 0;
   sd.events_found = 0;
   sd.array = g_ptr_array_sized_new(n);
-  sd.filter = filter;
+  sd.filter1 = filter1;
+  sd.filter2 = filter2;
+  sd.filter3 = filter3;
+  sd.data = data;
   sd.n = n;
+  sd.check = check;
+  sd.stop_flag = stop_flag;
+  sd.raw_event_count = 0;
   g_ptr_array_set_size(sd.array, n);
   for(i=0;i<n;i++) {
     g_ptr_array_index (sd.array, i) = lttv_traceset_context_position_new(self);
@@ -1526,7 +1510,13 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self,
 struct seek_forward_data {
   guint event_count;  /* event counter */
   guint n;            /* requested number of events to jump over */
-  LttvFilter *filter;
+  LttvFilter *filter1;
+  LttvFilter *filter2;
+  LttvFilter *filter3;
+  gpointer data;
+  check_handler *check;
+  gboolean *stop_flag;
+  guint raw_event_count;  /* event counter */
 };
 
 static gint seek_forward_event_hook(void *hook_data, void* call_data)
@@ -1534,16 +1524,38 @@ static gint seek_forward_event_hook(void *hook_data, void* call_data)
   struct seek_forward_data *sd = (struct seek_forward_data*)hook_data;
   LttvTracefileContext *tfc = (LttvTracefileContext*)call_data;
 
-  if(sd->filter == NULL || lttv_filter_tree_parse(sd->filter->head,
+  if(sd->check && sd->check(sd->raw_event_count, sd->stop_flag, sd->data))
+    return TRUE;
+  sd->raw_event_count++;
+
+  if(sd->filter1 != NULL && sd->filter1->head != NULL && 
+    !lttv_filter_tree_parse(sd->filter1->head,
           ltt_tracefile_get_event(tfc->tf),
           tfc->tf,
           tfc->t_context->t,
-          tfc)) {
-    sd->event_count++;
-    if(sd->event_count >= sd->n)
-      return TRUE;
+          tfc,NULL,NULL)) {
+         return FALSE;
   }
-  return FALSE;
+  if(sd->filter2 != NULL && sd->filter2->head != NULL && 
+    !lttv_filter_tree_parse(sd->filter2->head,
+          ltt_tracefile_get_event(tfc->tf),
+          tfc->tf,
+          tfc->t_context->t,
+          tfc,NULL,NULL)) {
+         return FALSE;
+  }
+  if(sd->filter3 != NULL && sd->filter3->head != NULL && 
+    !lttv_filter_tree_parse(sd->filter3->head,
+          ltt_tracefile_get_event(tfc->tf),
+          tfc->tf,
+          tfc->t_context->t,
+          tfc,NULL,NULL)) {
+         return FALSE;
+  }
+
+  sd->event_count++;
+  if(sd->event_count >= sd->n)
+      return TRUE;
 }
 
 /* Seek back n events forward from the current position (1 to n)
@@ -1557,12 +1569,24 @@ static gint seek_forward_event_hook(void *hook_data, void* call_data)
  * returns : the number of events jumped over (may be less than requested if end
  * of traceset reached) */
 guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self,
-                                          guint n, LttvFilter *filter)
+                                          guint n,
+                                          check_handler *check,
+                                          gboolean *stop_flag,
+                                         LttvFilter *filter1,
+                                         LttvFilter *filter2,
+                                         LttvFilter *filter3,
+                                         gpointer data)
 {
   struct seek_forward_data sd;
   sd.event_count = 0;
   sd.n = n;
-  sd.filter = filter;
+  sd.filter1 = filter1;
+  sd.filter2 = filter2;
+  sd.filter3 = filter3;
+  sd.data = data;
+  sd.check = check;
+  sd.stop_flag = stop_flag;
+  sd.raw_event_count = 0;
   
   if(sd.event_count >= sd.n) return sd.event_count;
   
This page took 0.027627 seconds and 4 git commands to generate.