X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=lttv%2Flttv%2Ftracecontext.c;h=5f6455a42f4be31b1d8bd4db7efba9ebce502e8f;hb=9a366873e0ed6ecc7f23e2d3a959ecddd4f2f91d;hp=136b2eec2f5dfe3b820f9ad30c3cec5bdb685873;hpb=90e19f82bca635a1ba52b8a50b64e484bd19c14f;p=lttv.git diff --git a/lttv/lttv/tracecontext.c b/lttv/lttv/tracecontext.c index 136b2eec..5f6455a4 100644 --- a/lttv/lttv/tracecontext.c +++ b/lttv/lttv/tracecontext.c @@ -22,12 +22,24 @@ #include #include -#include +#include #include #include +#ifdef BABEL_NOFILTER #include +#endif #include +#include +#include + +#include +#include + +#include +#include + +#ifdef BABEL_CLEANUP gint compare_tracefile(gconstpointer a, gconstpointer b) { gint comparison = 0; @@ -63,7 +75,7 @@ struct _LttvTracesetContextPosition { * set, else, a position is set (may be end * of trace, with ep->len == 0) */ }; - +#endif void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts) { LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts); @@ -112,6 +124,8 @@ lttv_context_new_tracefile_context(LttvTracesetContext *self) void lttv_traceset_context_compute_time_span(LttvTracesetContext *self, TimeInterval *time_span) { + //todo mdenis: adapt to babeltrace +#ifdef BABEL_CLEANUP LttvTraceset * traceset = self->ts; int numTraces = lttv_traceset_number(traceset); int i; @@ -126,6 +140,7 @@ void lttv_traceset_context_compute_time_span(LttvTracesetContext *self, for(i=0; itraces[i]; + trace = tc->t; ltt_trace_time_span_get(trace, &s, &e); @@ -146,6 +161,7 @@ void lttv_traceset_context_compute_time_span(LttvTracesetContext *self, time_span->end_time = e; } } +#endif } static void init_tracefile_context(LttTracefile *tracefile, @@ -179,12 +195,23 @@ init(LttvTracesetContext *self, LttvTraceset *ts) GData **tracefiles_groups; struct compute_tracefile_group_args args; + + struct bt_iter_pos begin_pos; nb_trace = lttv_traceset_number(ts); self->ts = ts; self->traces = g_new(LttvTraceContext *, nb_trace); self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); self->ts_a = lttv_traceset_attribute(ts); + + begin_pos.type = BT_SEEK_BEGIN; + + self->iter = bt_ctf_iter_create(lttv_traceset_get_context(ts), + &begin_pos, + NULL); + self->event_hooks = lttv_hooks_new(); + self->tmpState = g_new(LttvTraceState *, 1); + for(i = 0 ; i < nb_trace ; i++) { tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self); self->traces[i] = tc; @@ -192,12 +219,15 @@ init(LttvTracesetContext *self, LttvTraceset *ts) tc->ts_context = self; tc->index = i; tc->vt = lttv_traceset_get(ts, i); +#ifdef BABEL_CLEANUP tc->t = lttv_trace(tc->vt); +#endif tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); tc->t_a = lttv_trace_attribute(tc->vt); tc->tracefiles = g_array_sized_new(FALSE, TRUE, sizeof(LttvTracefileContext*), 10); +#ifdef BABEL_CLEANUP tracefiles_groups = ltt_trace_get_tracefiles_groups(tc->t); if(tracefiles_groups != NULL) { args.func = (ForEachTraceFileFunc)init_tracefile_context; @@ -207,37 +237,14 @@ init(LttvTracesetContext *self, LttvTraceset *ts) (GDataForeachFunc)compute_tracefile_group, &args); } +#endif -#if 0 - nb_control = ltt_trace_control_tracefile_number(tc->t); - nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t); - nb_tracefile = nb_control + nb_per_cpu; - tc->tracefiles = g_new(LttvTracefileContext *, nb_tracefile); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self); - tc->tracefiles[j] = tfc; - tfc->index = j; - - if(j < nb_control) { - tfc->control = TRUE; - tfc->tf = ltt_trace_control_tracefile_get(tc->t, j); - } else { - tfc->control = FALSE; - tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control); - } - - tfc->t_context = tc; - tfc->e = ltt_event_new(); - tfc->event = lttv_hooks_new(); - tfc->event_by_id = lttv_hooks_by_id_new(); - tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - } -#endif //0 } self->sync_position = lttv_traceset_context_position_new(self); +#ifdef BABEL_CLEANUP self->pqueue = g_tree_new(compare_tracefile); +#endif lttv_process_traceset_seek_time(self, ltt_time_zero); lttv_traceset_context_compute_time_span(self, &self->time_span); @@ -295,6 +302,8 @@ void lttv_traceset_context_add_hooks(LttvTracesetContext *self, LttvTraceContext *tc; lttv_hooks_call(before_traceset, self); + + lttv_hooks_add_list(self->event_hooks, event); nb_trace = lttv_traceset_number(ts); @@ -681,6 +690,47 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, gulong nb_events, const LttvTracesetContextPosition *end_position) { + + unsigned count = 0; + + gint last_ret = 0; + struct bt_ctf_event *bt_event; + + LttvEvent event; + + while(TRUE) { + + if(last_ret == TRUE || ((count >= nb_events) && (nb_events != G_MAXULONG))) { + break; + } + + if((bt_event = bt_ctf_iter_read_event(self->iter)) != NULL) { + + count++; + + event.bt_event = bt_event; + /* TODO ybrosseau 2012-04-01: use bt_ctf_get_trace_handle + to retrieve the right state container */ + event.state = self->tmpState; + + last_ret = lttv_hooks_call(self->event_hooks, &event); + + if(bt_iter_next(bt_ctf_get_iter(self->iter)) < 0) { + printf("ERROR NEXT\n"); + break; + } + } else { + /* READ FAILED */ + + break; + + } + } + + + + return count; +#ifdef BABEL_CLEANUP GTree *pqueue = self->pqueue; LttvTracefileContext *tfc; @@ -689,6 +739,8 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, unsigned count = 0; + gboolean is_live = FALSE; /* set this flag if we detect a live trace */ + guint read_ret; //enum read_state last_read_state = LAST_NONE; @@ -706,7 +758,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, /* End of traceset : tfc is NULL */ if(unlikely(tfc == NULL)) { - return count; + break; } /* Have we reached : @@ -716,14 +768,17 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, * then the read is finished. We leave the queue in the same state and * break the loop. */ - + if(tfc->tf->trace->is_live && ltt_time_compare(tfc->timestamp, tfc->tf->trace->live_safe_timestamp) >= 0) { + + break; + } if(unlikely(last_ret == TRUE || ((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; + break; } /* Get the tracefile with an event for the smallest time found. If two @@ -765,7 +820,8 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, if(unlikely(last_ret == 2)) { /* This is a case where we want to stay at this position and stop read. */ g_tree_insert(pqueue, tfc, tfc); - return count - 1; + count--; + break; } #endif //0 read_ret = ltt_tracefile_read(tfc->tf); @@ -774,8 +830,15 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, 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); + if(tfc->tf->trace->is_live && ltt_time_compare(tfc->timestamp, tfc->tf->trace->live_safe_timestamp) >= 0) + { + is_live |= TRUE; + break; + } #ifdef DEBUG test_time.tv_sec = 0; test_time.tv_nsec = 0; @@ -794,6 +857,14 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self, g_error("Error happened in lttv_process_traceset_middle"); } } + + if (unlikely((count == 0) && is_live)) { + return -1; + } else { + return count; + } + +#endif /* BABEL_CLEANUP */ } @@ -856,11 +927,103 @@ void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) #endif //DEBUG } +/**************************************************************************** + * lttv_process_trace_update + * + * process the changes that occur in the trace. Use a regular file polling to + * monitor the tracefile. + * + * Return the number of tracefile updated + ***************************************************************************/ +guint lttv_process_trace_update(LttvTraceContext *self) +{ + guint i; + guint nb_tracefile = 0; -void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) + LttTracefile *tf = 0; + LttvTracefileContext **tfc; + + /* Skip non live traces */ + if(self->t->is_live) { + + nb_tracefile = ltt_trace_update(self->t); + + /* Recreate the pqueue following an update*/ + GTree *pqueue = self->ts_context->pqueue; + + for(i = 0 ; i < self->tracefiles->len ; i++) { + tfc = &g_array_index(self->tracefiles, LttvTracefileContext*, i); + tf = (*tfc)->tf; + if(g_tree_remove(pqueue, *tfc) == FALSE) { + if(tf->buf_index != NULL) { + + if(ltt_tracefile_read(tf) == 0) { + + (*tfc)->timestamp = ltt_event_time(ltt_tracefile_get_event((*tfc)->tf)); + g_tree_insert(pqueue, (*tfc), (*tfc)); + + } + } + } else { + g_tree_insert(pqueue, (*tfc), (*tfc)); + + } + + + } + //Update self time span + self->time_span.end_time = LTT_TIME_MAX(self->t->live_safe_timestamp, + self->time_span.end_time); + //Update self tscontext time span + self->ts_context->time_span.end_time = LTT_TIME_MAX(self->time_span.end_time, + self->ts_context->time_span.end_time); + } + return nb_tracefile; + +} + +/**************************************************************************** + * lttv_process_traceset_update + * + * process the changes that occur in the traceset. + * + * Return the number of file presently monitor(open for writting). If 0, the + * current traceset probably received all the data. + ***************************************************************************/ +guint lttv_process_traceset_update(LttvTracesetContext *self) { + guint i; + guint nb_trace; + guint open_counter = 0; + + nb_trace = lttv_traceset_number(self->ts); + + for(i = 0 ; i < nb_trace ; i++) { + open_counter += lttv_process_trace_update(self->traces[i]); + } + return open_counter; +} + +void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) +{ +#ifdef WAIT_FOR_BABELTRACE_FIX_SEEK_ZERO + struct bt_iter_pos seekpos; + int ret; + seekpos.type = BT_SEEK_TIME; + seekpos.u.seek_time = ltt_time_to_uint64(start); + ret = bt_iter_set_pos(bt_ctf_get_iter(self->iter), &seekpos); + if(ret < 0) { + printf("Seek by time error: %s,\n",strerror(-ret)); + } +#else +#warning Seek time disabled because of babeltrace bugs +#endif + +#ifdef BABEL_CLEANUP guint i, nb_trace; + + LttvTraceContext *tc; //g_tree_destroy(self->pqueue); @@ -871,6 +1034,7 @@ void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) tc = self->traces[i]; lttv_process_trace_seek_time(tc, start); } +#endif }