X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ftracecontext.c;h=c78907909d10bc2846d2d6bd339bcdd50143e983;hb=36d36c9f7565d90fdbe9de5532b096507c6b92b3;hp=970da06454407f05b1bea32c6f0b9c5ffc3c5084;hpb=021eeb4103ade4c06dc3c1d7475187483d86009a;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index 970da064..c7890790 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -39,7 +39,7 @@ gint compare_tracefile(gconstpointer a, gconstpointer b) const LttvTracefileContext *trace_b = (const LttvTracefileContext *)b; if(likely(trace_a != trace_b)) { - comparison = ltt_time_compare(trace_b->timestamp, trace_a->timestamp); + 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; @@ -165,7 +165,7 @@ static void init_tracefile_context(LttTracefile *tracefile, static void init(LttvTracesetContext *self, LttvTraceset *ts) { - guint i, j, nb_trace; + guint i, nb_trace; LttvTraceContext *tc; @@ -178,6 +178,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; @@ -249,6 +250,7 @@ void fini(LttvTracesetContext *self) g_tree_destroy(self->pqueue); g_object_unref(self->a); + // lttv_traceset_context_position_destroy(self->sync_position); nb_trace = lttv_traceset_number(ts); @@ -657,6 +659,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, @@ -673,7 +677,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 */ @@ -707,7 +713,7 @@ 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. */ @@ -723,15 +729,20 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, 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)) { @@ -739,12 +750,14 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, tfc->timestamp = ltt_event_time(e); g_tree_insert(pqueue, tfc, tfc); + 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"); } } @@ -819,8 +832,6 @@ gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, const LttvTracesetContextPosition *pos) { guint i; - LttvTraceContext *tc; - LttvTracefileContext *tfc; g_tree_destroy(self->pqueue); self->pqueue = g_tree_new(compare_tracefile); @@ -830,14 +841,15 @@ gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, LttvTracefileContext **tfc = &g_array_index(pos->tfc, LttvTracefileContext*, i); if(*ep != NULL) { - g_assert(ltt_tracefile_seek_position((*tfc)->tf, *ep) == 0); + 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; } } - return TRUE; + return 0; } @@ -888,7 +900,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; @@ -930,8 +943,10 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, 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++) { @@ -960,6 +975,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; @@ -1080,8 +1096,15 @@ gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self, const LttvTracesetContextPosition *pos) { int i; - int ret; - + int ret = 0; + + 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(i=0;iep->len;i++) { LttEventPosition *ep = g_array_index(pos->ep, LttEventPosition*, i); LttvTracefileContext *tfc = @@ -1115,6 +1138,13 @@ gint lttv_traceset_context_pos_pos_compare( int i, j; int 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, @@ -1165,3 +1195,26 @@ 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 + * 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); +} + +#endif //0 +