[ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.

Mathieu Desnoyers compudj at krystal.dyndns.org
Sat Sep 11 12:34:12 EDT 2010


* 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 <lttv/filter.h>
>  #include <errno.h>
>
> +#include <limits.h>
> +
> +#include <linux/version.h>
> +
> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
> +#include <sys/inotify.h>
> +#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




More information about the lttng-dev mailing list