X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ftracecontext.c;h=6f1e7b58a334665c1f1254cb9204d67c3bbb9c23;hb=f4b88a7dd49bfb6b88ea579410d7e4b59faaf73c;hp=03cee2cca190717b05e880ddcaf1d73e0f1e59db;hpb=8fe3c6b699e245cf9a5263e687778dc10d501f4b;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index 03cee2cc..6f1e7b58 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -56,7 +56,10 @@ struct _LttvTracesetContextPosition { GArray *ep; /* Array of LttEventPosition */ GArray *tfc; /* Array of corresponding TracefileContext* */ - LttTime timestamp; /* Current time at the saved position */ + 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) @@ -178,7 +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(); + 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; @@ -250,7 +253,7 @@ void fini(LttvTracesetContext *self) g_tree_destroy(self->pqueue); g_object_unref(self->a); - // lttv_traceset_context_position_destroy(self->sync_position); + lttv_traceset_context_position_destroy(self->sync_position); nb_trace = lttv_traceset_number(ts); @@ -620,6 +623,10 @@ static gboolean get_first(gpointer key, gpointer value, gpointer user_data) { return TRUE; } +#ifdef DEBUG +// Test to see if pqueue is traversed in the right order. +static LttTime test_time; + static gboolean test_tree(gpointer key, gpointer value, gpointer user_data) { LttvTracefileContext *tfc = (LttvTracefileContext *)key; @@ -628,15 +635,22 @@ static gboolean test_tree(gpointer key, gpointer value, gpointer user_data) { g_quark_to_string(ltt_tracefile_name(tfc->tf)), tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec, tfc->index, tfc->t_context->index); + + 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; - 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(((LttvTracefileContext *)user_data) != (LttvTracefileContext *)value); return FALSE; } +#endif //DEBUG @@ -659,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, @@ -675,7 +691,9 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, unsigned count = 0; - guint read_ret = FALSE; + guint read_ret; + + enum read_state last_read_state = LAST_NONE; gboolean last_ret = FALSE; /* return value of the last hook list called */ @@ -709,44 +727,62 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, { 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); #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 - 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); + 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"); + //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) + if(read_ret == ERANGE) { + last_read_state = LAST_EMPTY; g_debug("End of trace"); - else + } else g_error("Error happened in lttv_process_traceset_middle"); } } @@ -772,7 +808,10 @@ void lttv_process_traceset_end(LttvTracesetContext *self, /* 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. */ + * 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; @@ -781,25 +820,35 @@ void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) LttvTracefileContext **tfc; - GTree *pqueue = self->ts_context->pqueue; - 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); - g_tree_remove(pqueue, *tfc); + //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 + + + } @@ -809,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]; @@ -821,23 +873,36 @@ gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, const LttvTracesetContextPosition *pos) { guint i; - - 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_tree_insert(self->pqueue, (*tfc), (*tfc)); - } else { - (*tfc)->timestamp = ltt_time_infinite; + /* 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 0; } @@ -942,7 +1007,7 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, 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); @@ -972,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)); @@ -1004,14 +1069,17 @@ LttvTracesetContextPosition *lttv_traceset_context_position_new() return pos; } -/* Save all positions, the ones not in the pqueue will have NULL +/* Save all positions, the ones with infinite time will have NULL * ep. */ void lttv_traceset_context_position_save(const LttvTracesetContext *self, LttvTracesetContextPosition *pos) { guint i; guint num_traces = lttv_traceset_number(self->ts); - + + pos->tfc = g_array_set_size(pos->tfc, 0); + pos->ep = g_array_set_size(pos->ep, 0); + for(i=0; itraces[i]->tracefiles; guint j; @@ -1060,8 +1128,8 @@ void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest, int i; LttEventPosition **src_ep, **dest_ep; - g_array_set_size(dest->ep, src->ep->len); - g_array_set_size(dest->tfc, src->tfc->len); + 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); @@ -1184,7 +1252,7 @@ LttvTracefileContext *lttv_traceset_context_get_current_tfc(LttvTracesetContext return tfc; } -#if 0 + /* lttv_process_traceset_synchronize_tracefiles * * Use the sync_position field of the trace set context to synchronize each @@ -1205,5 +1273,3 @@ void lttv_process_traceset_get_sync_data(LttvTracesetContext *tsc) lttv_traceset_context_position_save(tsc, tsc->sync_position); } -#endif //0 -