* [ltt-dev] [LTTV PATCH 2/3] Add live trace read support to lttv base library and to command line modules
2011-04-21 20:52 [ltt-dev] [LTTV PATCH 1/3] Add live trace reading support to lttvtraceread lib Yannick Brosseau
@ 2011-04-21 20:52 ` Yannick Brosseau
2011-04-21 20:52 ` [ltt-dev] [LTTV PATCH 3/3] Add live trace support to LTTV GUI Yannick Brosseau
1 sibling, 0 replies; 3+ messages in thread
From: Yannick Brosseau @ 2011-04-21 20:52 UTC (permalink / raw)
Change process_traceset_middle to handle live traces
Add lttv_process_trace_update to manage trace update
Add parameter to batchanalysis to indicate a live trace and its update period
-When activating the live option of the batchAnalysis module, the trace processing will loop. In each loop, it will
wait for the specified period, update the trace and then read the added events.
Signed-off-by: Yannick Brosseau <yannick.brosseau at gmail.com>
---
lttv/lttv/batchtest.c | 2 +-
lttv/lttv/tracecontext.c | 95 +++++++++++++++++++++++++++++++++++-
lttv/lttv/tracecontext.h | 2 +
lttv/modules/text/batchAnalysis.c | 40 ++++++++++++++--
4 files changed, 130 insertions(+), 9 deletions(-)
diff --git a/lttv/lttv/batchtest.c b/lttv/lttv/batchtest.c
index 08b892b..fd4a218 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, FALSE);
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..45a810d 100644
--- a/lttv/lttv/tracecontext.c
+++ b/lttv/lttv/tracecontext.c
@@ -27,6 +27,7 @@
#include <ltt/trace.h>
#include <lttv/filter.h>
#include <errno.h>
+#include <ltt/time.h>
gint compare_tracefile(gconstpointer a, gconstpointer b)
{
@@ -689,6 +690,8 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
unsigned count = 0;
+ gboolean is_live = FALSE; /* set this flag if we detect a live trace */
+
guint read_ret;
//enum read_state last_read_state = LAST_NONE;
@@ -706,7 +709,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
/* End of traceset : tfc is NULL */
if(unlikely(tfc == NULL))
{
- return count;
+ break;
}
/* Have we reached :
@@ -723,7 +726,7 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
end_position) == 0)
|| ltt_time_compare(end, tfc->timestamp) <= 0))
{
- return count;
+ break;
}
/* Get the tracefile with an event for the smallest time found. If two
@@ -765,7 +768,8 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
if(unlikely(last_ret == 2)) {
/* This is a case where we want to stay at this position and stop read. */
g_tree_insert(pqueue, tfc, tfc);
- return count - 1;
+ count--;
+ break;
}
#endif //0
read_ret = ltt_tracefile_read(tfc->tf);
@@ -774,6 +778,12 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
if(likely(!read_ret)) {
//g_debug("An event is ready");
tfc->timestamp = ltt_event_time(e);
+ if(tfc->tf->trace->is_live && ltt_time_compare(tfc->timestamp, tfc->tf->trace->live_safe_timestamp) >= 0)
+ {
+ is_live |= TRUE;
+ break;
+ }
+
g_assert(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0);
g_tree_insert(pqueue, tfc, tfc);
#ifdef DEBUG
@@ -794,6 +804,12 @@ guint lttv_process_traceset_middle(LttvTracesetContext *self,
g_error("Error happened in lttv_process_traceset_middle");
}
}
+
+ if (unlikely(count == 0 && is_live)) {
+ return -1;
+ } else {
+ return count;
+ }
}
@@ -856,6 +872,79 @@ void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
#endif //DEBUG
}
+/****************************************************************************
+ * lttv_process_trace_update
+ *
+ * process the changes that occur in the trace. Use a regular file polling to
+ * monitor the tracefile.
+ *
+ * Return the number of tracefile updated
+ ***************************************************************************/
+guint lttv_process_trace_update(LttvTraceContext *self)
+{
+ guint i;
+ guint nb_tracefile = 0;
+
+ gint ret;
+
+ LttvTracefileContext **tfc;
+
+ /* Skip non live traces */
+ if(self->t->is_live) {
+
+ 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);
+
+ (*tfc)->tf->trace->live_safe_timestamp = LTT_TIME_MAX((*tfc)->tf->trace->live_safe_timestamp,
+ ltt_interpolate_time_from_tsc((*tfc)->tf,
+ (*tfc)->tf->end_timestamp));
+
+ ret = ltt_tracefile_update((*tfc)->tf);
+ if(ret == 1 || ltt_time_compare((*tfc)->timestamp,ltt_time_infinite) != 0)
+ {
+ (*tfc)->timestamp = ltt_event_time(ltt_tracefile_get_event((*tfc)->tf));
+ g_tree_insert(pqueue, (*tfc), (*tfc));
+
+ }
+ }
+ //Update self time span
+ self->time_span.end_time = LTT_TIME_MAX(self->t->live_safe_timestamp,
+ self->time_span.end_time);
+ //Update self tscontext time span
+ self->ts_context->time_span.end_time = LTT_TIME_MAX(self->time_span.end_time,
+ self->ts_context->time_span.end_time);
+ }
+ return nb_tracefile;
+
+}
+
+/****************************************************************************
+ * 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.
+ ***************************************************************************/
+guint lttv_process_traceset_update(LttvTracesetContext *self)
+{
+ guint i;
+ guint nb_trace;
+ guint open_counter = 0;
+
+ nb_trace = lttv_traceset_number(self->ts);
+
+ for(i = 0 ; i < nb_trace ; i++) {
+ open_counter += lttv_process_trace_update(self->traces[i]);
+ }
+ return open_counter;
+}
void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
{
diff --git a/lttv/lttv/tracecontext.h b/lttv/lttv/tracecontext.h
index acedeea..e509811 100644
--- a/lttv/lttv/tracecontext.h
+++ b/lttv/lttv/tracecontext.h
@@ -220,6 +220,8 @@ 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);
diff --git a/lttv/modules/text/batchAnalysis.c b/lttv/modules/text/batchAnalysis.c
index 7d55f44..4a79afb 100644
--- a/lttv/modules/text/batchAnalysis.c
+++ b/lttv/modules/text/batchAnalysis.c
@@ -24,6 +24,7 @@
#endif
#include <glib.h>
+#include <unistd.h>
#include <lttv/lttv.h>
#include <lttv/attribute.h>
#include <lttv/hook.h>
@@ -51,12 +52,16 @@ static LttvHooks
static char *a_trace;
static gboolean a_stats;
+static gboolean a_live;
+static int a_live_update_period;
+
+#define DEFAULT_LIVE_UPDATE_PERIOD 1
void lttv_trace_option(void *hook_data)
{
LttTrace *trace;
- trace = ltt_trace_open(a_trace);
+ trace = ltt_trace_open(a_trace, a_live);
if(trace == NULL) g_critical("cannot open trace %s", a_trace);
lttv_traceset_add(traceset, lttv_trace_new(trace));
}
@@ -134,10 +139,19 @@ static gboolean process_traceset(void *hook_data, void *call_data)
g_info("BatchAnalysis process traceset");
lttv_process_traceset_seek_time(tc, start);
- lttv_process_traceset_middle(tc,
- end,
- G_MAXULONG,
- NULL);
+ /* Read as long a we do not reach the end (0) */
+ unsigned int count;
+ unsigned int updated_count;
+ do {
+ count = lttv_process_traceset_middle(tc,
+ end,
+ G_MAXULONG,
+ NULL);
+
+ updated_count = lttv_process_traceset_update(tc);
+
+ sleep(a_live_update_period);
+ } while(count != 0 || updated_count > 0);
//lttv_traceset_context_remove_hooks(tc,
@@ -186,6 +200,20 @@ static void init()
"",
LTTV_OPT_NONE, &a_stats, NULL, NULL);
+ a_live = FALSE;
+ lttv_option_add("live", 'L',
+ "define if the traceset is receiving live informations",
+ "",
+ LTTV_OPT_NONE, &a_live, NULL, NULL);
+
+ a_live_update_period = DEFAULT_LIVE_UPDATE_PERIOD;
+ lttv_option_add("live-period", 0,
+ "period to update a live trace",
+ "in seconds",
+ LTTV_OPT_INT,
+ &a_live_update_period,
+ NULL, NULL);
+
traceset = lttv_traceset_new();
@@ -251,6 +279,8 @@ static void destroy()
lttv_option_remove("trace");
lttv_option_remove("stats");
+ lttv_option_remove("live");
+ lttv_option_remove("live-period");
lttv_hooks_destroy(before_traceset);
lttv_hooks_destroy(after_traceset);
--
1.7.2.3
^ permalink raw reply [flat|nested] 3+ messages in thread* [ltt-dev] [LTTV PATCH 3/3] Add live trace support to LTTV GUI.
2011-04-21 20:52 [ltt-dev] [LTTV PATCH 1/3] Add live trace reading support to lttvtraceread lib Yannick Brosseau
2011-04-21 20:52 ` [ltt-dev] [LTTV PATCH 2/3] Add live trace read support to lttv base library and to command line modules Yannick Brosseau
@ 2011-04-21 20:52 ` Yannick Brosseau
1 sibling, 0 replies; 3+ messages in thread
From: Yannick Brosseau @ 2011-04-21 20:52 UTC (permalink / raw)
Add an option to the open trace dialog to specify that the trace is to be open in live mode
Update the displays when new events are available in a trace
Disable statistics for live traces
Signed-off-by: Yannick Brosseau <yannick.brosseau at gmail.com>
---
lttv/modules/gui/detailedevents/events.c | 27 +++
lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c | 170 +++++++++++---------
lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h | 2 +-
.../gui/lttvwindow/lttvwindow/init_module.c | 10 +-
.../modules/gui/lttvwindow/lttvwindow/lttvwindow.c | 47 ++++++
.../modules/gui/lttvwindow/lttvwindow/lttvwindow.h | 30 ++++
lttv/modules/gui/lttvwindow/lttvwindow/timeentry.h | 1 -
lttv/modules/gui/statistics/statistics.c | 56 +++++--
lttv/modules/gui/tracecontrol/tracecontrol.c | 3 +-
9 files changed, 258 insertions(+), 88 deletions(-)
diff --git a/lttv/modules/gui/detailedevents/events.c b/lttv/modules/gui/detailedevents/events.c
index 0c1a153..ae749ea 100644
--- a/lttv/modules/gui/detailedevents/events.c
+++ b/lttv/modules/gui/detailedevents/events.c
@@ -99,6 +99,7 @@ gboolean update_current_time(void * hook_data, void * call_data);
gboolean update_current_position(void * hook_data, void * call_data);
//gboolean show_event_detail(void * hook_data, void * call_data);
gboolean traceset_changed(void * hook_data, void * call_data);
+gboolean timespan_changed(void * hook_data, void * call_data);
gboolean filter_changed(void * hook_data, void * call_data);
static void request_background_data(EventViewerData *event_viewer_data);
@@ -211,6 +212,8 @@ gui_events(LttvPluginTab *ptab)
update_current_position,event_viewer_data);
lttvwindow_register_traceset_notify(tab,
traceset_changed,event_viewer_data);
+ lttvwindow_register_time_span_notify(tab,
+ timespan_changed,event_viewer_data);
lttvwindow_register_filter_notify(tab,
filter_changed, event_viewer_data);
lttvwindow_register_redraw_notify(tab,
@@ -449,12 +452,14 @@ gui_events(LttvPluginTab *ptab)
g_signal_connect (G_OBJECT (event_viewer_data->vadjust_c), "value-changed",
G_CALLBACK (v_scroll_cb),
event_viewer_data);
+ //TODO ybrosseau 2011-01-06: Fix comment
/* Set the upper bound to the last event number */
event_viewer_data->previous_value = 0;
event_viewer_data->vadjust_c->lower = 0.0;
//event_viewer_data->vadjust_c->upper = event_viewer_data->number_of_events;
LttTime time = lttvwindow_get_current_time(tab);
time = ltt_time_sub(time, tsc->time_span.start_time);
+ //TODO ybrosseau 2011-01-06: Which one do we keep?
event_viewer_data->vadjust_c->value = ltt_time_to_double(time);
event_viewer_data->vadjust_c->value = 0.0;
event_viewer_data->vadjust_c->step_increment = 1.0;
@@ -1769,7 +1774,27 @@ gboolean update_current_position(void * hook_data, void * call_data)
return FALSE;
}
+gboolean timespan_changed(void * hook_data, void * call_data)
+{
+ EventViewerData *event_viewer_data = (EventViewerData*) hook_data;
+ LttvTracesetContext * tsc =
+ lttvwindow_get_traceset_context(event_viewer_data->tab);
+ TimeInterval time_span = tsc->time_span;
+
+ LttTime end;
+ end = ltt_time_sub(time_span.end_time, time_span.start_time);
+ event_viewer_data->vadjust_c->upper = ltt_time_to_double(end);
+
+ if(event_viewer_data->pos->len < event_viewer_data->num_visible_events ) {
+
+
+ get_events(event_viewer_data->vadjust_c->value, event_viewer_data);
+
+ request_background_data(event_viewer_data);
+ }
+ return FALSE;
+}
gboolean traceset_changed(void * hook_data, void * call_data)
{
@@ -1863,6 +1888,8 @@ void gui_events_free(gpointer data)
// show_event_detail, event_viewer_data);
lttvwindow_unregister_traceset_notify(tab,
traceset_changed, event_viewer_data);
+ lttvwindow_unregister_time_span_notify(tab,
+ timespan_changed,event_viewer_data);
lttvwindow_unregister_filter_notify(tab,
filter_changed, event_viewer_data);
lttvwindow_unregister_redraw_notify(tab,
diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c b/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c
index d2e397f..b185edf 100644
--- a/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c
+++ b/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.c
@@ -101,7 +101,6 @@ enum
};
-
#if 0
static void on_top_notify(GObject *gobject,
GParamSpec *arg1,
@@ -303,71 +302,8 @@ int SetTraceset(Tab * tab, LttvTraceset *traceset)
new_time_window.time_width) ;
}
-
-
-#if 0
- /* Set scrollbar */
- GtkAdjustment *adjustment = gtk_range_get_adjustment(GTK_RANGE(tab->scrollbar));
- LttTime upper = ltt_time_sub(time_span.end_time, time_span.start_time);
-
- g_object_set(G_OBJECT(adjustment),
- "lower",
- 0.0, /* lower */
- "upper",
- ltt_time_to_double(upper)
- * NANOSECONDS_PER_SECOND, /* upper */
- "step_increment",
- ltt_time_to_double(tab->time_window.time_width)
- / SCROLL_STEP_PER_PAGE
- * NANOSECONDS_PER_SECOND, /* step increment */
- "page_increment",
- ltt_time_to_double(tab->time_window.time_width)
- * NANOSECONDS_PER_SECOND, /* page increment */
- "page_size",
- ltt_time_to_double(tab->time_window.time_width)
- * NANOSECONDS_PER_SECOND, /* page size */
- NULL);
- gtk_adjustment_changed(adjustment);
-
- g_object_set(G_OBJECT(adjustment),
- "value",
- ltt_time_to_double(
- ltt_time_sub(tab->time_window.start_time, time_span.start_time))
- * NANOSECONDS_PER_SECOND, /* value */
- NULL);
- gtk_adjustment_value_changed(adjustment);
-
- /* set the time bar. The value callbacks will change their nsec themself */
- /* start seconds */
- gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry1),
- (double)time_span.start_time.tv_sec,
- (double)time_span.end_time.tv_sec);
-
- /* end seconds */
- gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry3),
- (double)time_span.start_time.tv_sec,
- (double)time_span.end_time.tv_sec);
-
- /* current seconds */
- gtk_spin_button_set_range(GTK_SPIN_BUTTON(tab->MEntry5),
- (double)time_span.start_time.tv_sec,
- (double)time_span.end_time.tv_sec);
-#endif //0
-
/* Finally, call the update hooks of the viewers */
- LttvHooks * tmp;
- LttvAttributeValue value;
- gint retval = 0;
-
- retval= lttv_iattribute_find_by_path(tab->attributes,
- "hooks/updatetraceset", LTTV_POINTER, &value);
- g_assert(retval);
-
- tmp = (LttvHooks*)*(value.v_pointer);
- if(tmp == NULL)
- retval = 1;
- else
- lttv_hooks_call(tmp,traceset);
+ gint retval = update_traceset(tab,traceset);
time_change_manager(tab, new_time_window);
current_time_change_manager(tab, new_current_time);
@@ -408,20 +344,48 @@ int SetFilter(Tab * tab, gpointer filter)
* @param tab viewer's tab
*/
-void update_traceset(Tab *tab)
+int update_traceset(Tab *tab, LttvTraceset *traceset)
{
LttvAttributeValue value;
LttvHooks * tmp;
gboolean retval;
retval= lttv_iattribute_find_by_path(tab->attributes,
- "hooks/updatetraceset", LTTV_POINTER, &value);
+ "hooks/updatetraceset",
+ LTTV_POINTER,
+ &value);
g_assert(retval);
tmp = (LttvHooks*)*(value.v_pointer);
- if(tmp == NULL) return;
- lttv_hooks_call(tmp, NULL);
+ if(tmp == NULL) {
+ retval = 1;
+ } else {
+ lttv_hooks_call(tmp, traceset);
+ }
+ return retval;
}
+/**
+ Call hooks register to get update on traceset time span changes
+*/
+int notify_time_span_changed(Tab *tab)
+{
+ LttvAttributeValue value;
+ LttvHooks * tmp;
+ gboolean retval;
+
+ retval= lttv_iattribute_find_by_path(tab->attributes,
+ "hooks/updatetimespan",
+ LTTV_POINTER,
+ &value);
+ g_assert(retval);
+ tmp = (LttvHooks*)*(value.v_pointer);
+ if(tmp == NULL) {
+ retval = 1;
+ } else {
+ lttv_hooks_call(tmp, NULL);
+ }
+ return retval;
+}
/* get_label function is used to get user input, it displays an input
* box, which allows user to input a string
@@ -1506,7 +1470,49 @@ gboolean lttvwindow_process_pending_requests(Tab *tab)
}
#undef list_out
+/**
+ Manage the periodic update of a live trace
+*/
+static gboolean
+live_trace_update_handler(Tab *tab)
+{
+ unsigned int updated_count;
+
+ LttvTracesetContext *tsc = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context);
+ TimeInterval initial_time_span = tsc->time_span;
+ TimeInterval updated_time_span;
+
+ updated_count = lttv_process_traceset_update(tsc);
+
+ /* TODO ybrosseau 2011-01-12: Add trace resynchronization */
+
+ /* Get the changed period bounds */
+ updated_time_span = tsc->time_span;
+ if(ltt_time_compare(updated_time_span.start_time,
+ initial_time_span.start_time) != 0) {
+ /* The initial time should not change on a live update */
+ g_assert(FALSE);
+ }
+
+ /* Notify viewers (only on updates) */
+ if(ltt_time_compare(updated_time_span.end_time,
+ initial_time_span.end_time) != 0) {
+
+ notify_time_span_changed(tab);
+ /* TODO ybrosseau 2011-01-12: Change the timebar to register
+ to the time_span hook */
+ timebar_set_minmax_time(TIMEBAR(tab->MTimebar),
+ &updated_time_span.start_time,
+ &updated_time_span.end_time );
+
+ /* To update the min max */
+ time_change_manager(tab, tab->time_window);
+ }
+
+ /* Timer will be recalled as long as there is files to update */
+ return (updated_count > 0);
+}
static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
{
@@ -1561,6 +1567,16 @@ static void lttvwindow_add_trace(Tab *tab, LttvTrace *trace_v)
//FIXME
//add_trace_into_traceset_selector(GTK_MULTIVPANED(tab->multivpaned), lttv_trace(trace_v));
+
+
+ if (lttv_trace(trace_v)->is_live) {
+ /* Add timer for live update */
+ /* TODO ybrosseau 2011-01-12: Parametrize the hardcoded 1 seconds */
+ g_timeout_add_seconds (1,
+ live_trace_update_handler,
+ tab);
+ }
+
}
/* add_trace adds a trace into the current traceset. It first displays a
@@ -1593,6 +1609,7 @@ void add_trace(GtkWidget * widget, gpointer user_data)
}
/* File open dialog management */
+ GtkWidget *extra_live_button;
GtkFileChooser * file_chooser =
GTK_FILE_CHOOSER(
gtk_file_chooser_dialog_new ("Select a trace",
@@ -1602,6 +1619,11 @@ void add_trace(GtkWidget * widget, gpointer user_data)
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL));
+ /* Button to indicate the opening of a live trace */
+ extra_live_button = gtk_check_button_new_with_mnemonic ("Trace is live (currently being writen)");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra_live_button), FALSE);
+ gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_chooser), extra_live_button);
+
gtk_file_chooser_set_show_hidden (file_chooser, TRUE);
if(remember_trace_dir[0] != '\0')
gtk_file_chooser_set_filename(file_chooser, remember_trace_dir);
@@ -1612,6 +1634,7 @@ void add_trace(GtkWidget * widget, gpointer user_data)
case GTK_RESPONSE_ACCEPT:
case GTK_RESPONSE_OK:
dir = gtk_file_chooser_get_filename (file_chooser);
+
strncpy(remember_trace_dir, dir, PATH_MAX);
strncat(remember_trace_dir, "/", PATH_MAX);
if(!dir || strlen(dir) == 0){
@@ -1620,7 +1643,9 @@ 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,
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (extra_live_button)));
if(trace == NULL) {
g_warning("cannot open trace %s", abs_path);
@@ -3295,7 +3320,6 @@ void current_position_change_manager(Tab *tab,
set_current_position(tab, pos);
}
-
static void on_timebar_starttime_changed(Timebar *timebar,
gpointer user_data)
{
@@ -4084,7 +4108,7 @@ gboolean execute_events_requests(Tab *tab)
}
-__EXPORT void create_main_window_with_trace_list(GSList *traces)
+__EXPORT void create_main_window_with_trace_list(GSList *traces, gboolean is_live)
{
GSList *iter = NULL;
@@ -4116,7 +4140,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, is_live);
if(trace == NULL) {
g_warning("cannot open trace %s", abs_path);
diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h b/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h
index 1bbd4fb..b4373b8 100644
--- a/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h
+++ b/lttv/modules/gui/lttvwindow/lttvwindow/callbacks.h
@@ -27,7 +27,7 @@ MainWindow *construct_main_window(MainWindow * parent);
void main_window_free(MainWindow * mw);
void main_window_destructor(MainWindow * mw);
-void create_main_window_with_trace_list(GSList *traces);
+void create_main_window_with_trace_list(GSList *traces, gboolean is_live);
void insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data);
gboolean execute_events_requests(Tab *tab);
diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c b/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c
index 99ab15f..329885c 100644
--- a/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c
+++ b/lttv/modules/gui/lttvwindow/lttvwindow/init_module.c
@@ -88,6 +88,7 @@ static GSList *g_init_trace = NULL;
static char *a_trace;
//static char g_init_trace[PATH_MAX] = "";
+static gboolean a_live;
void lttv_trace_option(void *hook_data)
@@ -124,7 +125,7 @@ static gboolean window_creation_hook(void *hook_data, void *call_data)
add_pixmap_directory ("../modules/gui/main/pixmaps");
/* First window, use command line trace */
- create_main_window_with_trace_list(g_init_trace);
+ create_main_window_with_trace_list(g_init_trace, a_live);
gtk_main ();
@@ -174,6 +175,12 @@ static void init() {
"pathname of the directory containing the trace",
LTTV_OPT_STRING, &a_trace, lttv_trace_option, NULL);
+ a_live = FALSE;
+ lttv_option_add("live", 'L',
+ "define if the traceset is receiving live informations",
+ "",
+ LTTV_OPT_NONE, &a_live, NULL, NULL);
+
retval= lttv_iattribute_find_by_path(attributes, "hooks/main/before",
LTTV_POINTER, &value);
g_assert(retval);
@@ -243,6 +250,7 @@ static void destroy_walk(gpointer data, gpointer user_data)
static void destroy() {
lttv_option_remove("trace");
+ lttv_option_remove("live");
lttv_hooks_remove_data(main_hooks, window_creation_hook, NULL);
diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c b/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c
index ee3f924..acb968b 100644
--- a/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c
+++ b/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.c
@@ -468,6 +468,53 @@ __EXPORT void lttvwindow_unregister_time_window_notify(Tab *tab,
}
/**
+ * Function to register a hook function for a viewer to set/update its
+ * allowed time span.
+ * @param tab viewer's tab
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+__EXPORT void lttvwindow_register_time_span_notify(Tab *tab,
+ LttvHook hook, gpointer hook_data)
+{
+ LttvAttributeValue value;
+ LttvHooks * tmp;
+ gboolean retval;
+
+ retval= lttv_iattribute_find_by_path(tab->attributes,
+ "hooks/updatetimespan", LTTV_POINTER, &value);
+ g_assert(retval);
+ tmp = (LttvHooks*)*(value.v_pointer);
+ if(tmp == NULL){
+ tmp = lttv_hooks_new();
+ *(value.v_pointer) = tmp;
+ }
+ lttv_hooks_add(tmp, hook,hook_data, LTTV_PRIO_DEFAULT);
+}
+/**
+ * Function to unregister a viewer's hook function which is used to
+ * set/update the time span allowed for the viewer.
+ * @param tab viewer's tab
+ * @param hook hook function of the viewer.
+ * @param hook_data hook data associated with the hook function.
+ */
+
+__EXPORT void lttvwindow_unregister_time_span_notify(Tab *tab,
+ LttvHook hook, gpointer hook_data)
+{
+ LttvAttributeValue value;
+ LttvHooks * tmp;
+ gboolean retval;
+
+ retval= lttv_iattribute_find_by_path(tab->attributes,
+ "hooks/updatetimespan", LTTV_POINTER, &value);
+ g_assert(retval);
+ tmp = (LttvHooks*)*(value.v_pointer);
+ if(tmp == NULL) return;
+ lttv_hooks_remove_data(tmp, hook, hook_data);
+}
+
+/**
* Function to register a hook function for a viewer to set/update its
* traceset.
* @param tab viewer's tab
diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h b/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h
index 30fa5c6..42a8ba3 100644
--- a/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h
+++ b/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindow.h
@@ -361,6 +361,36 @@ void lttvwindow_unregister_time_window_notify(Tab *tab,
LttvHook hook,
gpointer hook_data);
+/**
+ * Function to register a hook function that will be called by the main window
+ * when the time span of the traceset is updated.
+ *
+ * This register function is typically called by the constructor of the viewer.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook that sould be called by the main window when the time
+ * interval changes.
+ * @param hook_data hook data associated with the hook function. It will
+ * be typically a pointer to the viewer's data structure.
+ */
+void lttvwindow_register_timespan_notify(Tab *tab,
+ LttvHook hook,
+ gpointer hook_data);
+
+/**
+ * Function to unregister the time_span notification hook.
+ *
+ * This unregister function is typically called by the destructor of the viewer.
+ *
+ * @param tab the tab the viewer belongs to.
+ * @param hook hook that sould be called by the main window when the time
+ * interval changes.
+ * @param hook_data hook data associated with the hook function. It will
+ * be typically a pointer to the viewer's data structure.
+ */
+void lttvwindow_unregister_timespan_notify(Tab *tab,
+ LttvHook hook,
+ gpointer hook_data);
/**
* Function to register a hook function that will be called by the main window
diff --git a/lttv/modules/gui/lttvwindow/lttvwindow/timeentry.h b/lttv/modules/gui/lttvwindow/lttvwindow/timeentry.h
index 580b20c..6dcf22b 100644
--- a/lttv/modules/gui/lttvwindow/lttvwindow/timeentry.h
+++ b/lttv/modules/gui/lttvwindow/lttvwindow/timeentry.h
@@ -1,4 +1,3 @@
-
/* This file is part of the Linux Trace Toolkit viewer
* Copyright (C) 2010 Yannick Brosseau
*
diff --git a/lttv/modules/gui/statistics/statistics.c b/lttv/modules/gui/statistics/statistics.c
index 2b40d6b..ce71862 100644
--- a/lttv/modules/gui/statistics/statistics.c
+++ b/lttv/modules/gui/statistics/statistics.c
@@ -116,6 +116,7 @@ struct _StatisticViewerData{
GHashTable *statistic_hash;
guint background_info_waiting;
+ guint live_trace_count;
};
@@ -290,6 +291,7 @@ gui_statistic(LttvPluginTab *ptab)
GtkTreeViewColumn *column;
StatisticViewerData* statistic_viewer_data = g_new(StatisticViewerData,1);
+ statistic_viewer_data->live_trace_count = 0;
Tab *tab = ptab->tab;
statistic_viewer_data->tab = tab;
statistic_viewer_data->ptab = ptab;
@@ -301,7 +303,6 @@ gui_statistic(LttvPluginTab *ptab)
lttvwindow_register_traceset_notify(statistic_viewer_data->tab,
statistic_traceset_changed,
statistic_viewer_data);
-
statistic_viewer_data->statistic_hash = g_hash_table_new_full(g_str_hash,
g_str_equal,
statistic_destroy_hash_key,
@@ -424,6 +425,8 @@ extern FILE *stdout;
extern FILE *stderr;
#endif //DEBUG
+static const char *live_msg = "Statistics for traceset containing live traces are inaccurate";
+
void show_traceset_stats(StatisticViewerData * statistic_viewer_data)
{
Tab *tab = statistic_viewer_data->tab;
@@ -451,6 +454,21 @@ void show_traceset_stats(StatisticViewerData * statistic_viewer_data)
-1);
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
str = gtk_tree_path_to_string (path);
+
+ for(i = 0 ; i < nb ; i++) {
+ if (LTTV_TRACESET_CONTEXT(tscs)->traces[i]->t->is_live) {
+ statistic_viewer_data->live_trace_count++;
+ }
+
+ }
+ if (statistic_viewer_data->live_trace_count) {
+ LttvAttributeValue value;
+ value = lttv_attribute_add(tscs->stats,
+ g_quark_from_static_string("WARNING: Live traceset"),
+ LTTV_STRING);
+ *(value.v_string) = live_msg;
+
+ }
g_hash_table_insert(statistic_viewer_data->statistic_hash,
(gpointer)str, tscs->stats);
show_tree(statistic_viewer_data, tscs->stats, &iter);
@@ -467,16 +485,30 @@ void show_traceset_stats(StatisticViewerData * statistic_viewer_data)
start_time.tv_nsec);
#endif //0
sprintf(trace_str, "%s", g_quark_to_string(ltt_trace_name(tcs->parent.parent.t)));
- gtk_tree_store_append (store, &iter, NULL);
- gtk_tree_store_set (store, &iter,NAME_COLUMN,trace_str,-1);
- path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
- str = gtk_tree_path_to_string (path);
- g_hash_table_insert(statistic_viewer_data->statistic_hash,
- (gpointer)str,tcs->stats);
- show_tree(statistic_viewer_data, tcs->stats, &iter);
+ /* TODO ybrosseau 2011-01-12: Reenable stats for live trace */
+ if (LTTV_TRACE_CONTEXT(tcs)->t->is_live) {
+ strcat(trace_str, " [LIVE]");
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter,NAME_COLUMN,trace_str,-1);
+
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+ str = gtk_tree_path_to_string (path);
+ g_hash_table_insert(statistic_viewer_data->statistic_hash,
+ (gpointer)str,0);
+
+ } else {
+
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter,NAME_COLUMN,trace_str,-1);
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
+ str = gtk_tree_path_to_string (path);
+ g_hash_table_insert(statistic_viewer_data->statistic_hash,
+ (gpointer)str,tcs->stats);
+ show_tree(statistic_viewer_data, tcs->stats, &iter);
#ifdef DEBUG
- lttv_attribute_write_xml(tcs->stats, stdout, 3, 4);
+ lttv_attribute_write_xml(tcs->stats, stdout, 3, 4);
#endif //DEBUG
+ }
}
}
@@ -523,7 +555,7 @@ void show_tree(StatisticViewerData * statistic_viewer_data,
void show_statistic(StatisticViewerData * statistic_viewer_data,
LttvAttribute* stats, GtkTextBuffer* buf)
{
- int i, nb , flag;
+ int i, nb = 0, flag;
LttvAttributeName name;
LttvAttributeValue value;
LttvAttributeType type;
@@ -532,7 +564,9 @@ void show_statistic(StatisticViewerData * statistic_viewer_data,
GtkTextIter text_iter;
flag = 0;
- nb = lttv_attribute_get_number(stats);
+ if(stats) {
+ nb = lttv_attribute_get_number(stats);
+ }
for(i = 0 ; i < nb ; i++) {
type = lttv_attribute_get(stats, i, &name, &value, &is_named);
if(is_named)
diff --git a/lttv/modules/gui/tracecontrol/tracecontrol.c b/lttv/modules/gui/tracecontrol/tracecontrol.c
index 56165d9..2aae7aa 100644
--- a/lttv/modules/gui/tracecontrol/tracecontrol.c
+++ b/lttv/modules/gui/tracecontrol/tracecontrol.c
@@ -1115,7 +1115,8 @@ void stop_clicked (GtkButton *button, gpointer user_data)
switch(id){
case GTK_RESPONSE_ACCEPT:
{
- create_main_window_with_trace_list(trace_list);
+ /* TODO ybrosseau: 2011-04-20: Add support for live trace */
+ create_main_window_with_trace_list(trace_list, FALSE);
}
break;
case GTK_RESPONSE_REJECT:
--
1.7.2.3
^ permalink raw reply [flat|nested] 3+ messages in thread