From: oussama.el-mfadli@polymtl.ca (Oussama El Mfadli)
Subject: [ltt-dev] [PATCH 2/2] Add Support to lttv to analyse streaming trace.
Date: Fri, 27 Aug 2010 20:30:56 -0400 [thread overview]
Message-ID: <4C7858C0.1020602@polymtl.ca> (raw)
In-Reply-To: <20100827172945.GA30338@Krystal>
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
next prev parent reply other threads:[~2010-08-28 0:30 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[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 [this message]
2010-09-11 16:34 ` Mathieu Desnoyers
2010-08-27 17:11 Oussama El Mfadli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C7858C0.1020602@polymtl.ca \
--to=oussama.el-mfadli@polymtl.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox