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

Oussama El Mfadli oussama.el-mfadli at polymtl.ca
Fri Oct 1 20:59:48 EDT 2010


The modification have been made. Dont hesitation to give other feed-back.
Thanks

Oussama
the patch is next:

---
 ltt/trace.h                                        |    1 -
 ltt/tracefile.c                                    |    2 +-
 lttv/lttv/batchtest.c                              |    2 +-
 lttv/lttv/tracecontext.c                           |  180
+++++++++++++++++++-
 lttv/lttv/tracecontext.h                           |    3 +
 lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c |    4 +-
 lttv/modules/text/batchAnalysis.c                  |   27 +++-
 7 files changed, 206 insertions(+), 13 deletions(-)

diff --git a/ltt/trace.h b/ltt/trace.h
index a1503d3..a580ced 100644
--- a/ltt/trace.h
+++ b/ltt/trace.h
@@ -31,7 +31,6 @@
 #include <linux/version.h>

 //Options used to open a trace
-#define NO_FLAG 0
 #define TRACE_STREAMING (1 << 0)

 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
diff --git a/ltt/tracefile.c b/ltt/tracefile.c
index 607ca7c..b78ff47 100644
--- a/ltt/tracefile.c
+++ b/ltt/tracefile.c
@@ -1152,7 +1152,7 @@ alloc_error:
  */
 LttTrace *ltt_trace_copy(LttTrace *self)
 {
-  unsigned int flag = NO_FLAG;
+  unsigned int flag = 0;
   if(self->streaming_is_enable)
     flag |= TRACE_STREAMING;
   return ltt_trace_open(g_quark_to_string(self->pathname), flag);
diff --git a/lttv/lttv/batchtest.c b/lttv/lttv/batchtest.c
index 08b892b..7f093b1 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, 0);
  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..8aa69cb 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,22 @@ 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 +729,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 +749,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 +843,124 @@ 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;
+ int offset = 0;
+ 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);
+
+ }
+
+ 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 +1004,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..95dc345 100644
--- a/lttv/lttv/tracecontext.h
+++ b/lttv/lttv/tracecontext.h
@@ -220,6 +220,7 @@ void lttv_process_traceset_end(LttvTracesetContext
*self,
  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..fd83fe7 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, 0);
         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, 0);
       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..22ce389 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 = 0;
+  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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.casi.polymtl.ca/pipermail/lttng-dev/attachments/20101001/9fa099c9/attachment-0003.htm>


More information about the lttng-dev mailing list