Mirror of the lttng-dev mailing list
 help / color / mirror / Atom feed
* [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.
@ 2010-08-27 17:11 Oussama El Mfadli
  0 siblings, 0 replies; 5+ messages in thread
From: Oussama El Mfadli @ 2010-08-27 17:11 UTC (permalink / raw)


  Add Support to lttv to analyse streaming trace.
  Currently, only the textDump module support the streaming traces 
(option -S), but all the tools
  are in place for the other modules.

---
  lttv/lttv/tracecontext.c          |  136 
+++++++++++++++++++++++++++++++++++++
  lttv/lttv/tracecontext.h          |   14 +++-
  lttv/modules/text/batchAnalysis.c |   24 ++++++-
  3 files changed, 168 insertions(+), 6 deletions(-)

diff --git a/lttv/lttv/tracecontext.c b/lttv/lttv/tracecontext.c
index 136b2ee..9f50859 100644
--- a/lttv/lttv/tracecontext.c
+++ b/lttv/lttv/tracecontext.c
@@ -28,6 +28,11 @@
  #include <lttv/filter.h>
  #include <errno.h>

+#include <linux/limits.h>
+#include <sys/inotify.h>
+#include <stdlib.h>
+#include <unistd.h>
+
  gint compare_tracefile(gconstpointer a, gconstpointer b)
  {
      gint comparison = 0;
@@ -675,6 +680,28 @@ void 
lttv_process_traceset_begin(LttvTracesetContext *self,

  //enum read_state { LAST_NONE, LAST_OK, LAST_EMPTY };

+/****************************************************************************
+ * lttv_process_traceset_middle_streaming
+ *
+ * This function should be called periodacly to retreive the new 
informations
+ * that were added in the tracefile since the last call.
+ * It will also process them.
+ *
+ * Return the number of file presently monitor. If 0, the current trace 
probably
+ * received all the data.
+ *
+ * Author : Oussama El Mfadli
+ 
***************************************************************************/
+guint lttv_process_traceset_middle_streaming(LttvTracesetContext *self,
+        LttTime end,
+        gulong nb_events,
+        const LttvTracesetContextPosition *end_position)
+{
+    guint tracefile_counter = lttv_process_traceset_update(self);
+    lttv_process_traceset_middle(self, end, nb_events, end_position);
+    return tracefile_counter;
+}
+
  /* Note : a _middle must be preceded from a _seek or another middle */
  guint lttv_process_traceset_middle(LttvTracesetContext *self,
          LttTime end,
@@ -814,6 +841,90 @@ void lttv_process_traceset_end(LttvTracesetContext 
*self,
              event_by_id_channel);
  }

+/****************************************************************************
+ * 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.
+ *
+ * Author : Oussama El Mfadli
+ 
***************************************************************************/
+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;
+    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 )
+            {
+              ltt_tracefile_add_streaming( 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;
+}
+
  /* 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 +968,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..57b85e7 100644
--- a/lttv/lttv/tracecontext.h
+++ b/lttv/lttv/tracecontext.h
@@ -212,14 +212,22 @@ guint 
lttv_process_traceset_middle(LttvTracesetContext *self,
          LttTime end,
          gulong nb_events,
          const LttvTracesetContextPosition *end_position);
-
+
+
+guint lttv_process_traceset_middle_streaming(LttvTracesetContext *self,
+        LttTime end,
+        gulong nb_events,
+        const LttvTracesetContextPosition *end_position);
+
+
  void lttv_process_traceset_end(LttvTracesetContext *self,
          LttvHooks *after_traceset,
          LttvHooks *after_trace,
          LttvHooks *after_tracefile,
          LttvHooks *event,
          LttvHooksByIdChannelArray *event_by_id_channel);
-
+
+guint lttv_process_traceset_update(LttvTracesetContext *self);

  void lttv_process_traceset_seek_time(LttvTracesetContext *self, 
LttTime start);

@@ -229,6 +237,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/text/batchAnalysis.c 
b/lttv/modules/text/batchAnalysis.c
index 4b02f33..39448f1 100644
--- a/lttv/modules/text/batchAnalysis.c
+++ b/lttv/modules/text/batchAnalysis.c
@@ -49,14 +49,14 @@ 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);
+  trace = ltt_trace_open_streaming(a_trace, a_streaming);
    if(trace == NULL) g_critical("cannot open trace %s", a_trace);
    lttv_traceset_add(traceset, lttv_trace_new(trace));
  }
@@ -138,8 +138,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_streaming(tc,
+                                   end,
+                                   G_MAXULONG,
+                                       NULL);
+
+     }
+  }
    //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 +196,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 +266,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




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.
  2010-08-28  0:30     ` Oussama El Mfadli
@ 2010-09-11 16:34       ` Mathieu Desnoyers
  0 siblings, 0 replies; 5+ messages in thread
From: Mathieu Desnoyers @ 2010-09-11 16:34 UTC (permalink / raw)


* 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




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.
  2010-08-27 17:29   ` Mathieu Desnoyers
@ 2010-08-28  0:30     ` Oussama El Mfadli
  2010-09-11 16:34       ` Mathieu Desnoyers
  0 siblings, 1 reply; 5+ messages in thread
From: Oussama El Mfadli @ 2010-08-28  0:30 UTC (permalink / raw)


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);
      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
+
  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;
+
+    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;
+    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);
-
+
  void lttv_process_traceset_end(LttvTracesetContext *self,
          LttvHooks *after_traceset,
          LttvHooks *after_trace,
          LttvHooks *after_tracefile,
          LttvHooks *event,
          LttvHooksByIdChannelArray *event_by_id_channel);
-
+
+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);
+
+     }
+  }
    //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




^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.
  2010-08-27 16:36 ` Oussama El Mfadli
@ 2010-08-27 17:29   ` Mathieu Desnoyers
  2010-08-28  0:30     ` Oussama El Mfadli
  0 siblings, 1 reply; 5+ messages in thread
From: Mathieu Desnoyers @ 2010-08-27 17:29 UTC (permalink / raw)


* Oussama El Mfadli (oussama.el-mfadli at polymtl.ca) wrote:
>  Add Support to lttv to analyse streaming trace.
>  Currently, only the textDump module support the streaming traces, but all the tools
>  are in place for the other modules.
> 
> ---
>  lttv/lttv/tracecontext.c          |  136 +++++++++++++++++++++++++++++++++++++
>  lttv/lttv/tracecontext.h          |   14 +++-
>  lttv/modules/text/batchAnalysis.c |   24 ++++++-
>  3 files changed, 168 insertions(+), 6 deletions(-)
> 
> diff --git a/lttv/lttv/tracecontext.c b/lttv/lttv/tracecontext.c
> index 136b2ee..9f50859 100644
> --- a/lttv/lttv/tracecontext.c
> +++ b/lttv/lttv/tracecontext.c
> @@ -28,6 +28,11 @@
>  #include <lttv/filter.h>
>  #include <errno.h>
>  
> +#include <linux/limits.h>

We should include <limits.h> for portability.

> +#include <sys/inotify.h>

See the lttd code for:

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)

and fallback on a timer-based scheme if inotify is not available.

> +#include <stdlib.h>
> +#include <unistd.h>

Since the project is using glib, then we should not rely directly on
stdlib.h and unistd.h, but rather use the glib wrappers (e.g. g_printf()
etc etc).

> +
>  gint compare_tracefile(gconstpointer a, gconstpointer b)
>  {
>  	gint comparison = 0;
> @@ -675,6 +680,28 @@ void lttv_process_traceset_begin(LttvTracesetContext *self,
>  
>  //enum read_state { LAST_NONE, LAST_OK, LAST_EMPTY };
>  
> +/****************************************************************************
> + * lttv_process_traceset_middle_streaming
> + *
> + * This function should be called periodacly to retreive the new informations

periodically   retrieve   information

Please enable a basic spell checker in your text editor.

> + * that were added in the tracefile since the last call.
> + * It will also process them.
> + * 
> + * Return the number of file presently monitor. If 0, the current trace probably 

of files   .. currently  ... monitored .. 

What do you mean by "probably" ? So it may, or may not, be reliable ?

> + * received all the data.
> + *
> + * Author : Oussama El Mfadli

We usually put credits at the beginning of the top-of-file header. the
git log will contain information about per-line (and thus per-function)
authors.

> + ***************************************************************************/
> +guint lttv_process_traceset_middle_streaming(LttvTracesetContext *self,
> +		LttTime end,
> +		gulong nb_events,
> +		const LttvTracesetContextPosition *end_position)
> +{
> +	guint tracefile_counter = lttv_process_traceset_update(self);
> +	lttv_process_traceset_middle(self, end, nb_events, end_position);
> +	return tracefile_counter;

So the only difference between this and the standard
lttv_process_traceset_middle is that it explicitly return the number of
tracefiles which may still have information available.
lttv_process_traceset_middle() already provides the "end of trace"
information by returning a count of 0 events.  We could simply modify
lttv_process_traceset_middle() and make it return "-1" if we are about
to return 0 events for a non-finalized streaming trace.

As for the call to lttv_process_traceset_update(), this could be hidden
within lttv_process_traceset_middle with a check for "streaming" trace.

Also, this patch calls lttv_process_traceset_middle_streaming

So, why do we need this new API ?

> +}
> +
>  /* Note : a _middle must be preceded from a _seek or another middle */
>  guint lttv_process_traceset_middle(LttvTracesetContext *self,
>  		LttTime end,
> @@ -814,6 +841,90 @@ void lttv_process_traceset_end(LttvTracesetContext *self,
>  			event_by_id_channel);
>  }
>  
> +/****************************************************************************
> + * lttv_process_trace_update
> + *
> + * process the changes that occur in the trace. Use Inotify System Call to 

Process

> + * monitor the tracefile.

tracefiles

> + * 
> + * Return the number of file presently monitor. If 0, the current trace probably 

files .. currently .. monitored

> + * received all the data.
> + *
> + * Author : Oussama El Mfadli
> + ***************************************************************************/
> +guint lttv_process_trace_update(LttvTraceContext *self)

How do you deal with the fact that, when lttv_process_trace_update() is
called here, we're within "lttv_process_traceset_middle" in a context
where we already called

lttv_process_traceset_begin

which already added the hook lists to the list of hooks that should be
called when reading events. How do you update this hook list when new
markers are detected ?

It might not be much of a problem for the text dump because we only use
"main" hooks, but lttv_process_traceset_middle is also used with
per-event hook lists, and these are set at lttv_process_traceset_begin.
So I fear your new API does not fit at the right location.

Thanks,

Mathieu

> +{
> +  
> +	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;
> +	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 )
> +		    {
> +		      ltt_tracefile_add_streaming( 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;
> +}
> +
>  /* 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 +968,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..57b85e7 100644
> --- a/lttv/lttv/tracecontext.h
> +++ b/lttv/lttv/tracecontext.h
> @@ -212,14 +212,22 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
>  		LttTime end,
>  		gulong nb_events,
>  		const LttvTracesetContextPosition *end_position);
> -
> +		
> +		
> +guint lttv_process_traceset_middle_streaming(LttvTracesetContext *self,
> +		LttTime end,
> +		gulong nb_events,
> +		const LttvTracesetContextPosition *end_position);
> +		
> +		
>  void lttv_process_traceset_end(LttvTracesetContext *self,
>  		LttvHooks *after_traceset,
>  		LttvHooks *after_trace,
>  		LttvHooks *after_tracefile,
>  		LttvHooks *event,
>  		LttvHooksByIdChannelArray *event_by_id_channel);
> -
> +		
> +guint lttv_process_traceset_update(LttvTracesetContext *self);
>  
>  void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start);
>  
> @@ -229,6 +237,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/text/batchAnalysis.c b/lttv/modules/text/batchAnalysis.c
> index 4b02f33..39448f1 100644
> --- a/lttv/modules/text/batchAnalysis.c
> +++ b/lttv/modules/text/batchAnalysis.c
> @@ -49,14 +49,14 @@ 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);
> +  trace = ltt_trace_open_streaming(a_trace, a_streaming);
>    if(trace == NULL) g_critical("cannot open trace %s", a_trace);
>    lttv_traceset_add(traceset, lttv_trace_new(trace));
>  }
> @@ -138,8 +138,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_streaming(tc,
> +                	               end,
> +                        	       G_MAXULONG,
> +                            	   	NULL);
> +	
> +	 }
> +  }	
>    //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 +196,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 +266,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
> 
> 
> _______________________________________________
> ltt-dev mailing list
> ltt-dev at lists.casi.polymtl.ca
> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
> 

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.
       [not found] <Oussama El Mfadli>
@ 2010-08-27 16:36 ` Oussama El Mfadli
  2010-08-27 17:29   ` Mathieu Desnoyers
  0 siblings, 1 reply; 5+ messages in thread
From: Oussama El Mfadli @ 2010-08-27 16:36 UTC (permalink / raw)


 Add Support to lttv to analyse streaming trace.
 Currently, only the textDump module support the streaming traces, but all the tools
 are in place for the other modules.

---
 lttv/lttv/tracecontext.c          |  136 +++++++++++++++++++++++++++++++++++++
 lttv/lttv/tracecontext.h          |   14 +++-
 lttv/modules/text/batchAnalysis.c |   24 ++++++-
 3 files changed, 168 insertions(+), 6 deletions(-)

diff --git a/lttv/lttv/tracecontext.c b/lttv/lttv/tracecontext.c
index 136b2ee..9f50859 100644
--- a/lttv/lttv/tracecontext.c
+++ b/lttv/lttv/tracecontext.c
@@ -28,6 +28,11 @@
 #include <lttv/filter.h>
 #include <errno.h>
 
+#include <linux/limits.h>
+#include <sys/inotify.h>
+#include <stdlib.h>
+#include <unistd.h>
+
 gint compare_tracefile(gconstpointer a, gconstpointer b)
 {
 	gint comparison = 0;
@@ -675,6 +680,28 @@ void lttv_process_traceset_begin(LttvTracesetContext *self,
 
 //enum read_state { LAST_NONE, LAST_OK, LAST_EMPTY };
 
+/****************************************************************************
+ * lttv_process_traceset_middle_streaming
+ *
+ * This function should be called periodacly to retreive the new informations
+ * that were added in the tracefile since the last call.
+ * It will also process them.
+ * 
+ * Return the number of file presently monitor. If 0, the current trace probably 
+ * received all the data.
+ *
+ * Author : Oussama El Mfadli
+ ***************************************************************************/
+guint lttv_process_traceset_middle_streaming(LttvTracesetContext *self,
+		LttTime end,
+		gulong nb_events,
+		const LttvTracesetContextPosition *end_position)
+{
+	guint tracefile_counter = lttv_process_traceset_update(self);
+	lttv_process_traceset_middle(self, end, nb_events, end_position);
+	return tracefile_counter;
+}
+
 /* Note : a _middle must be preceded from a _seek or another middle */
 guint lttv_process_traceset_middle(LttvTracesetContext *self,
 		LttTime end,
@@ -814,6 +841,90 @@ void lttv_process_traceset_end(LttvTracesetContext *self,
 			event_by_id_channel);
 }
 
+/****************************************************************************
+ * 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.
+ *
+ * Author : Oussama El Mfadli
+ ***************************************************************************/
+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;
+	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 )
+		    {
+		      ltt_tracefile_add_streaming( 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;
+}
+
 /* 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 +968,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..57b85e7 100644
--- a/lttv/lttv/tracecontext.h
+++ b/lttv/lttv/tracecontext.h
@@ -212,14 +212,22 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
 		LttTime end,
 		gulong nb_events,
 		const LttvTracesetContextPosition *end_position);
-
+		
+		
+guint lttv_process_traceset_middle_streaming(LttvTracesetContext *self,
+		LttTime end,
+		gulong nb_events,
+		const LttvTracesetContextPosition *end_position);
+		
+		
 void lttv_process_traceset_end(LttvTracesetContext *self,
 		LttvHooks *after_traceset,
 		LttvHooks *after_trace,
 		LttvHooks *after_tracefile,
 		LttvHooks *event,
 		LttvHooksByIdChannelArray *event_by_id_channel);
-
+		
+guint lttv_process_traceset_update(LttvTracesetContext *self);
 
 void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start);
 
@@ -229,6 +237,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/text/batchAnalysis.c b/lttv/modules/text/batchAnalysis.c
index 4b02f33..39448f1 100644
--- a/lttv/modules/text/batchAnalysis.c
+++ b/lttv/modules/text/batchAnalysis.c
@@ -49,14 +49,14 @@ 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);
+  trace = ltt_trace_open_streaming(a_trace, a_streaming);
   if(trace == NULL) g_critical("cannot open trace %s", a_trace);
   lttv_traceset_add(traceset, lttv_trace_new(trace));
 }
@@ -138,8 +138,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_streaming(tc,
+                	               end,
+                        	       G_MAXULONG,
+                            	   	NULL);
+	
+	 }
+  }	
   //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 +196,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 +266,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




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-09-11 16:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-27 17:11 [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace Oussama El Mfadli
     [not found] <Oussama El Mfadli>
2010-08-27 16:36 ` Oussama El Mfadli
2010-08-27 17:29   ` Mathieu Desnoyers
2010-08-28  0:30     ` Oussama El Mfadli
2010-09-11 16:34       ` Mathieu Desnoyers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox