From 33e44b82c5966a1841044f9ad87485054a39df7e Mon Sep 17 00:00:00 2001 From: compudj Date: Tue, 30 Aug 2005 23:39:39 +0000 Subject: [PATCH] seek forward and backward fixed git-svn-id: http://ltt.polymtl.ca/svn@1092 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/lttv/lttv/batchtest.c | 85 +++++++++++++++++ ltt/branches/poly/lttv/lttv/filter.c | 15 ++- ltt/branches/poly/lttv/lttv/filter.h | 6 +- ltt/branches/poly/lttv/lttv/tracecontext.c | 105 +++++++++++++++++---- ltt/branches/poly/lttv/lttv/tracecontext.h | 18 +++- 5 files changed, 203 insertions(+), 26 deletions(-) diff --git a/ltt/branches/poly/lttv/lttv/batchtest.c b/ltt/branches/poly/lttv/lttv/batchtest.c index 8d4be06e..d1a57886 100644 --- a/ltt/branches/poly/lttv/lttv/batchtest.c +++ b/ltt/branches/poly/lttv/lttv/batchtest.c @@ -77,6 +77,7 @@ static gboolean a_test6, a_test7, a_test8, + a_test9, a_test_all; static GQuark QUARK_BLOCK_START, @@ -649,6 +650,84 @@ static gboolean process_traceset(void __UNUSED__ *hook_data, } + if(a_test9 || a_test_all) { + /* Run seek_forward and seek_backward test */ + LttvTracesetContextPosition *saved_pos = + lttv_traceset_context_position_new(); + guint count; + LttvTracesetContext *tsc = &ts->parent; + g_message("Running test 9 : seek_forward and seek_backward"); + lttv_process_traceset_seek_time(tsc, ltt_time_zero); + + count = lttv_process_traceset_seek_n_forward(tsc, 500, NULL); + g_assert(count == 500); + lttv_traceset_context_position_save(tsc, saved_pos); + count = lttv_process_traceset_seek_n_forward(tsc, 150000, NULL); + g_assert(count == 150000); + count = lttv_process_traceset_seek_n_backward(tsc, 150000, + seek_back_default_offset, lttv_process_traceset_seek_time, NULL); + g_assert(count == 150000); + if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) { + g_warning("Problem with seek_n ! Positions differ. (1)"); + } + + lttv_process_traceset_seek_n_forward(tsc, 500, NULL); + lttv_traceset_context_position_save(tsc, saved_pos); + lttv_process_traceset_seek_n_forward(tsc, 15000, NULL); + lttv_process_traceset_seek_n_backward(tsc, 15005, + seek_back_default_offset, lttv_process_traceset_seek_time, NULL); + lttv_process_traceset_seek_n_forward(tsc, 5, NULL); + if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) { + g_warning("Problem with seek_n ! Positions differ. (2)"); + } + + lttv_process_traceset_seek_time(tsc, ltt_time_infinite); + + count = lttv_process_traceset_seek_n_forward(tsc, 15000, NULL); + if(count > 0) + g_warning("Problem with seek_n ! Forward at end of traceset."); + + lttv_process_traceset_seek_time(tsc, ltt_time_infinite); + + lttv_traceset_context_position_save(tsc, saved_pos); + lttv_process_traceset_seek_n_backward(tsc, 300, + seek_back_default_offset, lttv_process_traceset_seek_time, NULL); + count = lttv_process_traceset_seek_n_forward(tsc, 299, NULL); + count = lttv_process_traceset_seek_n_forward(tsc, 1, NULL); + + if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) { + g_warning("Problem with seek_n ! Positions differ. (4)"); + } + + /* try a volountary error */ + lttv_process_traceset_seek_time(tsc, ltt_time_infinite); + + lttv_traceset_context_position_save(tsc, saved_pos); + lttv_process_traceset_seek_n_backward(tsc, 301, + seek_back_default_offset, lttv_process_traceset_seek_time, NULL); + count = lttv_process_traceset_seek_n_forward(tsc, 299, NULL); + count = lttv_process_traceset_seek_n_forward(tsc, 1, NULL); + + if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos) == 0) { + g_warning("Problem with seek_n ! Positions _should_ differ. (5)"); + } + + /* Try a seek by closest time : Hint : try this one with and without states + * computed. */ + lttv_process_traceset_seek_time(tsc, ltt_time_zero); + count = lttv_process_traceset_seek_n_forward(tsc, 200000, NULL); + lttv_traceset_context_position_save(tsc, saved_pos); + lttv_process_traceset_seek_n_backward(tsc, 100301, + //seek_back_default_offset, lttv_state_traceset_seek_time_closest, NULL); + seek_back_default_offset, lttv_process_traceset_seek_time, NULL); + count = lttv_process_traceset_seek_n_forward(tsc, 100301, NULL); + + if(lttv_traceset_context_ctx_pos_compare(tsc, saved_pos)) { + g_warning("Problem with seek_n with state seek time! Positions differ. (6)"); + } + + lttv_traceset_context_position_destroy(saved_pos); + } if(a_trace_event) lttv_hooks_remove_data(event_hook, trace_event, NULL); g_free(save_state.write_time); @@ -757,6 +836,11 @@ static void init() a_test8 = FALSE; lttv_option_add("test8", '8', "Test seeking to positions using saved states computed at 6 : check if number of events fits", "", LTTV_OPT_NONE, &a_test8, NULL, NULL); + + a_test9 = FALSE; + lttv_option_add("test9", '9', "Test seeking backward/forward positions", + "", LTTV_OPT_NONE, &a_test9, NULL, NULL); + a_test_all = FALSE; lttv_option_add("testall", 'a', "Run all tests ", "", @@ -833,6 +917,7 @@ static void destroy() lttv_option_remove("test6"); lttv_option_remove("test7"); lttv_option_remove("test8"); + lttv_option_remove("test9"); lttv_option_remove("testall"); lttv_hooks_destroy(before_traceset); diff --git a/ltt/branches/poly/lttv/lttv/filter.c b/ltt/branches/poly/lttv/lttv/filter.c index d6defdf7..b7979f3f 100644 --- a/ltt/branches/poly/lttv/lttv/filter.c +++ b/ltt/branches/poly/lttv/lttv/filter.c @@ -1612,7 +1612,6 @@ lttv_filter_tree_parse( const LttEvent* event, const LttTracefile* tracefile, const LttTrace* trace, - const LttvProcessState* state, const LttvTracefileContext* context /*,...*/) { @@ -1653,12 +1652,22 @@ lttv_filter_tree_parse( */ gboolean lresult = FALSE, rresult = FALSE; + + LttvProcessState* state; + + if(LTTV_IS_TRACESET_STATE(context)) { + guint cpu = ltt_tracefile_num(context->tf); + LttvTraceState *ts = (LttvTraceState*)context->t_context; + state = ts->running_process[cpu]; + } else { + state = NULL; + } /* * Parse left branch */ if(t->left == LTTV_TREE_NODE) { - lresult = lttv_filter_tree_parse(t->l_child.t,event,tracefile,trace,state,context); + lresult = lttv_filter_tree_parse(t->l_child.t,event,tracefile,trace,context); } else if(t->left == LTTV_TREE_LEAF) { lresult = lttv_filter_tree_parse_branch(t->l_child.leaf,event,tracefile,trace,state,context); @@ -1675,7 +1684,7 @@ lttv_filter_tree_parse( * Parse right branch */ if(t->right == LTTV_TREE_NODE) { - rresult = lttv_filter_tree_parse(t->r_child.t,event,tracefile,trace,state,context); + rresult = lttv_filter_tree_parse(t->r_child.t,event,tracefile,trace,context); } else if(t->right == LTTV_TREE_LEAF) { rresult = lttv_filter_tree_parse_branch(t->r_child.leaf,event,tracefile,trace,state,context); diff --git a/ltt/branches/poly/lttv/lttv/filter.h b/ltt/branches/poly/lttv/lttv/filter.h index 0e7ca9c7..9531046f 100644 --- a/ltt/branches/poly/lttv/lttv/filter.h +++ b/ltt/branches/poly/lttv/lttv/filter.h @@ -65,8 +65,11 @@ typedef union _LttvFieldValue LttvFieldValue; typedef struct _LttvSimpleExpression LttvSimpleExpression; typedef struct _LttvFilterTree LttvFilterTree; -typedef struct _LttvFilter LttvFilter; +#ifndef LTTVFILTER_TYPE_DEFINED +typedef struct _LttvFilter LttvFilter; +#define LTTVFILTER_TYPE_DEFINED +#endif /** * @enum _LttvStructType @@ -327,7 +330,6 @@ gboolean lttv_filter_tree_parse( const LttEvent* event, const LttTracefile* tracefile, const LttTrace* trace, - const LttvProcessState* state, const LttvTracefileContext* context); gboolean lttv_filter_tree_parse_branch( diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.c b/ltt/branches/poly/lttv/lttv/tracecontext.c index 305d736c..08c12e23 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.c +++ b/ltt/branches/poly/lttv/lttv/tracecontext.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define min(a,b) (((a)<(b))?(a):(b)) @@ -1077,6 +1078,11 @@ void lttv_traceset_context_position_save(const LttvTracesetContext *self, guint i; guint num_traces = lttv_traceset_number(self->ts); + for(i=0;iep->len;i++){ + LttEventPosition *ep = g_array_index(pos->ep, LttEventPosition*, i); + if(ep != NULL) g_free(ep); + } + pos->tfc = g_array_set_size(pos->tfc, 0); pos->ep = g_array_set_size(pos->ep, 0); @@ -1137,7 +1143,7 @@ void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest, src_ep = &g_array_index(src->ep, LttEventPosition*, i); dest_ep = &g_array_index(dest->ep, LttEventPosition*, i); if(*src_ep != NULL) { - *dest_ep = ltt_event_position_new(); + if(*dest_ep == NULL) *dest_ep = ltt_event_position_new(); ltt_event_position_copy( *dest_ep, *src_ep); @@ -1280,7 +1286,9 @@ struct seek_back_data { overwrite at this position : this is a circular array. */ guint events_found; + guint n; /* number of events requested */ GPtrArray *array; /* array of LttvTracesetContextPositions pointers */ + LttvFilter *filter; }; static gint seek_back_event_hook(void *hook_data, void* call_data) @@ -1289,32 +1297,40 @@ static gint seek_back_event_hook(void *hook_data, void* call_data) LttvTracefileContext *tfc = (LttvTracefileContext*)call_data; LttvTracesetContext *tsc = tfc->t_context->ts_context; LttvTracesetContextPosition *pos; - - if(sd->events_found < sd->array->len) { - pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd->array, - sd->events_found); - } else { - pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd->array, - sd->first_event); + + if(sd->filter != NULL) { + if(!lttv_filter_tree_parse(sd->filter->head, + ltt_tracefile_get_event(tfc->tf), + tfc->tf, + tfc->t_context->t, + tfc)) + return FALSE; } + + pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd->array, + sd->first_event); lttv_traceset_context_position_save(tsc, pos); if(sd->first_event >= sd->array->len - 1) sd->first_event = 0; else sd->first_event++; - sd->events_found = min(sd->array->len, sd->events_found + 1); + sd->events_found = min(sd->n, sd->events_found + 1); return FALSE; } - /* Seek back n events back from the current position. * * Parameters : * @self The trace set context * @n number of events to jump over * @first_offset The initial offset value used. Hint : try about 100000ns. + * never put first_offset at ltt_time_zero. + * @time_seeker Function pointer of the function to use to seek time : + * either lttv_process_traceset_seek_time + * or lttv_state_traceset_seek_time_closest + * @filter The filter to call. * * Return value : the number of events found (might be lower than the number * requested if beginning of traceset is reached). @@ -1331,12 +1347,18 @@ static gint seek_back_event_hook(void *hook_data, void* call_data) * contain any hook, as process_traceset_middle is used in this routine. */ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, - guint n, LttTime first_offset) + guint n, LttTime first_offset, + seek_time_fct time_seeker, + LttvFilter *filter) { + if(lttv_traceset_number(self->ts) == 0) return 0; + g_assert(ltt_time_compare(first_offset, ltt_time_zero) != 0); + guint i; LttvTracesetContextPosition *next_iter_end_pos = lttv_traceset_context_position_new(); LttvTracesetContextPosition *end_pos = lttv_traceset_context_position_new(); + LttvTracesetContextPosition *saved_pos = lttv_traceset_context_position_new(); LttTime time; LttTime time_offset; struct seek_back_data sd; @@ -1345,12 +1367,15 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, sd.first_event = 0; sd.events_found = 0; sd.array = g_ptr_array_sized_new(n); + sd.filter = filter; + sd.n = n; g_ptr_array_set_size(sd.array, n); for(i=0;itime_span.start_time) < 0) break; - if(sd.events_found == n) break; lttv_traceset_context_position_copy(end_pos, next_iter_end_pos); @@ -1375,8 +1399,13 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, /* this time becomes the new reference time */ time = ltt_time_sub(time, time_offset); - lttv_process_traceset_seek_time(self, time); + time_seeker(self, time); lttv_traceset_context_position_save(self, next_iter_end_pos); + /* Resync the time in case of a seek_closest */ + time = lttv_traceset_context_position_get_time(next_iter_end_pos); + if(ltt_time_compare(time, self->time_span.end_time) > 0) { + time = self->time_span.end_time; + } /* Process the traceset, calling a hook which adds events * to the array, overwriting the tail. It changes first_event and @@ -1386,6 +1415,25 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, lttv_process_traceset_middle(self, ltt_time_infinite, G_MAXUINT, end_pos); + if(sd.events_found < n) { + if(sd.first_event > 0) { + /* Save the first position */ + LttvTracesetContextPosition *pos = + (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, 0); + lttv_traceset_context_position_copy(saved_pos, pos); + } + g_assert(n-sd.events_found <= sd.array->len); + /* Change array size to n - events_found */ + for(i=n-sd.events_found;ilen;i++) { + LttvTracesetContextPosition *pos = + (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, i); + lttv_traceset_context_position_destroy(pos); + } + g_ptr_array_set_size(sd.array, n-sd.events_found); + sd.first_event = 0; + + } else break; /* Second end criterion : n events found */ + time_offset = ltt_time_mul(time_offset, BACKWARD_SEEK_MUL); } @@ -1394,15 +1442,19 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, lttv_process_traceset_end(self, NULL, NULL, NULL, hooks, NULL); - if(sd.events_found > 0) { + if(sd.events_found >= n) { /* Seek the traceset to the first event in the circular array */ LttvTracesetContextPosition *pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, sd.first_event); g_assert(lttv_process_traceset_seek_position(self, pos) == 0); + } else { + /* Will seek to the last saved position : in the worst case, it will be the + * original position (if events_found is 0) */ + g_assert(lttv_process_traceset_seek_position(self, saved_pos) == 0); } - for(i=0;ilen;i++) { LttvTracesetContextPosition *pos = (LttvTracesetContextPosition*)g_ptr_array_index (sd.array, i); lttv_traceset_context_position_destroy(pos); @@ -1411,6 +1463,8 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, lttv_hooks_destroy(hooks); + lttv_traceset_context_position_destroy(saved_pos); + return sd.events_found; } @@ -1418,12 +1472,23 @@ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, struct seek_forward_data { guint event_count; /* event counter */ guint n; /* requested number of events to jump over */ + LttvFilter *filter; }; static gint seek_forward_event_hook(void *hook_data, void* call_data) { struct seek_forward_data *sd = (struct seek_forward_data*)hook_data; + LttvTracefileContext *tfc = (LttvTracefileContext*)call_data; + if(sd->filter != NULL) { + if(!lttv_filter_tree_parse(sd->filter->head, + ltt_tracefile_get_event(tfc->tf), + tfc->tf, + tfc->t_context->t, + tfc)) + return FALSE; + } + sd->event_count++; if(sd->event_count >= sd->n) @@ -1435,17 +1500,19 @@ static gint seek_forward_event_hook(void *hook_data, void* call_data) /* Seek back n events forward from the current position * * Parameters : - * @self the trace set context - * @n number of events to jump over + * @self the trace set context + * @n number of events to jump over + * @filter filter to call. * * returns : the number of events jumped over (may be less than requested if end * of traceset reached) */ guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self, - guint n) + guint n, LttvFilter *filter) { struct seek_forward_data sd; sd.event_count = 0; sd.n = n; + sd.filter = filter; LttvHooks *hooks = lttv_hooks_new(); lttv_hooks_add(hooks, seek_forward_event_hook, &sd, LTTV_PRIO_DEFAULT); diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.h b/ltt/branches/poly/lttv/lttv/tracecontext.h index f1396463..c8ec8443 100644 --- a/ltt/branches/poly/lttv/lttv/tracecontext.h +++ b/ltt/branches/poly/lttv/lttv/tracecontext.h @@ -77,6 +77,11 @@ typedef struct _LttvTracefileContextClass LttvTracefileContextClass; typedef struct _LttvTracesetContextPosition LttvTracesetContextPosition; typedef struct _LttvTraceContextPosition LttvTraceContextPosition; +#ifndef LTTVFILTER_TYPE_DEFINED +typedef struct _LttvFilter LttvFilter; +#define LTTVFILTER_TYPE_DEFINED +#endif + #define LTTV_TRACESET_CONTEXT_TYPE (lttv_traceset_context_get_type ()) #define LTTV_TRACESET_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContext)) #define LTTV_TRACESET_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass)) @@ -341,10 +346,19 @@ void lttv_process_traceset_get_sync_data(LttvTracesetContext *tsc); #define BACKWARD_SEEK_MUL 2 /* Multiplication factor of time_offset between backward seek iterations */ +static const LttTime seek_back_default_offset = { 0, 100000 }; + guint lttv_process_traceset_seek_n_forward(LttvTracesetContext *self, - guint n); + guint n, + LttvFilter *filter); +typedef void (*seek_time_fct)(LttvTracesetContext *self, LttTime start); +/* If first_offset is ltt_time_zero, it will choose a default value */ guint lttv_process_traceset_seek_n_backward(LttvTracesetContext *self, - guint n, LttTime first_offset); + guint n, + LttTime first_offset, + seek_time_fct, + LttvFilter *filter); + #endif // PROCESSTRACE_H -- 2.34.1