1 /* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 /* This file is the API used to launch any background computation on a trace */
21 /* Here is the implementation of the API */
27 #include <sys/types.h>
33 #include <ltt/trace.h>
35 #include <lttv/lttv.h>
36 #include <lttv/traceset.h>
37 #include <lttv/attribute.h>
38 #include <lttv/tracecontext.h>
39 #include <lttvwindow/lttvwindowtraces.h>
40 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
41 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
43 extern GSList * g_main_window_list;
45 typedef struct _BackgroundRequest {
46 LttvAttributeName module_name; /* Hook path in global attributes,
47 where all standard hooks under computation/.
49 LttvTrace *trace; /* trace concerned */
50 GtkWidget *dialog; /* Dialog linked with the request, may be NULL */
51 GtkWidget *parent_window; /* Parent window the dialog must be transient for */
54 typedef struct _BackgroundNotify {
56 LttvTrace *trace; /* trace */
58 LttvTracesetContextPosition *notify_position;
59 LttvHooks *notify; /* Hook to call when the notify is
60 passed, or at the end of trace */
66 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
68 /* Get a trace by its path name.
70 * @param path path of the trace on the virtual file system.
71 * @return Pointer to trace if found
72 * NULL is returned if the trace is not present
75 LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
79 for(i=0;i<lttvwindowtraces_get_number();i++) {
80 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
83 g_assert(trace_v != NULL);
85 trace = lttv_trace(trace_v);
86 g_assert(trace != NULL);
87 name = g_quark_to_string(ltt_trace_name(trace));
89 if(strcmp(name, path) == 0) {
98 /* Get a trace by its number identifier */
100 LttvTrace *lttvwindowtraces_get_trace(guint num)
102 LttvAttribute *g_attribute = lttv_global_attributes();
103 LttvAttribute *attribute;
104 LttvAttributeType type;
105 LttvAttributeName name;
106 LttvAttributeValue value;
110 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
113 type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value,
116 if(type == LTTV_POINTER) {
117 return (LttvTrace *)*(value.v_pointer);
123 /* Total number of traces */
125 guint lttvwindowtraces_get_number()
127 LttvAttribute *g_attribute = lttv_global_attributes();
128 LttvAttribute *attribute;
129 LttvAttributeValue value;
132 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
135 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute)) );
138 /* Add a trace to the global attributes */
140 void lttvwindowtraces_add_trace(LttvTrace *trace)
142 LttvAttribute *g_attribute = lttv_global_attributes();
143 LttvAttribute *attribute;
144 LttvAttributeValue value;
147 gchar attribute_path[PATH_MAX];
149 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace))), &buf)) {
150 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
151 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
155 snprintf(attribute_path, PATH_MAX, "%llu:%llu", buf.st_dev, buf.st_ino) >= 0);
158 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
161 value = lttv_attribute_add(attribute,
162 g_quark_from_string(attribute_path),
165 *(value.v_pointer) = (gpointer)trace;
167 /* create new traceset and tracesetcontext */
169 LttvTracesetStats *tss;
170 //LttvTracesetContextPosition *sync_position;
172 attribute = lttv_trace_attribute(trace);
173 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
174 LTTV_COMPUTATION_TRACESET,
177 ts = lttv_traceset_new();
178 *(value.v_pointer) = ts;
180 lttv_traceset_add(ts,trace);
182 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
183 LTTV_COMPUTATION_TRACESET_CONTEXT,
186 tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
187 *(value.v_pointer) = tss;
189 lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
191 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
192 LTTV_COMPUTATION_SYNC_POSITION,
196 sync_position = lttv_traceset_context_position_new();
197 *(value.v_pointer) = sync_position;
199 value = lttv_attribute_add(attribute,
203 value = lttv_attribute_add(attribute,
204 LTTV_REQUESTS_CURRENT,
207 value = lttv_attribute_add(attribute,
211 value = lttv_attribute_add(attribute,
216 /* Remove a trace from the global attributes */
218 void lttvwindowtraces_remove_trace(LttvTrace *trace)
220 LttvAttribute *g_attribute = lttv_global_attributes();
221 LttvAttribute *attribute;
222 LttvAttributeValue value;
226 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
229 for(i=0;i<lttvwindowtraces_get_number();i++) {
230 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
232 g_assert(trace_v != NULL);
234 /* Remove and background computation that could be in progress */
235 g_idle_remove_by_data(trace_v);
237 if(trace_v == trace) {
239 LttvAttribute *l_attribute;
241 /* destroy traceset and tracesetcontext */
243 LttvTracesetStats *tss;
244 //LttvTracesetContextPosition *sync_position;
246 l_attribute = lttv_trace_attribute(trace);
249 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
250 LTTV_REQUESTS_QUEUE);
252 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
253 LTTV_REQUESTS_CURRENT);
255 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
258 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
259 LTTV_NOTIFY_CURRENT);
261 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
262 LTTV_COMPUTATION_TRACESET,
265 ts = (LttvTraceset*)*(value.v_pointer);
267 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
268 LTTV_COMPUTATION_SYNC_POSITION,
271 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
272 lttv_traceset_context_position_destroy(sync_position);
274 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
275 LTTV_COMPUTATION_SYNC_POSITION);
278 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
279 LTTV_COMPUTATION_TRACESET_CONTEXT,
282 tss = (LttvTracesetStats*)*(value.v_pointer);
284 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
286 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
287 LTTV_COMPUTATION_TRACESET_CONTEXT);
288 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
289 LTTV_COMPUTATION_TRACESET);
290 /* Destroy the traceset and the trace also */
291 lttv_traceset_destroy(ts);
293 /* finally, remove the global attribute */
294 lttv_attribute_remove(attribute, i);
301 static void destroy_dialog(BackgroundRequest *bg_req)
303 gtk_widget_destroy(bg_req->dialog);
304 bg_req->dialog = NULL;
309 * Function to request data from a specific trace
311 * The memory allocated for the request will be managed by the API.
313 * @param widget the current Window
314 * @param trace the trace to compute
315 * @param module_name the name of the module which registered global computation
319 void lttvwindowtraces_background_request_queue
320 (GtkWidget *widget, LttvTrace *trace, gchar *module_name)
322 BackgroundRequest *bg_req;
323 LttvAttribute *attribute = lttv_trace_attribute(trace);
324 LttvAttribute *g_attribute = lttv_global_attributes();
325 LttvAttribute *module_attribute;
326 LttvAttributeValue value;
327 LttvAttributeType type;
331 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
335 slist = (GSList**)(value.v_pointer);
337 /* Verify that the calculator is loaded */
338 g_assert(module_attribute =
339 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
343 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
344 g_quark_from_string(module_name),
346 if(type == LTTV_NONE) {
347 g_critical("Missing background calculator %s", module_name);
351 bg_req = g_new(BackgroundRequest,1);
352 bg_req->module_name = g_quark_from_string(module_name);
353 bg_req->trace = trace;
355 *slist = g_slist_append(*slist, bg_req);
357 /* Priority lower than live servicing */
358 g_idle_remove_by_data(trace);
359 g_idle_add_full((G_PRIORITY_HIGH_IDLE + 23),
360 (GSourceFunc)lttvwindowtraces_process_pending_requests,
363 /* FIXME : show message in status bar, need context and message id */
364 g_info("Background computation for %s started for trace %p", module_name,
367 gtk_message_dialog_new(
369 GTK_DIALOG_DESTROY_WITH_PARENT,
370 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
371 "Background computation for %s started for trace %s",
373 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
374 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(widget));
375 g_signal_connect_swapped (dialog, "response",
376 G_CALLBACK (destroy_dialog),
378 bg_req->dialog = dialog;
379 /* the parent window might vanish : only use this pointer for a
380 * comparison with existing windows */
381 bg_req->parent_window = gtk_widget_get_toplevel(widget);
382 gtk_widget_show(dialog);
386 * Remove a background request from a trace.
388 * This should ONLY be used by the modules which registered the global hooks
389 * (module_name). If this is called by the viewers, it may lead to incomplete
390 * and incoherent background processing information.
392 * Even if the module which deals with the hooks removes the background
393 * requests, it may cause a problem if the module gets loaded again in the
394 * session : the data will be partially calculated. The calculation function
395 * must deal with this case correctly.
397 * @param trace the trace to compute
398 * @param module_name the name of the module which registered global computation
402 void lttvwindowtraces_background_request_remove
403 (LttvTrace *trace, gchar *module_name)
405 LttvAttribute *attribute = lttv_trace_attribute(trace);
406 LttvAttributeValue value;
410 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
414 slist = (GSList**)(value.v_pointer);
416 for(iter=*slist;iter!=NULL;) {
417 BackgroundRequest *bg_req =
418 (BackgroundRequest *)iter->data;
420 if(bg_req->module_name == g_quark_from_string(module_name)) {
421 GSList *rem_iter = iter;
422 iter=g_slist_next(iter);
424 *slist = g_slist_delete_link(*slist, rem_iter);
426 iter=g_slist_next(iter);
432 * Find a background request in a trace
436 gboolean lttvwindowtraces_background_request_find
437 (LttvTrace *trace, gchar *module_name)
439 LttvAttribute *attribute = lttv_trace_attribute(trace);
440 LttvAttributeValue value;
444 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
448 slist = (GSList**)(value.v_pointer);
450 for(iter=*slist;iter!=NULL;) {
451 BackgroundRequest *bg_req =
452 (BackgroundRequest *)iter->data;
454 if(bg_req->module_name == g_quark_from_string(module_name)) {
457 iter=g_slist_next(iter);
464 * Register a callback to be called when requested data is passed in the next
465 * queued background processing.
467 * @param owner owner of the background notification
468 * @param trace the trace computed
469 * @param notify_time time when notification hooks must be called
470 * @param notify_position position when notification hooks must be called
471 * @param notify Hook to call when the notify position is passed
474 void lttvwindowtraces_background_notify_queue
478 const LttvTracesetContextPosition *notify_position,
479 const LttvHooks *notify)
481 BackgroundNotify *bg_notify;
482 LttvAttribute *attribute = lttv_trace_attribute(trace);
483 LttvAttributeValue value;
486 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
490 slist = (GSList**)(value.v_pointer);
492 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
493 LTTV_COMPUTATION_TRACESET_CONTEXT,
496 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
498 bg_notify = g_new(BackgroundNotify,1);
500 bg_notify->owner = owner;
501 bg_notify->trace = trace;
502 bg_notify->notify_time = notify_time;
503 if(notify_position != NULL) {
504 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
505 lttv_traceset_context_position_copy(bg_notify->notify_position,
508 bg_notify->notify_position = NULL;
511 bg_notify->notify = lttv_hooks_new();
512 lttv_hooks_add_list(bg_notify->notify, notify);
514 *slist = g_slist_append(*slist, bg_notify);
518 * Register a callback to be called when requested data is passed in the current
519 * background processing.
521 * @param owner owner of the background notification
522 * @param trace the trace computed
523 * @param notify_time time when notification hooks must be called
524 * @param notify_position position when notification hooks must be called
525 * @param notify Hook to call when the notify position is passed
528 void lttvwindowtraces_background_notify_current
532 const LttvTracesetContextPosition *notify_position,
533 const LttvHooks *notify)
535 BackgroundNotify *bg_notify;
536 LttvAttribute *attribute = lttv_trace_attribute(trace);
537 LttvAttributeValue value;
540 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
544 slist = (GSList**)(value.v_pointer);
546 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
547 LTTV_COMPUTATION_TRACESET_CONTEXT,
550 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
553 bg_notify = g_new(BackgroundNotify,1);
555 bg_notify->owner = owner;
556 bg_notify->trace = trace;
557 bg_notify->notify_time = notify_time;
558 if(notify_position!= NULL) {
559 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
560 lttv_traceset_context_position_copy(bg_notify->notify_position,
563 bg_notify->notify_position = NULL;
565 bg_notify->notify = lttv_hooks_new();
566 lttv_hooks_add_list(bg_notify->notify, notify);
568 *slist = g_slist_append(*slist, bg_notify);
572 static void notify_request_free(BackgroundNotify *notify_req)
574 if(notify_req == NULL) return;
576 if(notify_req->notify_position != NULL)
577 lttv_traceset_context_position_destroy(notify_req->notify_position);
578 if(notify_req->notify != NULL)
579 lttv_hooks_destroy(notify_req->notify);
584 * Removes all the notifications requests from a specific viewer.
586 * @param owner owner of the background notification
589 void lttvwindowtraces_background_notify_remove(gpointer owner)
593 for(i=0;i<lttvwindowtraces_get_number();i++) {
594 LttvAttribute *attribute;
595 LttvAttributeValue value;
596 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
600 g_assert(trace_v != NULL);
602 attribute = lttv_trace_attribute(trace_v);
604 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
608 slist = (GSList**)(value.v_pointer);
610 for(iter=*slist;iter!=NULL;) {
612 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
614 if(bg_notify->owner == owner) {
615 GSList *rem_iter = iter;
616 iter=g_slist_next(iter);
617 notify_request_free(bg_notify);
618 *slist = g_slist_remove_link(*slist, rem_iter);
620 iter=g_slist_next(iter);
624 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
628 slist = (GSList**)(value.v_pointer);
630 for(iter=*slist;iter!=NULL;) {
632 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
634 if(bg_notify->owner == owner) {
635 GSList *rem_iter = iter;
636 iter=g_slist_next(iter);
637 notify_request_free(bg_notify);
638 *slist = g_slist_remove_link(*slist, rem_iter);
640 iter=g_slist_next(iter);
647 /* Background processing helper functions */
649 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
650 LttvTracesetContext *tsc,
651 LttvHooks *hook_adder)
653 LttvAttribute *g_attribute = lttv_global_attributes();
654 LttvAttribute *module_attribute;
655 LttvAttributeType type;
656 LttvAttributeValue value;
659 g_assert(module_attribute =
660 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
663 g_assert(module_attribute =
664 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
665 LTTV_IATTRIBUTE(module_attribute),
668 /* Call the module's hook adder */
669 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
672 if(type == LTTV_POINTER) {
673 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
674 if(hook_adder != NULL)
675 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
679 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
680 LttvTracesetContext *tsc,
681 LttvHooks *hook_remover)
683 LttvAttribute *g_attribute = lttv_global_attributes();
684 LttvAttribute *module_attribute;
685 LttvAttributeType type;
686 LttvAttributeValue value;
688 g_assert(module_attribute =
689 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
692 g_assert(module_attribute =
693 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
694 LTTV_IATTRIBUTE(module_attribute),
697 /* Call the module's hook remover */
698 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
701 if(type == LTTV_POINTER) {
702 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
703 if(hook_remover != NULL)
704 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
708 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
709 LttvTracesetContext *tsc)
711 LttvAttribute *g_attribute = lttv_global_attributes();
712 LttvAttribute *module_attribute;
713 LttvAttributeType type;
714 LttvAttributeValue value;
715 LttvHooks *before_chunk_traceset=NULL;
716 LttvHooks *before_chunk_trace=NULL;
717 LttvHooks *before_chunk_tracefile=NULL;
718 LttvHooks *event_hook=NULL;
719 LttvHooksById *event_hook_by_id=NULL;
720 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
723 g_assert(module_attribute =
724 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
727 g_assert(module_attribute =
728 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
729 LTTV_IATTRIBUTE(module_attribute),
732 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
733 LTTV_BEFORE_CHUNK_TRACESET,
735 if(type == LTTV_POINTER) {
736 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
739 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
740 LTTV_BEFORE_CHUNK_TRACE,
742 if(type == LTTV_POINTER) {
743 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
746 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
747 LTTV_BEFORE_CHUNK_TRACEFILE,
749 if(type == LTTV_POINTER) {
750 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
753 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
756 if(type == LTTV_POINTER) {
757 event_hook = (LttvHooks*)*(value.v_pointer);
760 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
761 LTTV_EVENT_HOOK_BY_ID,
763 if(type == LTTV_POINTER) {
764 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
767 lttv_process_traceset_begin(tsc,
768 before_chunk_traceset,
770 before_chunk_tracefile,
777 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
778 LttvTracesetContext *tsc)
780 LttvAttribute *g_attribute = lttv_global_attributes();
781 LttvAttribute *module_attribute;
782 LttvAttributeType type;
783 LttvAttributeValue value;
784 LttvHooks *after_chunk_traceset=NULL;
785 LttvHooks *after_chunk_trace=NULL;
786 LttvHooks *after_chunk_tracefile=NULL;
787 LttvHooks *event_hook=NULL;
788 LttvHooksById *event_hook_by_id=NULL;
789 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
791 g_assert(module_attribute =
792 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
795 g_assert(module_attribute =
796 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
797 LTTV_IATTRIBUTE(module_attribute),
800 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
801 LTTV_AFTER_CHUNK_TRACESET,
803 if(type == LTTV_POINTER) {
804 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
807 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
808 LTTV_AFTER_CHUNK_TRACE,
810 if(type == LTTV_POINTER) {
811 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
814 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
815 LTTV_AFTER_CHUNK_TRACEFILE,
817 if(type == LTTV_POINTER) {
818 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
821 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
824 if(type == LTTV_POINTER) {
825 event_hook = (LttvHooks*)*(value.v_pointer);
828 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
829 LTTV_EVENT_HOOK_BY_ID,
831 if(type == LTTV_POINTER) {
832 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
835 lttv_process_traceset_end(tsc,
836 after_chunk_traceset,
838 after_chunk_tracefile,
845 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
848 LttvAttribute *attribute = lttv_trace_attribute(trace);
849 LttvAttributeValue value;
852 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
855 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
858 /* the value is left unset. The only presence of the attribute is necessary.
862 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
865 LttvAttribute *attribute = lttv_trace_attribute(trace);
868 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
871 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
875 gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
878 LttvAttribute *attribute = lttv_trace_attribute(trace);
879 LttvAttributeType type;
880 LttvAttributeValue value;
883 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
886 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
889 /* The only presence of the attribute is necessary. */
890 if(type == LTTV_NONE)
896 void lttvwindowtraces_set_ready(LttvAttributeName module_name,
899 LttvAttribute *attribute = lttv_trace_attribute(trace);
900 LttvAttributeValue value;
903 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
906 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
909 /* the value is left unset. The only presence of the attribute is necessary.
913 void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
916 LttvAttribute *attribute = lttv_trace_attribute(trace);
919 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
922 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
926 gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
929 LttvAttribute *attribute = lttv_trace_attribute(trace);
930 LttvAttributeType type;
931 LttvAttributeValue value;
934 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
937 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
940 /* The only presence of the attribute is necessary. */
941 if(type == LTTV_NONE)
947 static gint find_window_widget(MainWindow *a, GtkWidget *b)
949 if(a->mwindow == b) return 0;
954 /* lttvwindowtraces_process_pending_requests
956 * This internal function gets called by g_idle, taking care of the pending
962 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
964 LttvTracesetContext *tsc;
965 LttvTracesetStats *tss;
967 //LttvTracesetContextPosition *sync_position;
968 LttvAttribute *attribute;
969 LttvAttribute *g_attribute = lttv_global_attributes();
970 GSList **list_out, **list_in, **notify_in, **notify_out;
971 LttvAttributeValue value;
972 LttvAttributeType type;
978 if(lttvwindow_preempt_count > 0) return TRUE;
980 attribute = lttv_trace_attribute(trace);
982 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
985 g_assert(type == LTTV_POINTER);
986 list_out = (GSList**)(value.v_pointer);
988 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
989 LTTV_REQUESTS_CURRENT,
991 g_assert(type == LTTV_POINTER);
992 list_in = (GSList**)(value.v_pointer);
994 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
997 g_assert(type == LTTV_POINTER);
998 notify_out = (GSList**)(value.v_pointer);
1000 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1001 LTTV_NOTIFY_CURRENT,
1003 g_assert(type == LTTV_POINTER);
1004 notify_in = (GSList**)(value.v_pointer);
1006 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1007 LTTV_COMPUTATION_TRACESET,
1009 g_assert(type == LTTV_POINTER);
1010 ts = (LttvTraceset*)*(value.v_pointer);
1012 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1013 LTTV_COMPUTATION_TRACESET_CONTEXT,
1015 g_assert(type == LTTV_POINTER);
1016 tsc = (LttvTracesetContext*)*(value.v_pointer);
1017 tss = (LttvTracesetStats*)*(value.v_pointer);
1018 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
1019 g_assert(LTTV_IS_TRACESET_STATS(tss));
1021 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1022 LTTV_COMPUTATION_SYNC_POSITION,
1024 g_assert(type == LTTV_POINTER);
1025 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
1027 /* There is no events requests pending : we should never have been called! */
1028 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
1029 /* 0.1 Lock traces */
1034 iter_trace<lttv_traceset_number(tsc->ts);
1036 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
1038 if(lttvwindowtraces_lock(trace_v) != 0)
1039 return TRUE; /* Cannot get trace lock, try later */
1043 /* 0.2 Sync tracefiles */
1044 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1045 lttv_process_traceset_synchronize_tracefiles(tsc);
1046 /* 1. Before processing */
1048 /* if list_in is empty */
1049 if(g_slist_length(*list_in) == 0) {
1052 /* - Add all requests in list_out to list_in, empty list_out */
1053 GSList *iter = *list_out;
1055 while(iter != NULL) {
1056 gboolean remove = FALSE;
1057 gboolean free_data = FALSE;
1059 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1063 *list_in = g_slist_append(*list_in, bg_req);
1068 GSList *remove_iter = iter;
1070 iter = g_slist_next(iter);
1071 if(free_data) g_free(remove_iter->data);
1072 *list_out = g_slist_remove_link(*list_out, remove_iter);
1073 } else { // not remove
1074 iter = g_slist_next(iter);
1080 GSList *iter = *list_in;
1081 /* - for each request in list_in */
1082 while(iter != NULL) {
1084 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1085 /* - set hooks'in_progress flag to TRUE */
1086 lttvwindowtraces_set_in_progress(bg_req->module_name,
1089 /* - call before request hook */
1090 /* Get before request hook */
1091 LttvAttribute *module_attribute;
1093 g_assert(module_attribute =
1094 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1095 LTTV_IATTRIBUTE(g_attribute),
1096 LTTV_COMPUTATION)));
1098 g_assert(module_attribute =
1099 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1100 LTTV_IATTRIBUTE(module_attribute),
1101 bg_req->module_name)));
1103 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1104 LTTV_BEFORE_REQUEST,
1106 g_assert(type == LTTV_POINTER);
1107 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1109 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
1111 iter = g_slist_next(iter);
1115 /* - seek trace to start */
1117 LttTime start = { 0, 0};
1118 lttv_process_traceset_seek_time(tsc, start);
1121 /* - Move all notifications from notify_out to notify_in. */
1123 GSList *iter = *notify_out;
1124 g_assert(g_slist_length(*notify_in) == 0);
1126 while(iter != NULL) {
1127 gboolean remove = FALSE;
1128 gboolean free_data = FALSE;
1130 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1134 *notify_in = g_slist_append(*notify_in, notify_req);
1139 GSList *remove_iter = iter;
1141 iter = g_slist_next(iter);
1143 notify_request_free((BackgroundNotify*)remove_iter->data);
1144 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
1145 } else { // not remove
1146 iter = g_slist_next(iter);
1151 GSList *iter = *list_in;
1152 LttvHooks *hook_adder = lttv_hooks_new();
1153 /* - for each request in list_in */
1154 while(iter != NULL) {
1156 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1157 /*- add hooks to context*/
1158 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1161 iter = g_slist_next(iter);
1163 lttv_hooks_call(hook_adder,tsc);
1164 lttv_hooks_destroy(hook_adder);
1171 GSList *iter = *list_in;
1172 /* - for each request in list_in */
1173 while(iter != NULL) {
1175 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1176 /*- Call before chunk hooks for list_in*/
1177 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1179 iter = g_slist_next(iter);
1184 /* 2. call process traceset middle for a chunk */
1186 /*(assert list_in is not empty! : should not even be called in that case)*/
1187 LttTime end = ltt_time_infinite;
1188 g_assert(g_slist_length(*list_in) != 0);
1190 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1193 /* 3. After the chunk */
1195 /* 3.1 call after_chunk hooks for list_in */
1197 GSList *iter = *list_in;
1198 /* - for each request in list_in */
1199 while(iter != NULL) {
1201 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1202 /* - Call after chunk hooks for list_in */
1203 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1205 iter = g_slist_next(iter);
1209 /* 3.2 for each notify_in */
1211 GSList *iter = *notify_in;
1212 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1214 while(iter != NULL) {
1215 gboolean remove = FALSE;
1216 gboolean free_data = FALSE;
1218 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1220 /* - if current time >= notify time, call notify and remove from
1222 * - if current position >= notify position, call notify and remove
1226 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
1228 (notify_req->notify_position != NULL &&
1229 lttv_traceset_context_ctx_pos_compare(tsc,
1230 notify_req->notify_position) >= 0)
1233 lttv_hooks_call(notify_req->notify, notify_req);
1242 GSList *remove_iter = iter;
1244 iter = g_slist_next(iter);
1246 notify_request_free((BackgroundNotify*)remove_iter->data);
1247 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1248 } else { // not remove
1249 iter = g_slist_next(iter);
1255 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1256 /* 3.3 if end of trace reached */
1258 g_debug("Current time : %lu sec, %lu nsec",
1259 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
1260 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1261 tsc->time_span.end_time) > 0) {
1264 GSList *iter = *list_in;
1265 LttvHooks *hook_remover = lttv_hooks_new();
1266 /* - for each request in list_in */
1267 while(iter != NULL) {
1269 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1270 /* - remove hooks from context */
1271 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1274 iter = g_slist_next(iter);
1276 lttv_hooks_call(hook_remover,tsc);
1277 lttv_hooks_destroy(hook_remover);
1280 /* - for each request in list_in */
1282 GSList *iter = *list_in;
1284 while(iter != NULL) {
1285 gboolean remove = FALSE;
1286 gboolean free_data = FALSE;
1288 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1290 /* - set hooks'in_progress flag to FALSE */
1291 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1293 /* - set hooks'ready flag to TRUE */
1294 lttvwindowtraces_set_ready(bg_req->module_name,
1296 /* - call after request hook */
1297 /* Get after request hook */
1298 LttvAttribute *module_attribute;
1300 g_assert(module_attribute =
1301 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1302 LTTV_IATTRIBUTE(g_attribute),
1303 LTTV_COMPUTATION)));
1305 g_assert(module_attribute =
1306 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1307 LTTV_IATTRIBUTE(module_attribute),
1308 bg_req->module_name)));
1310 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1313 g_assert(type == LTTV_POINTER);
1314 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1316 if(after_request != NULL) lttv_hooks_call(after_request, tsc);
1318 if(bg_req->dialog != NULL)
1319 gtk_widget_destroy(bg_req->dialog);
1320 GtkWidget *parent_window;
1321 if(g_slist_find_custom(g_main_window_list,
1322 bg_req->parent_window,
1323 (GCompareFunc)find_window_widget))
1324 parent_window = GTK_WIDGET(bg_req->parent_window);
1326 parent_window = NULL;
1329 gtk_message_dialog_new(GTK_WINDOW(parent_window),
1330 GTK_DIALOG_DESTROY_WITH_PARENT,
1331 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1332 "Background computation %s finished for trace %s",
1333 g_quark_to_string(bg_req->module_name),
1334 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
1335 if(parent_window != NULL)
1336 gtk_window_set_transient_for(GTK_WINDOW(dialog),
1337 GTK_WINDOW(parent_window));
1338 g_signal_connect_swapped (dialog, "response",
1339 G_CALLBACK (gtk_widget_destroy),
1341 gtk_widget_show(dialog);
1343 /* - remove request */
1350 GSList *remove_iter = iter;
1352 iter = g_slist_next(iter);
1353 if(free_data) g_free(remove_iter->data);
1354 *list_in = g_slist_remove_link(*list_in, remove_iter);
1355 } else { // not remove
1356 iter = g_slist_next(iter);
1361 /* - for each notifications in notify_in */
1363 GSList *iter = *notify_in;
1365 while(iter != NULL) {
1366 gboolean remove = FALSE;
1367 gboolean free_data = FALSE;
1369 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1371 /* - call notify and remove from notify_in */
1372 lttv_hooks_call(notify_req->notify, notify_req);
1379 GSList *remove_iter = iter;
1381 iter = g_slist_next(iter);
1383 notify_request_free((BackgroundNotify*)remove_iter->data);
1384 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1385 } else { // not remove
1386 iter = g_slist_next(iter);
1391 /* - reset the context */
1392 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1393 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1395 /* - if list_out is empty */
1396 if(g_slist_length(*list_out) == 0) {
1397 /* - return FALSE (scheduler stopped) */
1398 g_debug("Background computation scheduler stopped");
1399 g_info("Background computation finished for trace %p", trace);
1400 /* FIXME : remove status bar info, need context id and message id */
1407 /* 3.4 else, end of trace not reached */
1408 /* - return TRUE (scheduler still registered) */
1409 g_debug("Background computation left");
1414 /* 4. Unlock traces */
1416 lttv_process_traceset_get_sync_data(tsc);
1417 //lttv_traceset_context_position_save(tsc, sync_position);
1421 iter_trace<lttv_traceset_number(tsc->ts);
1423 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1425 lttvwindowtraces_unlock(trace_v);
1434 * Register the background computation hooks for a specific module. It adds the
1435 * computation hooks to the global attrubutes, under "computation/module name".
1437 * @param module_name A GQuark : the name of the module which computes the
1440 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1441 LttvHooks *before_chunk_traceset,
1442 LttvHooks *before_chunk_trace,
1443 LttvHooks *before_chunk_tracefile,
1444 LttvHooks *after_chunk_traceset,
1445 LttvHooks *after_chunk_trace,
1446 LttvHooks *after_chunk_tracefile,
1447 LttvHooks *before_request,
1448 LttvHooks *after_request,
1449 LttvHooks *event_hook,
1450 LttvHooksById *event_hook_by_id,
1451 LttvHooks *hook_adder,
1452 LttvHooks *hook_remover)
1454 LttvAttribute *g_attribute = lttv_global_attributes();
1455 LttvAttribute *attribute;
1456 LttvAttributeValue value;
1458 g_assert(attribute =
1459 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1460 LTTV_COMPUTATION)));
1462 g_assert(attribute =
1463 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1466 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1467 LTTV_BEFORE_CHUNK_TRACESET,
1470 *(value.v_pointer) = before_chunk_traceset;
1472 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1473 LTTV_BEFORE_CHUNK_TRACE,
1476 *(value.v_pointer) = before_chunk_trace;
1478 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1479 LTTV_BEFORE_CHUNK_TRACEFILE,
1482 *(value.v_pointer) = before_chunk_tracefile;
1484 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1485 LTTV_AFTER_CHUNK_TRACESET,
1488 *(value.v_pointer) = after_chunk_traceset;
1490 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1491 LTTV_AFTER_CHUNK_TRACE,
1494 *(value.v_pointer) = after_chunk_trace;
1496 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1497 LTTV_AFTER_CHUNK_TRACEFILE,
1500 *(value.v_pointer) = after_chunk_tracefile;
1502 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1503 LTTV_BEFORE_REQUEST,
1506 *(value.v_pointer) = before_request;
1508 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1512 *(value.v_pointer) = after_request;
1514 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1518 *(value.v_pointer) = event_hook;
1520 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1521 LTTV_EVENT_HOOK_BY_ID,
1524 *(value.v_pointer) = event_hook_by_id;
1526 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1530 *(value.v_pointer) = hook_adder;
1532 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1536 *(value.v_pointer) = hook_remover;
1542 * It removes all the requests than can be currently processed by the
1543 * background computation algorithm for all the traces (list_in and list_out).
1545 * Leaves the flag to in_progress or none.. depending if current or queue
1547 * @param module_name A GQuark : the name of the module which computes the
1550 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1554 for(i=0;i<lttvwindowtraces_get_number();i++) {
1555 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1556 g_assert(trace_v != NULL);
1558 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1559 LttvAttributeValue value;
1560 GSList **queue, **current;
1563 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1564 LTTV_REQUESTS_QUEUE,
1567 queue = (GSList**)(value.v_pointer);
1570 while(iter != NULL) {
1571 gboolean remove = FALSE;
1572 gboolean free_data = FALSE;
1574 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1576 if(bg_req->module_name == module_name) {
1584 GSList *remove_iter = iter;
1586 iter = g_slist_next(iter);
1587 if(free_data) g_free(remove_iter->data);
1588 *queue = g_slist_remove_link(*queue, remove_iter);
1589 } else { // not remove
1590 iter = g_slist_next(iter);
1595 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1596 LTTV_REQUESTS_CURRENT,
1599 current = (GSList**)(value.v_pointer);
1602 while(iter != NULL) {
1603 gboolean remove = FALSE;
1604 gboolean free_data = FALSE;
1606 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1608 if(bg_req->module_name == module_name) {
1616 GSList *remove_iter = iter;
1618 iter = g_slist_next(iter);
1619 if(free_data) g_free(remove_iter->data);
1620 *current = g_slist_remove_link(*current, remove_iter);
1621 } else { // not remove
1622 iter = g_slist_next(iter);
1630 * Unregister the background computation hooks for a specific module.
1632 * It also removes all the requests than can be currently processed by the
1633 * background computation algorithm for all the traces (list_in and list_out).
1635 * @param module_name A GQuark : the name of the module which computes the
1639 void lttvwindowtraces_unregister_computation_hooks
1640 (LttvAttributeName module_name)
1642 LttvAttribute *g_attribute = lttv_global_attributes();
1643 LttvAttribute *attribute;
1644 LttvAttributeValue value;
1646 g_assert(attribute =
1647 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1648 LTTV_COMPUTATION)));
1649 g_assert(attribute =
1650 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1654 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1655 LTTV_BEFORE_CHUNK_TRACESET,
1658 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1659 if(before_chunk_traceset != NULL)
1660 lttv_hooks_destroy(before_chunk_traceset);
1662 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1663 LTTV_BEFORE_CHUNK_TRACE,
1666 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1667 if(before_chunk_trace != NULL)
1668 lttv_hooks_destroy(before_chunk_trace);
1670 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1671 LTTV_BEFORE_CHUNK_TRACEFILE,
1674 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1675 if(before_chunk_tracefile != NULL)
1676 lttv_hooks_destroy(before_chunk_tracefile);
1678 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1679 LTTV_AFTER_CHUNK_TRACESET,
1682 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1683 if(after_chunk_traceset != NULL)
1684 lttv_hooks_destroy(after_chunk_traceset);
1686 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1687 LTTV_AFTER_CHUNK_TRACE,
1690 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1691 if(after_chunk_trace != NULL)
1692 lttv_hooks_destroy(after_chunk_trace);
1694 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1695 LTTV_AFTER_CHUNK_TRACEFILE,
1698 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1699 if(after_chunk_tracefile != NULL)
1700 lttv_hooks_destroy(after_chunk_tracefile);
1702 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1703 LTTV_BEFORE_REQUEST,
1706 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1707 if(before_request != NULL)
1708 lttv_hooks_destroy(before_request);
1710 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1714 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1715 if(after_request != NULL)
1716 lttv_hooks_destroy(after_request);
1718 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1722 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1723 if(event_hook != NULL)
1724 lttv_hooks_destroy(event_hook);
1726 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1727 LTTV_EVENT_HOOK_BY_ID,
1730 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1731 if(event_hook_by_id != NULL)
1732 lttv_hooks_by_id_destroy(event_hook_by_id);
1734 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1738 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1739 if(hook_adder != NULL)
1740 lttv_hooks_destroy(hook_adder);
1742 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1746 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1747 if(hook_remover != NULL)
1748 lttv_hooks_destroy(hook_remover);
1751 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1752 LTTV_EVENT_HOOK_BY_ID);
1753 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1756 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1757 LTTV_AFTER_REQUEST);
1758 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1759 LTTV_BEFORE_REQUEST);
1761 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1762 LTTV_AFTER_CHUNK_TRACEFILE);
1763 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1764 LTTV_AFTER_CHUNK_TRACE);
1765 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1766 LTTV_AFTER_CHUNK_TRACESET);
1768 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1769 LTTV_BEFORE_CHUNK_TRACEFILE);
1770 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1771 LTTV_BEFORE_CHUNK_TRACE);
1772 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1773 LTTV_BEFORE_CHUNK_TRACESET);
1774 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1776 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1779 /* finally, remove module name */
1780 g_assert(attribute =
1781 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1782 LTTV_COMPUTATION)));
1783 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1789 * Lock a trace so no other instance can use it.
1791 * @param trace The trace to lock.
1792 * @return 0 on success, -1 if cannot get lock.
1794 gint lttvwindowtraces_lock(LttvTrace *trace)
1796 LttvAttribute *attribute = lttv_trace_attribute(trace);
1797 LttvAttributeValue value;
1798 LttvAttributeType type;
1800 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1803 /* Verify the absence of the lock. */
1804 if(type != LTTV_NONE) {
1805 g_critical("Cannot take trace lock");
1809 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1812 /* the value is left unset. The only presence of the attribute is necessary.
1821 * @param trace The trace to unlock.
1822 * @return 0 on success, -1 if cannot unlock (not locked ?).
1824 gint lttvwindowtraces_unlock(LttvTrace *trace)
1826 LttvAttribute *attribute = lttv_trace_attribute(trace);
1827 LttvAttributeType type;
1828 LttvAttributeValue value;
1830 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1833 /* Verify the presence of the lock. */
1834 if(type == LTTV_NONE) {
1835 g_critical("Cannot release trace lock");
1839 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1846 * Verify if a trace is locked.
1848 * @param trace The trace to verify.
1849 * @return TRUE if locked, FALSE is unlocked.
1851 gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1853 LttvAttribute *attribute = lttv_trace_attribute(trace);
1854 LttvAttributeType type;
1855 LttvAttributeValue value;
1857 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1860 /* The only presence of the attribute is necessary. */
1861 if(type == LTTV_NONE)