X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Flttvwindow%2Flttvwindow%2Flttvwindowtraces.c;h=5b34c8c5d071dfb77b6851c54f81db984f8caf74;hb=1ba187d313cd6e070cfebfa1314c295cf173c4b7;hp=18dc3d3a01f995049b9a6703a5ff0aaedd242bfb;hpb=2a74fbf4e7e641f94517b3e996c674291248bb1d;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c index 18dc3d3a..5b34c8c5 100644 --- a/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c +++ b/ltt/branches/poly/lttv/modules/gui/lttvwindow/lttvwindow/lttvwindowtraces.c @@ -53,6 +53,9 @@ typedef struct _BackgroundNotify { +/* Prototypes */ +gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace); + /* Get a trace by its path name. * * @param path path of the trace on the virtual file system. @@ -153,7 +156,7 @@ void lttvwindowtraces_add_trace(LttvTrace *trace) /* create new traceset and tracesetcontext */ LttvTraceset *ts; - LttvTracesetContext *tsc; + LttvTracesetStats *tss; attribute = lttv_trace_attribute(trace); g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), @@ -169,10 +172,10 @@ void lttvwindowtraces_add_trace(LttvTrace *trace) LTTV_COMPUTATION_TRACESET_CONTEXT, LTTV_POINTER, &value)); - tsc = g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL); - *(value.v_pointer) = tsc; + tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL); + *(value.v_pointer) = tss; - lttv_context_init(tsc, ts); + lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts); value = lttv_attribute_add(attribute, LTTV_REQUESTS_QUEUE, @@ -210,13 +213,16 @@ void lttvwindowtraces_remove_trace(LttvTrace *trace) g_assert(trace_v != NULL); + /* Remove and background computation that could be in progress */ + g_idle_remove_by_data(trace_v); + if(trace_v == trace) { /* Found */ LttvAttribute *l_attribute; /* create new traceset and tracesetcontext */ LttvTraceset *ts; - LttvTracesetContext *tsc; + LttvTracesetStats *tss; l_attribute = lttv_trace_attribute(trace); @@ -243,15 +249,16 @@ void lttvwindowtraces_remove_trace(LttvTrace *trace) LTTV_COMPUTATION_TRACESET_CONTEXT, LTTV_POINTER, &value)); - tsc = (LttvTracesetContext*)*(value.v_pointer); + tss = (LttvTracesetStats*)*(value.v_pointer); - lttv_context_fini(tsc); - g_object_unref(tsc); + lttv_context_fini(LTTV_TRACESET_CONTEXT(tss)); + g_object_unref(tss); lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute), LTTV_COMPUTATION_TRACESET_CONTEXT); - lttv_traceset_destroy(ts); lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute), LTTV_COMPUTATION_TRACESET); + /* Destroy the traceset and the trace also */ + lttv_traceset_destroy(ts); /* finally, remove the global attribute */ lttv_attribute_remove(attribute, i); @@ -277,7 +284,10 @@ void lttvwindowtraces_background_request_queue { BackgroundRequest *bg_req; LttvAttribute *attribute = lttv_trace_attribute(trace); + LttvAttribute *g_attribute = lttv_global_attributes(); + LttvAttribute *module_attribute; LttvAttributeValue value; + LttvAttributeType type; GSList **slist; guint num; @@ -286,12 +296,35 @@ void lttvwindowtraces_background_request_queue LTTV_POINTER, &value)); slist = (GSList**)(value.v_pointer); - + + /* Verify that the calculator is loaded */ + g_assert(module_attribute = + LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute), + LTTV_COMPUTATION))); + + + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute), + g_quark_from_string(module_name), + &value); + if(type == LTTV_NONE) { + g_critical("Missing background calculator %s", module_name); + return; + } + bg_req = g_new(BackgroundRequest,1); bg_req->module_name = g_quark_from_string(module_name); bg_req->trace = trace; *slist = g_slist_append(*slist, bg_req); + + /* Priority lower than live servicing */ + g_idle_remove_by_data(trace); + g_idle_add_full((G_PRIORITY_HIGH_IDLE + 23), + (GSourceFunc)lttvwindowtraces_process_pending_requests, + trace, + NULL); + /* FIXME : show message in status bar, need context and message id */ + g_info("Background computation started for trace %p", trace); } /** @@ -376,9 +409,14 @@ void lttvwindowtraces_background_notify_queue bg_notify->owner = owner; bg_notify->trace = trace; bg_notify->notify_time = notify_time; - bg_notify->notify_position = ltt_traceset_context_position_new(); - lttv_traceset_context_position_copy(bg_notify->notify_position, - notify_position); + if(notify_position != NULL) { + bg_notify->notify_position = lttv_traceset_context_position_new(); + lttv_traceset_context_position_copy(bg_notify->notify_position, + notify_position); + } else { + bg_notify->notify_position = NULL; + } + bg_notify->notify = lttv_hooks_new(); lttv_hooks_add_list(bg_notify->notify, notify); @@ -419,15 +457,31 @@ void lttvwindowtraces_background_notify_current bg_notify->owner = owner; bg_notify->trace = trace; bg_notify->notify_time = notify_time; - bg_notify->notify_position = ltt_traceset_context_position_new(); - lttv_traceset_context_position_copy(bg_notify->notify_position, - notify_position); + if(notify_position!= NULL) { + bg_notify->notify_position = lttv_traceset_context_position_new(); + lttv_traceset_context_position_copy(bg_notify->notify_position, + notify_position); + } else { + bg_notify->notify_position = NULL; + } bg_notify->notify = lttv_hooks_new(); lttv_hooks_add_list(bg_notify->notify, notify); *slist = g_slist_append(*slist, bg_notify); } + +static void notify_request_free(BackgroundNotify *notify_req) +{ + if(notify_req == NULL) return; + + if(notify_req->notify_position != NULL) + lttv_traceset_context_position_destroy(notify_req->notify_position); + if(notify_req->notify != NULL) + lttv_hooks_destroy(notify_req->notify); + g_free(notify_req); +} + /** * Removes all the notifications requests from a specific viewer. * @@ -447,7 +501,7 @@ void lttvwindowtraces_background_notify_remove(gpointer owner) g_assert(trace_v != NULL); - LttvAttribute *t_a = lttv_trace_attribute(trace_v); + attribute = lttv_trace_attribute(trace_v); g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), LTTV_NOTIFY_QUEUE, @@ -462,11 +516,8 @@ void lttvwindowtraces_background_notify_remove(gpointer owner) if(bg_notify->owner == owner) { GSList *rem_iter = iter; iter=g_slist_next(iter); - lttv_traceset_context_position_destroy( - bg_notify->notify_position); - lttv_hooks_destroy(bg_notify->notify); - g_free(bg_notify); - g_slist_remove_link(*slist, rem_iter); + notify_request_free(bg_notify); + *slist = g_slist_remove_link(*slist, rem_iter); } else { iter=g_slist_next(iter); } @@ -485,11 +536,8 @@ void lttvwindowtraces_background_notify_remove(gpointer owner) if(bg_notify->owner == owner) { GSList *rem_iter = iter; iter=g_slist_next(iter); - lttv_traceset_context_position_destroy( - bg_notify->notify_position); - lttv_hooks_destroy(bg_notify->notify); - g_free(bg_notify); - g_slist_remove_link(*slist, rem_iter); + notify_request_free(bg_notify); + *slist = g_slist_remove_link(*slist, rem_iter); } else { iter=g_slist_next(iter); } @@ -501,7 +549,8 @@ void lttvwindowtraces_background_notify_remove(gpointer owner) /* Background processing helper functions */ void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name, - LttvTracesetContext *tsc) + LttvTracesetContext *tsc, + LttvHooks *hook_adder) { LttvAttribute *g_attribute = lttv_global_attributes(); LttvAttribute *module_attribute; @@ -512,6 +561,7 @@ void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name, LttvHooks *before_chunk_tracefile=NULL; LttvHooks *event_hook=NULL; LttvHooksById *event_hook_by_id=NULL; + LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc); g_assert(module_attribute = @@ -558,6 +608,17 @@ void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name, event_hook_by_id = (LttvHooksById*)*(value.v_pointer); } + /* Call the module's hook adder */ + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute), + LTTV_HOOK_ADDER, + &value); + if(type == LTTV_POINTER) { + //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss); + if(hook_adder != NULL) + lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer)); + } + + lttv_process_traceset_begin(tsc, before_chunk_traceset, @@ -569,7 +630,8 @@ void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name, } void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name, - LttvTracesetContext *tsc) + LttvTracesetContext *tsc, + LttvHooks *hook_remover) { LttvAttribute *g_attribute = lttv_global_attributes(); LttvAttribute *module_attribute; @@ -580,7 +642,7 @@ void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name, LttvHooks *after_chunk_tracefile=NULL; LttvHooks *event_hook=NULL; LttvHooksById *event_hook_by_id=NULL; - + LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc); g_assert(module_attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute), @@ -625,14 +687,23 @@ void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name, if(type == LTTV_POINTER) { event_hook_by_id = (LttvHooksById*)*(value.v_pointer); } - - + lttv_process_traceset_end(tsc, after_chunk_traceset, after_chunk_trace, after_chunk_tracefile, event_hook, event_hook_by_id); + + /* Call the module's hook remover */ + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute), + LTTV_HOOK_REMOVER, + &value); + if(type == LTTV_POINTER) { + //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss); + if(hook_remover != NULL) + lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer)); + } } @@ -662,7 +733,7 @@ void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name, LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute), module_name))); - lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute), + lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), LTTV_IN_PROGRESS); } @@ -713,7 +784,7 @@ void lttvwindowtraces_unset_ready(LttvAttributeName module_name, LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute), module_name))); - lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute), + lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), LTTV_READY); } @@ -739,7 +810,6 @@ gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name, } - /* lttvwindowtraces_process_pending_requests * * This internal function gets called by g_idle, taking care of the pending @@ -751,13 +821,17 @@ gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name, gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) { LttvTracesetContext *tsc; + LttvTracesetStats *tss; LttvTraceset *ts; LttvAttribute *attribute; - GSList *list_out, *list_in, *notify_in, *notify_out; + LttvAttribute *g_attribute = lttv_global_attributes(); + GSList **list_out, **list_in, **notify_in, **notify_out; LttvAttributeValue value; LttvAttributeType type; + gboolean ret_val; + LttvHooks *before_request, *after_request; - if(trace == NULL) + if(trace == NULL) return FALSE; attribute = lttv_trace_attribute(trace); @@ -766,25 +840,25 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) LTTV_REQUESTS_QUEUE, &value); g_assert(type == LTTV_POINTER); - list_out = (GSList*)*(value.v_pointer); + list_out = (GSList**)(value.v_pointer); type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), LTTV_REQUESTS_CURRENT, &value); g_assert(type == LTTV_POINTER); - list_in = (GSList*)*(value.v_pointer); + list_in = (GSList**)(value.v_pointer); type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), LTTV_NOTIFY_QUEUE, &value); g_assert(type == LTTV_POINTER); - notify_out = (GSList*)*(value.v_pointer); + notify_out = (GSList**)(value.v_pointer); type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), LTTV_NOTIFY_CURRENT, &value); g_assert(type == LTTV_POINTER); - notify_in = (GSList*)*(value.v_pointer); + notify_in = (GSList**)(value.v_pointer); type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), LTTV_COMPUTATION_TRACESET, @@ -797,21 +871,38 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) &value); g_assert(type == LTTV_POINTER); tsc = (LttvTracesetContext*)*(value.v_pointer); + tss = (LttvTracesetStats*)*(value.v_pointer); g_assert(LTTV_IS_TRACESET_CONTEXT(tsc)); + g_assert(LTTV_IS_TRACESET_STATS(tss)); /* There is no events requests pending : we should never have been called! */ - g_assert(g_slist_length(list_out) != 0 || g_slist_length(list_in) != 0); + g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0); + /* 0.1 Lock traces */ + { + guint iter_trace=0; + + for(iter_trace=0; + iter_tracets); + iter_trace++) { + LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace); + + if(lttvwindowtraces_lock(trace_v) != 0) + return TRUE; /* Cannot get trace lock, try later */ + } + } + /* 0.2 Sync tracefiles */ + lttv_process_traceset_synchronize_tracefiles(tsc); /* 1. Before processing */ { /* if list_in is empty */ - if(g_slist_length(list_in) == 0) { + if(g_slist_length(*list_in) == 0) { { /* - Add all requests in list_out to list_in, empty list_out */ - GSList *iter = list_out; + GSList *iter = *list_out; while(iter != NULL) { gboolean remove = FALSE; @@ -821,7 +912,7 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) remove = TRUE; free_data = FALSE; - list_in = g_slist_append(list_in, bg_req); + *list_in = g_slist_append(*list_in, bg_req); /* Go to next */ if(remove) @@ -830,7 +921,7 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) iter = g_slist_next(iter); if(free_data) g_free(remove_iter->data); - list_out = g_slist_remove_link(list_out, remove_iter); + *list_out = g_slist_remove_link(*list_out, remove_iter); } else { // not remove iter = g_slist_next(iter); } @@ -838,14 +929,37 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) } { - GSList *iter = list_in; + GSList *iter = *list_in; /* - for each request in list_in */ while(iter != NULL) { BackgroundRequest *bg_req = (BackgroundRequest*)iter->data; - /*- add hooks to context*/ + /* - set hooks'in_progress flag to TRUE */ lttvwindowtraces_set_in_progress(bg_req->module_name, bg_req->trace); + + /* - call before request hook */ + /* Get before request hook */ + LttvAttribute *module_attribute; + + g_assert(module_attribute = + LTTV_ATTRIBUTE(lttv_iattribute_find_subdir( + LTTV_IATTRIBUTE(g_attribute), + LTTV_COMPUTATION))); + + g_assert(module_attribute = + LTTV_ATTRIBUTE(lttv_iattribute_find_subdir( + LTTV_IATTRIBUTE(module_attribute), + bg_req->module_name))); + + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute), + LTTV_BEFORE_REQUEST, + &value); + g_assert(type == LTTV_POINTER); + LttvHooks *before_request = (LttvHooks*)*(value.v_pointer); + + + if(before_request != NULL) lttv_hooks_call(before_request, tsc); iter = g_slist_next(iter); } @@ -859,8 +973,8 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) /* - Move all notifications from notify_out to notify_in. */ { - GSList *iter = notify_out; - g_assert(g_slist_length(notify_in) == 0); + GSList *iter = *notify_out; + g_assert(g_slist_length(*notify_in) == 0); while(iter != NULL) { gboolean remove = FALSE; @@ -870,7 +984,7 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) remove = TRUE; free_data = FALSE; - notify_in = g_slist_append(notify_in, notify_req); + *notify_in = g_slist_append(*notify_in, notify_req); /* Go to next */ if(remove) @@ -878,8 +992,9 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) GSList *remove_iter = iter; iter = g_slist_next(iter); - if(free_data) g_free(remove_iter->data); - notify_out = g_slist_remove_link(notify_out, remove_iter); + if(free_data) + notify_request_free((BackgroundNotify*)remove_iter->data); + *notify_out = g_slist_remove_link(*notify_out, remove_iter); } else { // not remove iter = g_slist_next(iter); } @@ -888,7 +1003,8 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) } { - GSList *iter = list_in; + GSList *iter = *list_in; + LttvHooks *hook_adder = lttv_hooks_new(); /* - for each request in list_in */ while(iter != NULL) { @@ -896,9 +1012,12 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) /*- Call before chunk hooks for list_in*/ /*- add hooks to context*/ lttvwindowtraces_add_computation_hooks(bg_req->module_name, - tsc); + tsc, + hook_adder); iter = g_slist_next(iter); } + lttv_hooks_call(hook_adder,tsc); + lttv_hooks_destroy(hook_adder); } } @@ -906,7 +1025,7 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) { /*(assert list_in is not empty! : should not even be called in that case)*/ LttTime end = { G_MAXUINT, G_MAXUINT }; - g_assert(g_slist_length(list_in) != 0); + g_assert(g_slist_length(*list_in) != 0); lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL); } @@ -915,7 +1034,8 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) { /* 3.1 call after_chunk hooks for list_in */ { - GSList *iter = list_in; + GSList *iter = *list_in; + LttvHooks *hook_remover = lttv_hooks_new(); /* - for each request in list_in */ while(iter != NULL) { @@ -923,14 +1043,17 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) /* - Call after chunk hooks for list_in */ /* - remove hooks from context */ lttvwindowtraces_remove_computation_hooks(bg_req->module_name, - tsc); + tsc, + hook_remover); iter = g_slist_next(iter); } + lttv_hooks_call(hook_remover,tsc); + lttv_hooks_destroy(hook_remover); } /* 3.2 for each notify_in */ { - GSList *iter = notify_in; + GSList *iter = *notify_in; LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc); while(iter != NULL) { @@ -945,10 +1068,11 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) * from notify_in. */ if( (tfc != NULL && - ltt_time_compare(notify_req->notify_time, tfc->timestamp) >= 0) + ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0) || - (lttv_traceset_context_ctx_pos_compare(tsc, - notify_req->notify_position) >= 0) + (notify_req->notify_position != NULL && + lttv_traceset_context_ctx_pos_compare(tsc, + notify_req->notify_position) >= 0) ) { lttv_hooks_call(notify_req->notify, notify_req); @@ -963,8 +1087,9 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) GSList *remove_iter = iter; iter = g_slist_next(iter); - if(free_data) g_free(remove_iter->data); - notify_in = g_slist_remove_link(notify_in, remove_iter); + if(free_data) + notify_request_free((BackgroundNotify*)remove_iter->data); + *notify_in = g_slist_remove_link(*notify_in, remove_iter); } else { // not remove iter = g_slist_next(iter); } @@ -974,12 +1099,15 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) { LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc); /* 3.3 if end of trace reached */ + if(tfc != NULL) + g_debug("Current time : %lu sec, %lu nsec", + tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec); if(tfc == NULL || ltt_time_compare(tfc->timestamp, tsc->time_span.end_time) > 0) { /* - for each request in list_in */ { - GSList *iter = list_in; + GSList *iter = *list_in; while(iter != NULL) { gboolean remove = FALSE; @@ -993,6 +1121,27 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) /* - set hooks'ready flag to TRUE */ lttvwindowtraces_set_ready(bg_req->module_name, bg_req->trace); + /* - call after request hook */ + /* Get after request hook */ + LttvAttribute *module_attribute; + + g_assert(module_attribute = + LTTV_ATTRIBUTE(lttv_iattribute_find_subdir( + LTTV_IATTRIBUTE(g_attribute), + LTTV_COMPUTATION))); + + g_assert(module_attribute = + LTTV_ATTRIBUTE(lttv_iattribute_find_subdir( + LTTV_IATTRIBUTE(module_attribute), + bg_req->module_name))); + + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute), + LTTV_AFTER_REQUEST, + &value); + g_assert(type == LTTV_POINTER); + LttvHooks *after_request = (LttvHooks*)*(value.v_pointer); + + if(after_request != NULL) lttv_hooks_call(after_request, tsc); /* - remove request */ remove = TRUE; free_data = TRUE; @@ -1004,7 +1153,7 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) iter = g_slist_next(iter); if(free_data) g_free(remove_iter->data); - list_in = g_slist_remove_link(list_in, remove_iter); + *list_in = g_slist_remove_link(*list_in, remove_iter); } else { // not remove iter = g_slist_next(iter); } @@ -1013,7 +1162,7 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) /* - for each notifications in notify_in */ { - GSList *iter = notify_in; + GSList *iter = *notify_in; while(iter != NULL) { gboolean remove = FALSE; @@ -1032,30 +1181,58 @@ gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace) GSList *remove_iter = iter; iter = g_slist_next(iter); - if(free_data) g_free(remove_iter->data); - notify_in = g_slist_remove_link(notify_in, remove_iter); + if(free_data) + notify_request_free((BackgroundNotify*)remove_iter->data); + *notify_in = g_slist_remove_link(*notify_in, remove_iter); } else { // not remove iter = g_slist_next(iter); } } } - - /* - return FALSE (scheduler stopped) */ - return FALSE; + { + /* - reset the context */ + LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc); + LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts); + } + /* - if list_out is empty */ + if(g_slist_length(*list_out) == 0) { + /* - return FALSE (scheduler stopped) */ + g_debug("Background computation scheduler stopped"); + g_info("Background computation finished for trace %p", trace); + /* FIXME : remove status bar info, need context id and message id */ + ret_val = FALSE; + } else { + ret_val = TRUE; + } } else { /* 3.4 else, end of trace not reached */ /* - return TRUE (scheduler still registered) */ - return TRUE; + g_debug("Background computation left"); + ret_val = TRUE; } } } + /* 4. Unlock traces */ + { + //lttv_process_traceset_get_sync_data(tsc); + guint iter_trace; + + for(iter_trace=0; + iter_tracets); + iter_trace++) { + LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace); + + lttvwindowtraces_unlock(trace_v); + } + } + return ret_val; } /** * Register the background computation hooks for a specific module. It adds the - * computation hooks to the global attrubutes, under "computation/module name" + * computation hooks to the global attrubutes, under "computation/module name". * * @param module_name A GQuark : the name of the module which computes the * information. @@ -1070,7 +1247,9 @@ void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name, LttvHooks *before_request, LttvHooks *after_request, LttvHooks *event_hook, - LttvHooksById *event_hook_by_id) + LttvHooksById *event_hook_by_id, + LttvHooks *hook_adder, + LttvHooks *hook_remover) { LttvAttribute *g_attribute = lttv_global_attributes(); LttvAttribute *attribute; @@ -1144,6 +1323,18 @@ void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name, &value)); *(value.v_pointer) = event_hook_by_id; + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_HOOK_ADDER, + LTTV_POINTER, + &value)); + *(value.v_pointer) = hook_adder; + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_HOOK_REMOVER, + LTTV_POINTER, + &value)); + *(value.v_pointer) = hook_remover; + } @@ -1166,16 +1357,16 @@ void lttvwindowtraces_unregister_requests(LttvAttributeName module_name) LttTrace *trace; LttvAttribute *attribute = lttv_trace_attribute(trace_v); LttvAttributeValue value; - GSList *queue, *current; + GSList **queue, **current; GSList *iter; g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), LTTV_REQUESTS_QUEUE, LTTV_POINTER, &value)); - queue = (GSList*)*(value.v_pointer); + queue = (GSList**)(value.v_pointer); - iter = queue; + iter = *queue; while(iter != NULL) { gboolean remove = FALSE; gboolean free_data = FALSE; @@ -1194,7 +1385,7 @@ void lttvwindowtraces_unregister_requests(LttvAttributeName module_name) iter = g_slist_next(iter); if(free_data) g_free(remove_iter->data); - queue = g_slist_remove_link(queue, remove_iter); + *queue = g_slist_remove_link(*queue, remove_iter); } else { // not remove iter = g_slist_next(iter); } @@ -1205,9 +1396,9 @@ void lttvwindowtraces_unregister_requests(LttvAttributeName module_name) LTTV_REQUESTS_CURRENT, LTTV_POINTER, &value)); - current = (GSList*)*(value.v_pointer); + current = (GSList**)(value.v_pointer); - iter = current; + iter = *current; while(iter != NULL) { gboolean remove = FALSE; gboolean free_data = FALSE; @@ -1226,7 +1417,7 @@ void lttvwindowtraces_unregister_requests(LttvAttributeName module_name) iter = g_slist_next(iter); if(free_data) g_free(remove_iter->data); - current = g_slist_remove_link(current, remove_iter); + *current = g_slist_remove_link(*current, remove_iter); } else { // not remove iter = g_slist_next(iter); } @@ -1250,6 +1441,7 @@ void lttvwindowtraces_unregister_computation_hooks { LttvAttribute *g_attribute = lttv_global_attributes(); LttvAttribute *attribute; + LttvAttributeValue value; g_assert(attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute), @@ -1259,6 +1451,103 @@ void lttvwindowtraces_unregister_computation_hooks module_name))); + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_BEFORE_CHUNK_TRACESET, + LTTV_POINTER, + &value)); + LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer); + if(before_chunk_traceset != NULL) + lttv_hooks_destroy(before_chunk_traceset); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_BEFORE_CHUNK_TRACE, + LTTV_POINTER, + &value)); + LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer); + if(before_chunk_trace != NULL) + lttv_hooks_destroy(before_chunk_trace); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_BEFORE_CHUNK_TRACEFILE, + LTTV_POINTER, + &value)); + LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer); + if(before_chunk_tracefile != NULL) + lttv_hooks_destroy(before_chunk_tracefile); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_AFTER_CHUNK_TRACESET, + LTTV_POINTER, + &value)); + LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer); + if(after_chunk_traceset != NULL) + lttv_hooks_destroy(after_chunk_traceset); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_AFTER_CHUNK_TRACE, + LTTV_POINTER, + &value)); + LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer); + if(after_chunk_trace != NULL) + lttv_hooks_destroy(after_chunk_trace); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_AFTER_CHUNK_TRACEFILE, + LTTV_POINTER, + &value)); + LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer); + if(after_chunk_tracefile != NULL) + lttv_hooks_destroy(after_chunk_tracefile); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_BEFORE_REQUEST, + LTTV_POINTER, + &value)); + LttvHooks *before_request = (LttvHooks*)*(value.v_pointer); + if(before_request != NULL) + lttv_hooks_destroy(before_request); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_AFTER_REQUEST, + LTTV_POINTER, + &value)); + LttvHooks *after_request = (LttvHooks*)*(value.v_pointer); + if(after_request != NULL) + lttv_hooks_destroy(after_request); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_EVENT_HOOK, + LTTV_POINTER, + &value)); + LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer); + if(event_hook != NULL) + lttv_hooks_destroy(event_hook); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_EVENT_HOOK_BY_ID, + LTTV_POINTER, + &value)); + LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer); + if(event_hook_by_id != NULL) + lttv_hooks_by_id_destroy(event_hook_by_id); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_HOOK_ADDER, + LTTV_POINTER, + &value)); + LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer); + if(hook_adder != NULL) + lttv_hooks_destroy(hook_adder); + + g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute), + LTTV_HOOK_REMOVER, + LTTV_POINTER, + &value)); + LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer); + if(hook_remover != NULL) + lttv_hooks_destroy(hook_remover); + + lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), LTTV_EVENT_HOOK_BY_ID); lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), @@ -1282,6 +1571,11 @@ void lttvwindowtraces_unregister_computation_hooks LTTV_BEFORE_CHUNK_TRACE); lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), LTTV_BEFORE_CHUNK_TRACESET); + lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), + LTTV_HOOK_ADDER); + lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), + LTTV_HOOK_REMOVER); + /* finally, remove module name */ g_assert(attribute = LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute), @@ -1291,4 +1585,82 @@ void lttvwindowtraces_unregister_computation_hooks } +/** + * Lock a trace so no other instance can use it. + * + * @param trace The trace to lock. + * @return 0 on success, -1 if cannot get lock. + */ +gint lttvwindowtraces_lock(LttvTrace *trace) +{ + LttvAttribute *attribute = lttv_trace_attribute(trace); + LttvAttributeValue value; + LttvAttributeType type; + + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), + LTTV_LOCK, + &value); + /* Verify the absence of the lock. */ + if(type != LTTV_NONE) { + g_critical("Cannot take trace lock"); + return -1; + } + + value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute), + LTTV_LOCK, + LTTV_INT); + /* the value is left unset. The only presence of the attribute is necessary. + */ + + return 0; +} + +/** + * Unlock a trace. + * + * @param trace The trace to unlock. + * @return 0 on success, -1 if cannot unlock (not locked ?). + */ +gint lttvwindowtraces_unlock(LttvTrace *trace) +{ + LttvAttribute *attribute = lttv_trace_attribute(trace); + LttvAttributeType type; + LttvAttributeValue value; + + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), + LTTV_LOCK, + &value); + /* Verify the presence of the lock. */ + if(type == LTTV_NONE) { + g_critical("Cannot release trace lock"); + return -1; + } + + lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute), + LTTV_LOCK); + + return 0; +} + +/** + * Verify if a trace is locked. + * + * @param trace The trace to verify. + * @return TRUE if locked, FALSE is unlocked. + */ +gint lttvwindowtraces_get_lock_state(LttvTrace *trace) +{ + LttvAttribute *attribute = lttv_trace_attribute(trace); + LttvAttributeType type; + LttvAttributeValue value; + + type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute), + LTTV_LOCK, + &value); + /* The only presence of the attribute is necessary. */ + if(type == LTTV_NONE) + return FALSE; + else + return TRUE; +}