X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ftracecontext.c;h=6f1e7b58a334665c1f1254cb9204d67c3bbb9c23;hb=f4b88a7dd49bfb6b88ea579410d7e4b59faaf73c;hp=d6ee6c4c85bd54c75e428ef0b09ebd6a654a8545;hpb=3865ea0940b718a7832b813a790f287140233efc;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index d6ee6c4c..6f1e7b58 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -26,11 +26,12 @@ #include #include #include +#include -static gint compare_tracefile(gconstpointer a, gconstpointer b) +gint compare_tracefile(gconstpointer a, gconstpointer b) { gint comparison = 0; @@ -51,15 +52,14 @@ static gint compare_tracefile(gconstpointer a, gconstpointer b) return comparison; } -struct _LttvTraceContextPosition { - LttEventPosition **tf_pos; /* Position in each tracefile */ - guint nb_tracefile; /* Number of tracefiles (check) */ -}; - struct _LttvTracesetContextPosition { - LttvTraceContextPosition *t_pos; /* Position in each trace */ - guint nb_trace; /* Number of traces (check) */ - LttTime timestamp; /* Current time at the saved position */ + GArray *ep; /* Array of LttEventPosition */ + GArray *tfc; /* Array of corresponding + TracefileContext* */ + LttTime timestamp; /* Current time at the saved position */ + /* If ltt_time_infinite : no position is + * set, else, a position is set (may be end + * of trace, with ep->len == 0) */ }; void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts) @@ -168,7 +168,7 @@ static void init_tracefile_context(LttTracefile *tracefile, static void init(LttvTracesetContext *self, LttvTraceset *ts) { - guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile; + guint i, nb_trace; LttvTraceContext *tc; @@ -181,6 +181,7 @@ init(LttvTracesetContext *self, LttvTraceset *ts) self->traces = g_new(LttvTraceContext *, nb_trace); self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); self->ts_a = lttv_traceset_attribute(ts); + self->sync_position = lttv_traceset_context_position_new(); for(i = 0 ; i < nb_trace ; i++) { tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self); self->traces[i] = tc; @@ -195,13 +196,14 @@ init(LttvTracesetContext *self, LttvTraceset *ts) sizeof(LttvTracefileContext*), 10); tracefiles_groups = ltt_trace_get_tracefiles_groups(tc->t); + if(tracefiles_groups != NULL) { + args.func = (ForEachTraceFileFunc)init_tracefile_context; + args.func_args = tc; - args.func = (ForEachTraceFileFunc)init_tracefile_context; - args.func_args = tc; - - g_datalist_foreach(tracefiles_groups, - (GDataForeachFunc)compute_tracefile_group, - &args); + g_datalist_foreach(tracefiles_groups, + (GDataForeachFunc)compute_tracefile_group, + &args); + } #if 0 nb_control = ltt_trace_control_tracefile_number(tc->t); @@ -245,14 +247,13 @@ void fini(LttvTracesetContext *self) LttvTraceContext *tc; - LttvTracefileContext *tfc; + LttvTracefileContext **tfc; LttvTraceset *ts = self->ts; - //FIXME : segfault - g_tree_destroy(self->pqueue); g_object_unref(self->a); + lttv_traceset_context_position_destroy(self->sync_position); nb_trace = lttv_traceset_number(ts); @@ -264,11 +265,11 @@ void fini(LttvTracesetContext *self) nb_tracefile = tc->tracefiles->len; for(j = 0 ; j < nb_tracefile ; 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); + 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_array_free(tc->tracefiles, TRUE); g_object_unref(tc); @@ -343,15 +344,15 @@ void lttv_trace_context_add_hooks(LttvTraceContext *self, { guint i, nb_tracefile; - LttvTracefileContext *tfc; + LttvTracefileContext **tfc; lttv_hooks_call(before_trace, self); nb_tracefile = self->tracefiles->len; for(i = 0 ; i < nb_tracefile ; i++) { - tfc = &g_array_index(self->tracefiles, LttvTracefileContext, i); - lttv_tracefile_context_add_hooks(tfc, + tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i); + lttv_tracefile_context_add_hooks(*tfc, before_tracefile, event, event_by_id); @@ -368,13 +369,13 @@ void lttv_trace_context_remove_hooks(LttvTraceContext *self, { guint i, nb_tracefile; - LttvTracefileContext *tfc; + LttvTracefileContext **tfc; nb_tracefile = self->tracefiles->len; for(i = 0 ; i < nb_tracefile ; i++) { - tfc = &g_array_index(self->tracefiles, LttvTracefileContext, i); - lttv_tracefile_context_remove_hooks(tfc, + tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i); + lttv_tracefile_context_remove_hooks(*tfc, after_tracefile, event, event_by_id); @@ -388,18 +389,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_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_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, @@ -407,18 +409,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_get(self->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, i)); + lttv_hooks_remove_list(hook, lttv_hooks_by_id_get(event_by_id, index)); } + } lttv_hooks_call(after_tracefile, self); } @@ -615,46 +618,39 @@ lttv_tracefile_context_get_type(void) static gboolean get_first(gpointer key, gpointer value, gpointer user_data) { + g_assert(key == value); *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value; return TRUE; } +#ifdef DEBUG +// Test to see if pqueue is traversed in the right order. +static LttTime test_time; -/* Put all the tracefiles at the tracefile context position */ -void lttv_process_traceset_synchronize_tracefiles(LttvTracesetContext *self) -{ - guint iter_trace, nb_trace; +static gboolean test_tree(gpointer key, gpointer value, gpointer user_data) { - LttvTraceContext *tc; + LttvTracefileContext *tfc = (LttvTracefileContext *)key; - nb_trace = lttv_traceset_number(self->ts); + g_debug("Tracefile name %s, time %lu.%lu, tfi %u, ti %u", + g_quark_to_string(ltt_tracefile_name(tfc->tf)), + tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec, + tfc->index, tfc->t_context->index); - for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) { - tc = self->traces[iter_trace]; - { - /* each trace */ - guint iter_tf, nb_tracefile; - - LttvTracefileContext *tfc; - - nb_tracefile = tc->tracefiles->len; - - for(iter_tf = 0 ; iter_tf < nb_tracefile ; iter_tf++) { - tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, iter_tf); - { - /* each tracefile */ - //ltt_tracefile_copy(tfc->tf_sync_data, tfc->tf); - LttEventPosition *ep = ltt_event_position_new(); - - ltt_event_position(ltt_tracefile_get_event(tfc->tf), ep); - - ltt_tracefile_seek_position(tfc->tf, ep); - g_free(ep); - } - } - } + if(user_data != NULL) { + if(((LttvTracefileContext *)user_data) == (LttvTracefileContext *)value) { + g_assert(compare_tracefile(user_data, value) == 0); + } else + g_assert(compare_tracefile(user_data, value) != 0); } + g_assert(ltt_time_compare(test_time, tfc->timestamp) <= 0); + test_time.tv_sec = tfc->timestamp.tv_sec; + test_time.tv_nsec = tfc->timestamp.tv_nsec; + + + //g_assert(((LttvTracefileContext *)user_data) != (LttvTracefileContext *)value); + return FALSE; } +#endif //DEBUG @@ -677,6 +673,8 @@ void lttv_process_traceset_begin(LttvTracesetContext *self, } +enum read_state { LAST_NONE, LAST_OK, LAST_EMPTY }; + /* Note : a _middle must be preceded from a _seek or another middle */ guint lttv_process_traceset_middle(LttvTracesetContext *self, LttTime end, @@ -685,7 +683,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, { GTree *pqueue = self->pqueue; - guint id; + guint fac_id, ev_id, id; LttvTracefileContext *tfc; @@ -693,6 +691,10 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, unsigned count = 0; + guint read_ret; + + enum read_state last_read_state = LAST_NONE; + gboolean last_ret = FALSE; /* return value of the last hook list called */ /* Get the next event from the pqueue, call its hooks, @@ -718,29 +720,70 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, */ if(unlikely(last_ret == TRUE || - count >= nb_events || + ((count >= nb_events) && (nb_events != G_MAXULONG)) || (end_position!=NULL&<tv_traceset_context_ctx_pos_compare(self, end_position) == 0)|| ltt_time_compare(end, tfc->timestamp) <= 0)) { 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. */ - + +#ifdef DEBUG + test_time.tv_sec = 0; + test_time.tv_nsec = 0; + g_debug("test tree before remove"); + g_tree_foreach(pqueue, test_tree, tfc); +#endif //DEBUG g_tree_remove(pqueue, tfc); - count++; - + +#ifdef DEBUG + test_time.tv_sec = 0; + test_time.tv_nsec = 0; + g_debug("test tree after remove"); + g_tree_foreach(pqueue, test_tree, tfc); +#endif //DEBUG + e = ltt_tracefile_get_event(tfc->tf); - id = ltt_event_eventtype_id(e); - last_ret = lttv_hooks_call_merge(tfc->event, tfc, - lttv_hooks_by_id_get(tfc->event_by_id, id), tfc); - if(likely(!ltt_tracefile_read(tfc->tf))) { + if(last_read_state != LAST_EMPTY) { + /* Only call hooks if the last read has given an event or if we are at the + * 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); + last_ret = lttv_hooks_call_merge(tfc->event, tfc, + lttv_hooks_by_id_get(tfc->event_by_id, id), tfc); + } + + read_ret = ltt_tracefile_read(tfc->tf); + + if(likely(!read_ret)) { + //g_debug("An event is ready"); tfc->timestamp = ltt_event_time(e); + g_assert(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0); g_tree_insert(pqueue, tfc, tfc); +#ifdef DEBUG + test_time.tv_sec = 0; + test_time.tv_nsec = 0; + g_debug("test tree after event ready"); + g_tree_foreach(pqueue, test_tree, NULL); +#endif //DEBUG + + last_read_state = LAST_OK; + } else { + tfc->timestamp = ltt_time_infinite; + + if(read_ret == ERANGE) { + last_read_state = LAST_EMPTY; + g_debug("End of trace"); + } else + g_error("Error happened in lttv_process_traceset_middle"); } } } @@ -763,26 +806,49 @@ 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. + * + * Don't forget to empty the traceset pqueue before calling this. + */ void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) { guint i, nb_tracefile; gint ret; - LttvTracefileContext *tfc; - - GTree *pqueue = self->ts_context->pqueue; + LttvTracefileContext **tfc; nb_tracefile = self->tracefiles->len; + GTree *pqueue = self->ts_context->pqueue; + for(i = 0 ; i < nb_tracefile ; i++) { - tfc = g_array_index(self->tracefiles, LttvTracefileContext*, i); - ret = ltt_tracefile_seek_time(tfc->tf, start); - if(ret) g_error("error in lttv_process_trace_seek_time seek"); - g_tree_remove(pqueue, tfc); - tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf)); - g_tree_insert(pqueue, tfc, tfc); + tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i); + + //g_tree_remove(pqueue, *tfc); + + ret = ltt_tracefile_seek_time((*tfc)->tf, start); + if(ret == EPERM) g_error("error in lttv_process_trace_seek_time seek"); + + if(ret == 0) { /* not ERANGE especially */ + (*tfc)->timestamp = ltt_event_time(ltt_tracefile_get_event((*tfc)->tf)); + g_assert(ltt_time_compare((*tfc)->timestamp, ltt_time_infinite) != 0); + g_tree_insert(pqueue, (*tfc), (*tfc)); + } else { + (*tfc)->timestamp = ltt_time_infinite; + } } +#ifdef DEBUG + test_time.tv_sec = 0; + test_time.tv_nsec = 0; + g_debug("test tree after seek_time"); + g_tree_foreach(pqueue, test_tree, NULL); +#endif //DEBUG + + + } @@ -792,6 +858,9 @@ void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) LttvTraceContext *tc; + g_tree_destroy(self->pqueue); + self->pqueue = g_tree_new(compare_tracefile); + nb_trace = lttv_traceset_number(self->ts); for(i = 0 ; i < nb_trace ; i++) { tc = self->traces[i]; @@ -800,62 +869,41 @@ void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) } -gboolean lttv_process_tracefile_seek_position(LttvTracefileContext *self, - const LttEventPosition *pos) -{ - LttvTracefileContext *tfc = self; - - GTree *pqueue = self->t_context->ts_context->pqueue; - - ltt_tracefile_seek_position(tfc->tf, pos); - g_tree_remove(pqueue, tfc); - tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf)); - g_tree_insert(pqueue, tfc, tfc); - - return TRUE; -} - -gboolean lttv_process_trace_seek_position(LttvTraceContext *self, - const LttvTraceContextPosition *pos) -{ - guint i, nb_tracefile; - - LttvTracefileContext *tfc; - - nb_tracefile = self->tracefiles->len; - - if(nb_tracefile != pos->nb_tracefile) - return FALSE; /* Error */ - - for(i = 0 ; i < nb_tracefile ; i++) { - tfc = g_array_index(self->tracefiles, LttvTracefileContext*, i); - lttv_process_tracefile_seek_position(tfc, pos->tf_pos[i]); - } - - return TRUE; -} - - - gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, const LttvTracesetContextPosition *pos) { - guint i, nb_trace; - gboolean sum_ret = TRUE; - - LttvTraceContext *tc; - - nb_trace = lttv_traceset_number(self->ts); + guint i; - if(nb_trace != pos->nb_trace) - return FALSE; /* Error */ - - 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]); + /* If a position is set, seek the traceset to this position */ + if(ltt_time_compare(pos->timestamp, ltt_time_infinite) != 0) { + g_tree_destroy(self->pqueue); + self->pqueue = g_tree_new(compare_tracefile); + + for(i=0;iep->len; i++) { + LttEventPosition **ep = &g_array_index(pos->ep, LttEventPosition*, i); + LttvTracefileContext **tfc = + &g_array_index(pos->tfc, LttvTracefileContext*, i); + if(*ep != NULL) { + if(ltt_tracefile_seek_position((*tfc)->tf, *ep) != 0) + return 1; + (*tfc)->timestamp = ltt_event_time(ltt_tracefile_get_event((*tfc)->tf)); + g_assert(ltt_time_compare((*tfc)->timestamp, ltt_time_infinite) != 0); + g_tree_insert(self->pqueue, (*tfc), (*tfc)); + } else { + (*tfc)->timestamp = ltt_time_infinite; + } + } } +#ifdef DEBUG + test_time.tv_sec = 0; + test_time.tv_nsec = 0; + g_debug("test tree after seek_position"); + g_tree_foreach(self->pqueue, test_tree, NULL); +#endif //DEBUG - return sum_ret; + + + return 0; } @@ -906,7 +954,8 @@ LttvTraceHookByFacility *lttv_trace_hook_get_first(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) + GQuark field1, GQuark field2, GQuark field3, LttvHook h, gpointer hook_data, + LttvTraceHook *th) { LttFacility *f; @@ -914,12 +963,12 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, GArray *facilities; - guint i, fac_id; + 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, @@ -935,33 +984,37 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, 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, ltt_eventtype_name(et)); + 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; + g_array_index(th->fac_list, LttvTraceHookByFacility*, 0) = thf; + + ev_id = ltt_eventtype_id(et); + thf->h = h; - thf->id = ltt_eventtype_id(et); + 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;ilen;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)); + 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; + g_array_index(th->fac_list, LttvTraceHookByFacility*, i) = thf; + ev_id = ltt_eventtype_id(et); thf->h = h; - thf->id = ltt_eventtype_id(et); + 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)) @@ -976,6 +1029,7 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, if(check_fields_compatibility(first_et, et, first_thf->f3, thf->f3)) goto type_error; + thf->hook_data = hook_data; } return 0; @@ -983,8 +1037,8 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, type_error: goto free; event_error: - g_error("Event type %s does not exist", - g_quark_to_string(ltt_eventtype_name(et))); + g_error("Event type does not exist for event %s", + g_quark_to_string(event)); goto free; facility_error: g_error("No %s facility", g_quark_to_string(facility)); @@ -1006,139 +1060,129 @@ void lttv_trace_hook_destroy(LttvTraceHook *th) LttvTracesetContextPosition *lttv_traceset_context_position_new() { - return g_new(LttvTracesetContextPosition,1); + 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; } - +/* Save all positions, the ones with infinite time will have NULL + * ep. */ void lttv_traceset_context_position_save(const LttvTracesetContext *self, LttvTracesetContextPosition *pos) { - guint nb_trace, nb_tracefile; - guint iter_trace, iter_tracefile; - - LttvTraceContext *tc; + guint i; + guint num_traces = lttv_traceset_number(self->ts); - LttvTracefileContext *tfc; - - LttEvent *event; - - LttTime timestamp = self->time_span.end_time; - - pos->nb_trace = nb_trace = lttv_traceset_number(self->ts); - pos->t_pos = g_new(LttvTraceContextPosition, nb_trace); + pos->tfc = g_array_set_size(pos->tfc, 0); + pos->ep = g_array_set_size(pos->ep, 0); - for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) { - tc = self->traces[iter_trace]; - - nb_tracefile = tc->tracefiles->len; - pos->t_pos[iter_trace].nb_tracefile = nb_tracefile; - - pos->t_pos[iter_trace].tf_pos = g_new(LttEventPosition*, nb_tracefile); - for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) { - tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, - iter_tracefile); - event = ltt_tracefile_get_event(tfc->tf); - if(event!=NULL) { - pos->t_pos[iter_trace].tf_pos[iter_tracefile] - = ltt_event_position_new(); - ltt_event_position(event, - pos->t_pos[iter_trace].tf_pos[iter_tracefile]); + for(i=0; itraces[i]->tracefiles; + guint j; + guint num_tracefiles = tracefiles->len; + + for(j=0;jtf); + LttEventPosition *ep; + + if(ltt_time_compare((*tfc)->timestamp, ltt_time_infinite) != 0) { + ep = ltt_event_position_new(); + ltt_event_position(event, ep); + if(ltt_time_compare((*tfc)->timestamp, pos->timestamp) < 0) + pos->timestamp = (*tfc)->timestamp; } else { - pos->t_pos[iter_trace].tf_pos[iter_tracefile] = NULL; + ep = NULL; } - if(ltt_time_compare(tfc->timestamp, timestamp) < 0) - timestamp = tfc->timestamp; + g_array_append_val(pos->tfc, *tfc); + g_array_append_val(pos->ep, ep); } + } - pos->timestamp = timestamp; } void lttv_traceset_context_position_destroy(LttvTracesetContextPosition *pos) { - guint nb_trace; - guint iter_trace, iter_tracefile; - - nb_trace = pos->nb_trace; + int i; + LttEventPosition **ep; - 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++) { - if(pos->t_pos[iter_trace].tf_pos[iter_tracefile] != NULL) - g_free(pos->t_pos[iter_trace].tf_pos[iter_tracefile]); - } - g_free(pos->t_pos[iter_trace].tf_pos); + for(i=0;iep->len;i++) { + ep = &g_array_index(pos->ep, LttEventPosition*, i); + if(*ep != NULL) + g_free(*ep); } - g_free(pos->t_pos); - + 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) { - guint nb_trace, nb_tracefile; - guint iter_trace, iter_tracefile; + int i; + LttEventPosition **src_ep, **dest_ep; - nb_trace = dest->nb_trace = src->nb_trace; - dest->t_pos = g_new(LttvTraceContextPosition, nb_trace); - - for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) { - - nb_tracefile = src->t_pos[iter_trace].nb_tracefile; - - dest->t_pos[iter_trace].nb_tracefile = nb_tracefile; - - dest->t_pos[iter_trace].tf_pos = g_new(LttEventPosition*, nb_tracefile); - - for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) { - dest->t_pos[iter_trace].tf_pos[iter_tracefile] = - ltt_event_position_new(); - if(src->t_pos[iter_trace].tf_pos[iter_tracefile] != NULL) - ltt_event_position_copy( - dest->t_pos[iter_trace].tf_pos[iter_tracefile], - src->t_pos[iter_trace].tf_pos[iter_tracefile]); - else - dest->t_pos[iter_trace].tf_pos[iter_tracefile] = NULL; - } + dest->ep = g_array_set_size(dest->ep, src->ep->len); + dest->tfc = g_array_set_size(dest->tfc, src->tfc->len); + + for(i=0;iep->len;i++) { + src_ep = &g_array_index(src->ep, LttEventPosition*, i); + dest_ep = &g_array_index(dest->ep, LttEventPosition*, i); + if(*src_ep != NULL) { + *dest_ep = ltt_event_position_new(); + ltt_event_position_copy( + *dest_ep, + *src_ep); + } else + *dest_ep = NULL; + } + for(i=0;itfc->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; - - LttvTraceContext *tc; + int i; + int ret = 0; - LttvTracefileContext *tfc; - - LttEvent *event; - - nb_trace = lttv_traceset_number(self->ts); - - if(unlikely(pos->nb_trace != nb_trace)) - g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match."); + if(pos->ep->len == 0) { + if(lttv_traceset_number(self->ts) == 0) return 0; + else return 1; + } + if(lttv_traceset_number(self->ts) == 0) + return -1; - for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) { - tc = self->traces[iter_trace]; - nb_tracefile = tc->tracefiles->len; + for(i=0;iep->len;i++) { + LttEventPosition *ep = g_array_index(pos->ep, LttEventPosition*, i); + LttvTracefileContext *tfc = + g_array_index(pos->tfc, LttvTracefileContext*, i); + + if(ep == NULL) { + if(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0) { + ret = -1; + } + } else { + if(ltt_time_compare(tfc->timestamp, ltt_time_infinite) == 0) { + ret = 1; + } else { + LttEvent *event = ltt_tracefile_get_event(tfc->tf); - if(unlikely(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 = g_array_index(tc->tracefiles, LttvTracefileContext*, - iter_tracefile); - event = ltt_tracefile_get_event(tfc->tf); - ret = ltt_event_position_compare((LttEventPosition*)event, - pos->t_pos[iter_trace].tf_pos[iter_tracefile]); - if(ret != 0) - return ret; + ret = ltt_event_position_compare((LttEventPosition*)event, + ep); + } } + if(ret != 0) return ret; + } return 0; } @@ -1148,27 +1192,44 @@ 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(unlikely(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(unlikely(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++) { - ret = ltt_event_position_compare( - pos1->t_pos[iter_trace].tf_pos[iter_tracefile], - pos2->t_pos[iter_trace].tf_pos[iter_tracefile]); - if(ret != 0) - return ret; + if(pos1->ep->len == 0) { + if(pos2->ep->len == 0) return 0; + else return 1; + } + if(pos2->ep->len == 0) + return -1; + + for(i=0;iep->len;i++) { + LttEventPosition *ep1 = g_array_index(pos1->ep, LttEventPosition*, i); + LttvTracefileContext *tfc1 = g_array_index(pos1->tfc, + LttvTracefileContext*, i); + + if(ep1 != NULL) { + for(j=0;jep->len;j++) { + LttEventPosition *ep2 = g_array_index(pos2->ep, LttEventPosition*, j); + LttvTracefileContext *tfc2 = g_array_index(pos2->tfc, + LttvTracefileContext*, j); + if(tfc1 == tfc2) { + if(ep2 != NULL) + ret = ltt_event_position_compare(ep1, ep2); + else + ret = -1; + + if(ret != 0) return ret; + } + } + } else { + for(j=0;jep->len;j++) { + LttEventPosition *ep2 = g_array_index(pos2->ep, LttEventPosition*, j); + LttvTracefileContext *tfc2 = g_array_index(pos2->tfc, + LttvTracefileContext*, j); + if(tfc1 == tfc2) { + if(ep2 != NULL) ret = 1; + } + } } } return 0; @@ -1191,3 +1252,24 @@ LttvTracefileContext *lttv_traceset_context_get_current_tfc(LttvTracesetContext return tfc; } + +/* lttv_process_traceset_synchronize_tracefiles + * + * Use the sync_position field of the trace set context to synchronize each + * tracefile with the previously saved position. + * + * If no previous position has been saved, it simply does nothing. + */ +void lttv_process_traceset_synchronize_tracefiles(LttvTracesetContext *tsc) +{ + g_assert(lttv_process_traceset_seek_position(tsc, tsc->sync_position) == 0); +} + + + + +void lttv_process_traceset_get_sync_data(LttvTracesetContext *tsc) +{ + lttv_traceset_context_position_save(tsc, tsc->sync_position); +} +