+
+
+
+/**
+ * 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;
+}
+