X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ftracecontext.c;h=c78907909d10bc2846d2d6bd339bcdd50143e983;hb=36d36c9f7565d90fdbe9de5532b096507c6b92b3;hp=a73e3d6ce608e12a8e66ecdab293f8afd23a9371;hpb=698e81c2b57c2557ec70f7dfe53538d7359e0552;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index a73e3d6c..c7890790 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -48,10 +48,7 @@ gint compare_tracefile(gconstpointer a, gconstpointer b) else if(trace_a->t_context->index > trace_b->t_context->index) comparison = 1; } - } else { - comparison = 0; } - return comparison; } @@ -168,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; @@ -181,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; @@ -195,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); @@ -245,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); @@ -264,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); @@ -343,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); @@ -368,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); @@ -617,13 +615,26 @@ 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) { - g_assert(((LttvTracefileContext *)user_data) != (LttvTracefileContext *)value); + 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; } @@ -648,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, @@ -664,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 */ @@ -698,33 +713,51 @@ 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 + 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); - count++; - +#endif //DEBUG + 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("got someting"); + g_debug("An event is ready"); tfc->timestamp = ltt_event_time(e); + g_tree_insert(pqueue, tfc, tfc); + last_read_state = LAST_OK; } else { - if(read_ret == ERANGE) + tfc->timestamp = ltt_time_infinite; + + 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"); } } @@ -757,21 +790,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; } } } @@ -795,21 +832,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; } @@ -860,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; @@ -873,7 +914,7 @@ lttv_trace_find_hook(LttTrace *t, GQuark facility, GQuark event, 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, @@ -893,8 +934,7 @@ 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); @@ -903,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++) { @@ -915,8 +957,7 @@ 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 = GET_HOOK_ID(fac_id, ev_id); @@ -934,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; @@ -973,38 +1015,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); @@ -1014,15 +1069,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) = @@ -1035,17 +1096,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); + + 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); - LttEvent *event = ltt_tracefile_get_event(tfc->tf); - - ret = ltt_event_position_compare((LttEventPosition*)event, - ep); + ret = ltt_event_position_compare((LttEventPosition*)event, + ep); + } + } if(ret != 0) return ret; } @@ -1060,22 +1138,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; - } @@ -1095,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 +