From mboxrd@z Thu Jan 1 00:00:00 1970 From: compudj@krystal.dyndns.org (Mathieu Desnoyers) Date: Sat, 11 Sep 2010 12:34:12 -0400 Subject: [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace. In-Reply-To: <4C7858C0.1020602@polymtl.ca> References: <1282927004-11289-1-git-send-email-oussama.el-mfadli@polymtl.ca> <20100827172945.GA30338@Krystal> <4C7858C0.1020602@polymtl.ca> Message-ID: <20100911163412.GB28088@Krystal> * Oussama El Mfadli (oussama.el-mfadli at polymtl.ca) wrote: > Hi, > As you suggest, I removed the lttv_process_traceset_middle_streaming. > Now the lttv_process_trace_update is called directly from the > lttv_process_traceset_middle. > Also added a support if inotify is not available. > > The patch is following: > ----------- > > Add Support to lttv to analyse streaming traces > > --- > lttv/lttv/batchtest.c | 2 +- > lttv/lttv/tracecontext.c | 184 > +++++++++++++++++++- > lttv/lttv/tracecontext.h | 7 +- > lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c | 4 +- > lttv/modules/text/batchAnalysis.c | 27 +++- > 5 files changed, 210 insertions(+), 14 deletions(-) > > diff --git a/lttv/lttv/batchtest.c b/lttv/lttv/batchtest.c > index 08b892b..df15dcd 100644 > --- a/lttv/lttv/batchtest.c > +++ b/lttv/lttv/batchtest.c > @@ -100,7 +100,7 @@ static void lttv_trace_option(void __UNUSED__ > *hook_data) > { > LttTrace *trace; > > - trace = ltt_trace_open(a_trace); > + trace = ltt_trace_open(a_trace, NO_FLAG); Just "0" would be fine. Please remove the "NO_FLAG" define. > if(trace == NULL) { > g_critical("cannot open trace %s", a_trace); > } else { > diff --git a/lttv/lttv/tracecontext.c b/lttv/lttv/tracecontext.c > index 136b2ee..332ae46 100644 > --- a/lttv/lttv/tracecontext.c > +++ b/lttv/lttv/tracecontext.c > @@ -28,6 +28,19 @@ > #include > #include > > +#include > + > +#include > + > +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) > +#include > +#define HAS_INOTIFY > + > +#else > + > +#undef HAS_INOTIFY > +#endif This should be put in a single header included by all code checking HAS_INOTIFY. This is a copy-paste of the library code. > + > gint compare_tracefile(gconstpointer a, gconstpointer b) > { > gint comparison = 0; > @@ -690,12 +703,23 @@ guint > lttv_process_traceset_middle(LttvTracesetContext *self, > unsigned count = 0; > > guint read_ret; > - > + guint i; > + guint tracefile_counter = 0; > + extra line. > + gboolean isStreaming = FALSE; > //enum read_state last_read_state = LAST_NONE; > > gint last_ret = 0; /* return value of the last hook list called */ > - > - /* Get the next event from the pqueue, call its hooks, > + > + guint num_trace = lttv_traceset_number(self->ts); > + for(i=0; i< num_trace; i++) > + if(self->traces[i]->t->streaming_is_enable == TRUE) > + { > + isStreaming = TRUE; > + tracefile_counter = lttv_process_traceset_update(self); > + break; > + } > + /* Get the next event from the pqueue, call its hooks, > reinsert in the pqueue the following event from the same tracefile > unless the tracefile is finished or the event is later than the > end time. */ > @@ -706,7 +730,10 @@ guint > lttv_process_traceset_middle(LttvTracesetContext *self, > /* End of traceset : tfc is NULL */ > if(unlikely(tfc == NULL)) > { > - return count; > + if(isStreaming) > + return tracefile_counter == 0 ? 0 : -1; > + else > + return count; > } > > /* Have we reached : > @@ -723,7 +750,10 @@ guint > lttv_process_traceset_middle(LttvTracesetContext *self, > end_position) == 0) > || ltt_time_compare(end, tfc->timestamp) <= 0)) > { > - return count; > + if(isStreaming) > + return tracefile_counter == 0 ? 0 : -1; > + else > + return count; > } > > /* Get the tracefile with an event for the smallest time found. > If two > @@ -814,6 +844,125 @@ void lttv_process_traceset_end(LttvTracesetContext > *self, > event_by_id_channel); > } > > +#ifdef HAS_INOTIFY > +/**************************************************************************** > + * lttv_process_trace_update > + * > + * process the changes that occur in the trace. Use Inotify System Call to > + * monitor the tracefile. > + * > + * Return the number of file presently monitor. If 0, the current trace > probably > + * received all the data. > + > ***************************************************************************/ > +guint lttv_process_trace_update(LttvTraceContext *self) > +{ > + > + guint i, j, nb_tracefile; > + > + gint ret; > + > + LttvTracefileContext **tfc; > + > + LttTrace *t = self->t; > + > + if(t == NULL) > + printf("the trace is NULL\n"); > + > + 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); > + > + } > + > + int offset = 0; declarations after code is to be avoided. Please check compiler warnings. > + char buf[sizeof(struct inotify_event) + PATH_MAX]; > + int len = read(t->inotify_fd, buf, sizeof(struct inotify_event) + > PATH_MAX); > + while(offset < len) { > + struct inotify_event * ievent = (struct inotify_event > *)&(buf[offset]); > + for(i=0; i< t->inotify_watch_array.num; i++) { > + if (t->inotify_watch_array.elem[i].wd == ievent->wd) { > + if ( ievent->mask & IN_ISDIR ) > + { > + open_tracefiles( t, g_quark_to_string(t->pathname), > ievent->name); > + } > + else > + { > + if(ievent->mask & IN_OPEN) > + { > + t->open_tracefile_counter++; > + break; > + } > + else if(ievent->mask & IN_CLOSE_WRITE) > + { > + > + t->open_tracefile_counter--; > + } > + else if(ievent->mask & IN_MODIFY) > + { > + (*tfc) = NULL; > + for(j = 0; j < self->tracefiles->len; j++) > + { > + tfc = &g_array_index(self->tracefiles, > LttvTracefileContext*, j); > + if((*tfc)->tf->name == > t->inotify_watch_array.elem[i].name && (*tfc)->tf->cpu_num == > t->inotify_watch_array.elem[i].num) > + break; > + } > + ret = ltt_tracefile_update((*tfc)->tf, t); > + if(ret == 0) > + { > + (*tfc)->timestamp = > ltt_event_time(ltt_tracefile_get_event((*tfc)->tf)); > + g_tree_insert(pqueue, (*tfc), (*tfc)); > + } > + } > + } > + break; > + } > + } > + offset += sizeof(*ievent) + ievent->len; > + } > + return t->open_tracefile_counter; > +} > +#else > + > /**************************************************************************** > + * lttv_process_trace_update > + * > + * process the changes that occur in the trace. Use a regular file > polling to > + * monitor the tracefile. > + * > + * Return 1 if a tracefile has been updated, 0 otherwise > + > ***************************************************************************/ > + guint lttv_process_trace_update(LttvTraceContext *self) > + { > + guint i, nb_tracefile; > + > + gint ret; > + > + LttvTracefileContext **tfc; > + > + 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); > + > + ret = ltt_tracefile_update((*tfc)->tf); > + if(ret == 1) > + { > + (*tfc)->timestamp = > ltt_event_time(ltt_tracefile_get_event((*tfc)->tf)); > + g_tree_insert(pqueue, (*tfc), (*tfc)); > + > + } > + } > + return nb_tracefile; > + } > +#endif > /* 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. > @@ -857,6 +1006,31 @@ void lttv_process_trace_seek_time(LttvTraceContext > *self, LttTime start) > } > > > +/**************************************************************************** > + * 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. > + * > + * Author : Oussama El Mfadli > + > ***************************************************************************/ > +guint lttv_process_traceset_update(LttvTracesetContext *self) > +{ > + guint i, nb_trace, open_counter ; > + > + LttvTraceContext *tc; > + > + nb_trace = lttv_traceset_number(self->ts); > + open_counter = 0; > + for(i = 0 ; i < nb_trace ; i++) { > + tc = self->traces[i]; > + open_counter += lttv_process_trace_update(tc); > + } > + return open_counter; > +} > + > void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime > start) > { > guint i, nb_trace; > diff --git a/lttv/lttv/tracecontext.h b/lttv/lttv/tracecontext.h > index acedeea..e36cec5 100644 > --- a/lttv/lttv/tracecontext.h > +++ b/lttv/lttv/tracecontext.h > @@ -212,14 +212,15 @@ guint > lttv_process_traceset_middle(LttvTracesetContext *self, > LttTime end, > gulong nb_events, > const LttvTracesetContextPosition *end_position); > - > + whitespace ? > void lttv_process_traceset_end(LttvTracesetContext *self, > LttvHooks *after_traceset, > LttvHooks *after_trace, > LttvHooks *after_tracefile, > LttvHooks *event, > LttvHooksByIdChannelArray *event_by_id_channel); > - > + again? > +guint lttv_process_traceset_update(LttvTracesetContext *self); > > void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime > start); > > @@ -229,6 +230,8 @@ void > lttv_traceset_context_compute_time_span(LttvTracesetContext *self, > gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self, > const LttvTracesetContextPosition *pos); > > +guint lttv_process_trace_update(LttvTraceContext *self); > + > void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start); > > void lttv_traceset_context_add_hooks(LttvTracesetContext *self, > diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c > b/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c > index d58c313..3db0749 100644 > --- a/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c > +++ b/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c > @@ -1869,7 +1869,7 @@ void add_trace(GtkWidget * widget, gpointer user_data) > get_absolute_pathname(dir, abs_path); > trace_v = lttvwindowtraces_get_trace_by_name(abs_path); > if(trace_v == NULL) { > - trace = ltt_trace_open(abs_path); > + trace = ltt_trace_open(abs_path, NO_FLAG); > if(trace == NULL) { > g_warning("cannot open trace %s", abs_path); > > @@ -4969,7 +4969,7 @@ __EXPORT void > create_main_window_with_trace_list(GSList *traces) > get_absolute_pathname(path, abs_path); > trace_v = lttvwindowtraces_get_trace_by_name(abs_path); > if(trace_v == NULL) { > - trace = ltt_trace_open(abs_path); > + trace = ltt_trace_open(abs_path, NO_FLAG); > if(trace == NULL) { > g_warning("cannot open trace %s", abs_path); > > diff --git a/lttv/modules/text/batchAnalysis.c > b/lttv/modules/text/batchAnalysis.c > index 4b02f33..1647598 100644 > --- a/lttv/modules/text/batchAnalysis.c > +++ b/lttv/modules/text/batchAnalysis.c > @@ -49,14 +49,17 @@ static LttvHooks > *main_hooks; > > static char *a_trace; > - > +static gboolean a_streaming; > static gboolean a_stats; > > void lttv_trace_option(void *hook_data) > { > LttTrace *trace; > > - trace = ltt_trace_open(a_trace); > + unsigned int flag = NO_FLAG; > + if( a_streaming ) > + flag |= TRACE_STREAMING; > + trace = ltt_trace_open(a_trace, flag); > if(trace == NULL) g_critical("cannot open trace %s", a_trace); > lttv_traceset_add(traceset, lttv_trace_new(trace)); > } > @@ -138,8 +141,18 @@ static gboolean process_traceset(void *hook_data, > void *call_data) > end, > G_MAXULONG, > NULL); > - > - > + if(a_streaming == TRUE) > + { > + gint tracefile_counter = -1; > + while(tracefile_counter != 0) > + { > + tracefile_counter = lttv_process_traceset_middle(tc, > + end, > + G_MAXULONG, > + NULL); odd alignment ? Thanks, Mathieu > + > + } > + } > //lttv_traceset_context_remove_hooks(tc, > //before_traceset, after_traceset, NULL, before_trace, after_trace, > //NULL, before_tracefile, after_tracefile, NULL, before_event, > after_event); > @@ -186,6 +199,11 @@ static void init() > "", > LTTV_OPT_NONE, &a_stats, NULL, NULL); > > + a_streaming = FALSE; > + lttv_option_add("streaming", 'S', > + "define if the traceset is receiving streamed informations", > + "", > + LTTV_OPT_NONE, &a_streaming, NULL, NULL); > > traceset = lttv_traceset_new(); > > @@ -251,6 +269,7 @@ static void destroy() > > lttv_option_remove("trace"); > lttv_option_remove("stats"); > + lttv_option_remove("streaming"); > > lttv_hooks_destroy(before_traceset); > lttv_hooks_destroy(after_traceset); > -- > 1.7.0.4 > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com