+/* 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.
LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
LttTrace *trace;
gchar *name;
-
g_assert(trace_v != NULL);
trace = lttv_trace(trace_v);
/* create new traceset and tracesetcontext */
LttvTraceset *ts;
- LttvTracesetContext *tsc;
+ LttvTracesetStats *tss;
attribute = lttv_trace_attribute(trace);
g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
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,
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);
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);
{
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;
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);
}
/**
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);
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.
*
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,
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);
}
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);
}
/* 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;
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 =
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,
}
void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
- LttvTracesetContext *tsc)
+ LttvTracesetContext *tsc,
+ LttvHooks *hook_remover)
{
LttvAttribute *g_attribute = lttv_global_attributes();
LttvAttribute *module_attribute;
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),
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));
+ }
}
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);
}
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);
}
}
-
/* lttvwindowtraces_process_pending_requests
*
* This internal function gets called by g_idle, taking care of the pending
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);
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,
&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_trace<lttv_traceset_number(tsc->ts);
+ 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;
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)
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);
}
}
{
- 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);
}
/* - 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;
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)
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);
}
}
{
- GSList *iter = list_in;
+ GSList *iter = *list_in;
+ LttvHooks *hook_adder = lttv_hooks_new();
/* - for each request in list_in */
while(iter != NULL) {
/*- 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);
}
}
{
/*(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);
}
{
/* 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) {
/* - 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) {
* 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);
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);
}
{
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;
/* - 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;
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);
}
/* - for each notifications in notify_in */
{
- GSList *iter = notify_in;
+ GSList *iter = *notify_in;
while(iter != NULL) {
gboolean remove = FALSE;
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_trace<lttv_traceset_number(tsc->ts);
+ 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".
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ * information.
+ */
+void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
+ LttvHooks *before_chunk_traceset,
+ LttvHooks *before_chunk_trace,
+ LttvHooks *before_chunk_tracefile,
+ LttvHooks *after_chunk_traceset,
+ LttvHooks *after_chunk_trace,
+ LttvHooks *after_chunk_tracefile,
+ LttvHooks *before_request,
+ LttvHooks *after_request,
+ LttvHooks *event_hook,
+ LttvHooksById *event_hook_by_id,
+ LttvHooks *hook_adder,
+ LttvHooks *hook_remover)
+{
+ LttvAttribute *g_attribute = lttv_global_attributes();
+ LttvAttribute *attribute;
+ LttvAttributeValue value;
+
+ g_assert(attribute =
+ LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+ LTTV_COMPUTATION)));
+
+ g_assert(attribute =
+ LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+ module_name)));
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_BEFORE_CHUNK_TRACESET,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = before_chunk_traceset;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_BEFORE_CHUNK_TRACE,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = before_chunk_trace;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_BEFORE_CHUNK_TRACEFILE,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = before_chunk_tracefile;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_CHUNK_TRACESET,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = after_chunk_traceset;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_CHUNK_TRACE,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = after_chunk_trace;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_CHUNK_TRACEFILE,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = after_chunk_tracefile;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_BEFORE_REQUEST,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = before_request;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_REQUEST,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = after_request;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_EVENT_HOOK,
+ LTTV_POINTER,
+ &value));
+ *(value.v_pointer) = event_hook;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_EVENT_HOOK_BY_ID,
+ LTTV_POINTER,
+ &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;
+
+}
+
+
+/**
+ * It removes all the requests than can be currently processed by the
+ * background computation algorithm for all the traces (list_in and list_out).
+ *
+ * Leaves the flag to in_progress or none.. depending if current or queue
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ * information.
+ */
+void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
+{
+ guint i;
+
+ for(i=0;i<lttvwindowtraces_get_number();i++) {
+ LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
+ g_assert(trace_v != NULL);
+ LttTrace *trace;
+ LttvAttribute *attribute = lttv_trace_attribute(trace_v);
+ LttvAttributeValue value;
+ GSList **queue, **current;
+ GSList *iter;
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_REQUESTS_QUEUE,
+ LTTV_POINTER,
+ &value));
+ queue = (GSList**)(value.v_pointer);
+
+ iter = *queue;
+ while(iter != NULL) {
+ gboolean remove = FALSE;
+ gboolean free_data = FALSE;
+
+ BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+
+ if(bg_req->module_name == module_name) {
+ remove = TRUE;
+ free_data = TRUE;
+ }
+
+ /* Go to next */
+ if(remove)
+ {
+ GSList *remove_iter = iter;
+
+ iter = g_slist_next(iter);
+ if(free_data) g_free(remove_iter->data);
+ *queue = g_slist_remove_link(*queue, remove_iter);
+ } else { // not remove
+ iter = g_slist_next(iter);
+ }
+ }
+
+
+ g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
+ LTTV_REQUESTS_CURRENT,
+ LTTV_POINTER,
+ &value));
+ current = (GSList**)(value.v_pointer);
+
+ iter = *current;
+ while(iter != NULL) {
+ gboolean remove = FALSE;
+ gboolean free_data = FALSE;
+
+ BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
+
+ if(bg_req->module_name == module_name) {
+ remove = TRUE;
+ free_data = TRUE;
+ }
+
+ /* Go to next */
+ if(remove)
+ {
+ GSList *remove_iter = iter;
+
+ iter = g_slist_next(iter);
+ if(free_data) g_free(remove_iter->data);
+ *current = g_slist_remove_link(*current, remove_iter);
+ } else { // not remove
+ iter = g_slist_next(iter);
}
}
}
}
+
+
+/**
+ * Unregister the background computation hooks for a specific module.
+ *
+ * It also removes all the requests than can be currently processed by the
+ * background computation algorithm for all the traces (list_in and list_out).
+ *
+ * @param module_name A GQuark : the name of the module which computes the
+ * information.
+ */
+
+void lttvwindowtraces_unregister_computation_hooks
+ (LttvAttributeName module_name)
+{
+ LttvAttribute *g_attribute = lttv_global_attributes();
+ LttvAttribute *attribute;
+ LttvAttributeValue value;
+
+ g_assert(attribute =
+ LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
+ LTTV_COMPUTATION)));
+ g_assert(attribute =
+ LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
+ 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),
+ LTTV_EVENT_HOOK);
+
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_REQUEST);
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ LTTV_BEFORE_REQUEST);
+
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_CHUNK_TRACEFILE);
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_CHUNK_TRACE);
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ LTTV_AFTER_CHUNK_TRACESET);
+
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ LTTV_BEFORE_CHUNK_TRACEFILE);
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ 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),
+ LTTV_COMPUTATION)));
+ lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
+ module_name);
+
+}
+
+/**
+ * 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;
+}
+