X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ftracecontext.c;h=5c2a17cb33b1ac349a1a609fe88d7098104b5494;hb=79257ba540581e198c9d9b047fe0738a25c324ff;hp=28c279670efe89e53272cabc77bb5a378934500f;hpb=9d239bd92ef3198e80333c703f3ab8ff8cdaeaf7;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index 28c27967..5c2a17cb 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_a->timestamp, trace_b->timestamp); + comparison = ltt_time_compare(trace_b->timestamp, trace_a->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, nb_control, nb_per_cpu, nb_tracefile; + 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; @@ -192,13 +193,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); @@ -242,14 +244,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); @@ -261,11 +262,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); @@ -340,15 +341,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); @@ -365,13 +366,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); @@ -614,10 +615,30 @@ 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; } +static gboolean test_tree(gpointer key, gpointer value, gpointer user_data) { + + LttvTracefileContext *tfc = (LttvTracefileContext *)key; + + 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); + + 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; +} + + void lttv_process_traceset_begin(LttvTracesetContext *self, LttvHooks *before_traceset, @@ -646,7 +667,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, { GTree *pqueue = self->pqueue; - guint id; + guint fac_id, ev_id, id; LttvTracefileContext *tfc; @@ -654,6 +675,8 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, 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, @@ -679,7 +702,7 @@ 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)) @@ -690,18 +713,41 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, /* 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 + g_debug("test tree before remove"); + g_tree_foreach(pqueue, test_tree, tfc); +#endif //DEBUG g_tree_remove(pqueue, tfc); + +#ifdef DEBUG + g_debug("test tree after remove"); + g_tree_foreach(pqueue, test_tree, tfc); +#endif //DEBUG + count++; e = ltt_tracefile_get_event(tfc->tf); - id = ltt_event_eventtype_id(e); + 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(likely(!ltt_tracefile_read(tfc->tf))) { + read_ret = ltt_tracefile_read(tfc->tf); + + if(likely(!read_ret)) { + g_debug("An event is ready"); tfc->timestamp = ltt_event_time(e); + g_tree_insert(pqueue, tfc, tfc); + } else { + tfc->timestamp = ltt_time_infinite; + + if(read_ret == ERANGE) + g_debug("End of trace"); + else + g_error("Error happened in lttv_process_traceset_middle"); } } } @@ -733,21 +779,25 @@ void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) gint ret; - LttvTracefileContext *tfc; + LttvTracefileContext **tfc; GTree *pqueue = self->ts_context->pqueue; nb_tracefile = self->tracefiles->len; for(i = 0 ; i < nb_tracefile ; i++) { - tfc = g_array_index(self->tracefiles, LttvTracefileContext*, i); - ret = ltt_tracefile_seek_time(tfc->tf, start); + 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"); - 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); + (*tfc)->timestamp = ltt_event_time(ltt_tracefile_get_event((*tfc)->tf)); + g_tree_insert(pqueue, (*tfc), (*tfc)); + } else { + (*tfc)->timestamp = ltt_time_infinite; } } } @@ -771,21 +821,24 @@ 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); for(i=0;iep->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); + 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; + } } - return TRUE; + return 0; } @@ -836,7 +889,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; @@ -844,12 +898,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, @@ -869,16 +923,19 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark 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++) { @@ -889,10 +946,10 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark 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)) @@ -907,6 +964,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; @@ -946,38 +1004,51 @@ LttvTracesetContextPosition *lttv_traceset_context_position_new() 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(); - - ltt_event_position(event, ep); - - g_array_append_val(pos->ep, ep); - g_array_append_val(pos->tfc, tfc); - - if(ltt_time_compare(tfc->timestamp, pos->timestamp) < 0) - pos->timestamp = tfc->timestamp; - - return 0; -} - -/* Subtile modification : - * only save the tracefiles that are loaded in the pqueue */ +/* Save all positions, the ones not in the pqueue will have NULL + * ep. */ void lttv_traceset_context_position_save(const LttvTracesetContext *self, LttvTracesetContextPosition *pos) { - g_tree_foreach(self->pqueue, traverse_get_tfc, pos); + guint i; + guint num_traces = lttv_traceset_number(self->ts); + + 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 { + ep = NULL; + } + g_array_append_val(pos->tfc, *tfc); + g_array_append_val(pos->ep, ep); + } + + } } void lttv_traceset_context_position_destroy(LttvTracesetContextPosition *pos) { int i; - for(i=0;iep->len;i++) - g_free(g_array_index(pos->ep, LttEventPosition*, i)); + LttEventPosition **ep; + + for(i=0;iep->len;i++) { + ep = &g_array_index(pos->ep, LttEventPosition*, i); + if(*ep != NULL) + g_free(*ep); + } g_array_free(pos->ep, TRUE); g_array_free(pos->tfc, TRUE); g_free(pos); @@ -987,15 +1058,21 @@ void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest, const LttvTracesetContextPosition *src) { 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); for(i=0;iep->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)); + 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) = @@ -1008,17 +1085,34 @@ 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 = g_array_index(pos->tfc, LttvTracefileContext*, i); - - LttEvent *event = ltt_tracefile_get_event(tfc->tf); - - ret = ltt_event_position_compare((LttEventPosition*)event, - ep); + + 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); + + ret = ltt_event_position_compare((LttEventPosition*)event, + ep); + } + } if(ret != 0) return ret; } @@ -1033,22 +1127,44 @@ 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); - LttTracefile *tf1 = ltt_event_position_tracefile(ep1); + LttvTracefileContext *tfc1 = g_array_index(pos1->tfc, + LttvTracefileContext*, i); - for(j=0;jep->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; + 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; - } @@ -1068,3 +1184,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 +