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>
34 #include <ltt/trace.h>
36 #include <lttv/lttv.h>
37 #include <lttv/traceset.h>
38 #include <lttv/attribute.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 LttvTracesetPosition
*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 __EXPORT LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
80 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
81 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
84 g_assert(trace_v
!= NULL
);
86 trace
= lttv_trace(trace_v
);
87 g_assert(trace
!= NULL
);
88 name
= g_quark_to_string(ltt_trace_name(trace
));
90 if(strcmp(name
, path
) == 0) {
99 /* Get a trace by its number identifier */
101 __EXPORT LttvTrace
*lttvwindowtraces_get_trace(guint num
)
103 LttvAttribute
*g_attribute
= lttv_global_attributes();
104 LttvAttribute
*attribute
;
105 LttvAttributeType type
;
106 LttvAttributeName name
;
107 LttvAttributeValue value
;
111 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
115 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
,
118 if(type
== LTTV_POINTER
) {
119 return (LttvTrace
*)*(value
.v_pointer
);
125 /* Total number of traces */
127 __EXPORT guint
lttvwindowtraces_get_number()
129 LttvAttribute
*g_attribute
= lttv_global_attributes();
130 LttvAttribute
*attribute
;
133 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
137 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
140 /* Add a trace to the global attributes */
142 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
145 LttvAttribute
*g_attribute
= lttv_global_attributes();
146 LttvAttribute
*attribute
;
147 LttvAttributeValue value
;
149 gchar attribute_path
[PATH_MAX
];
153 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
154 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
155 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
158 result
= snprintf(attribute_path
, PATH_MAX
, "%" PRIu64
":%" PRIu64
,
159 buf
.st_dev
, buf
.st_ino
);
160 g_assert(result
>= 0);
163 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
167 value
= lttv_attribute_add(attribute
,
168 g_quark_from_string(attribute_path
),
171 *(value
.v_pointer
) = (gpointer
)trace
;
173 /* create new traceset and tracesetcontext */
175 LttvTracesetStats
*tss
;
176 //LttvTracesetContextPosition *sync_position;
178 attribute
= lttv_trace_attribute(trace
);
179 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
180 LTTV_COMPUTATION_TRACESET
,
185 ts
= lttv_traceset_new();
186 *(value
.v_pointer
) = ts
;
188 lttv_traceset_add(ts
,trace
);
190 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
191 LTTV_COMPUTATION_TRACESET_CONTEXT
,
196 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
197 *(value
.v_pointer
) = tss
;
199 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
202 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
203 LTTV_COMPUTATION_SYNC_POSITION
,
208 sync_position
= lttv_traceset_context_position_new();
209 *(value
.v_pointer
) = sync_position
;
211 value
= lttv_attribute_add(attribute
,
215 value
= lttv_attribute_add(attribute
,
216 LTTV_REQUESTS_CURRENT
,
219 value
= lttv_attribute_add(attribute
,
223 value
= lttv_attribute_add(attribute
,
228 /* Remove a trace from the global attributes */
230 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
232 LttvAttribute
*g_attribute
= lttv_global_attributes();
233 LttvAttribute
*attribute
;
234 LttvAttributeValue value
;
239 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
243 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
244 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
246 g_assert(trace_v
!= NULL
);
248 /* Remove and background computation that could be in progress */
249 g_idle_remove_by_data(trace_v
);
251 if(trace_v
== trace
) {
253 LttvAttribute
*l_attribute
;
255 /* destroy traceset and tracesetcontext */
257 //LttvTracesetContextPosition *sync_position;
259 l_attribute
= lttv_trace_attribute(trace
);
262 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
263 LTTV_REQUESTS_QUEUE
);
265 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
266 LTTV_REQUESTS_CURRENT
);
268 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
271 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
272 LTTV_NOTIFY_CURRENT
);
274 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
275 LTTV_COMPUTATION_TRACESET
,
280 ts
= (LttvTraceset
*)*(value
.v_pointer
);
282 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
283 LTTV_COMPUTATION_SYNC_POSITION
,
288 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
289 lttv_traceset_context_position_destroy(sync_position
);
291 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
292 LTTV_COMPUTATION_SYNC_POSITION
);
295 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
296 LTTV_COMPUTATION_TRACESET_CONTEXT
,
301 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
303 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
305 #endif /* BABEL_CLEANUP */
306 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
307 LTTV_COMPUTATION_TRACESET_CONTEXT
);
308 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
309 LTTV_COMPUTATION_TRACESET
);
310 /* Destroy the traceset and the trace also */
311 lttv_traceset_destroy(ts
);
313 /* finally, remove the global attribute */
314 lttv_attribute_remove(attribute
, i
);
321 static void destroy_dialog(BackgroundRequest
*bg_req
)
323 gtk_widget_destroy(bg_req
->dialog
);
324 bg_req
->dialog
= NULL
;
329 * Function to request data from a specific trace
331 * The memory allocated for the request will be managed by the API.
333 * @param widget the current Window
334 * @param trace the trace to compute
335 * @param module_name the name of the module which registered global computation
339 __EXPORT
void lttvwindowtraces_background_request_queue
340 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
342 BackgroundRequest
*bg_req
;
343 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
344 LttvAttribute
*g_attribute
= lttv_global_attributes();
345 LttvAttribute
*module_attribute
;
346 LttvAttributeValue value
;
347 LttvAttributeType type
;
351 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
357 slist
= (GSList
**)(value
.v_pointer
);
359 /* Verify that the calculator is loaded */
361 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
363 g_assert(module_attribute
);
365 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
366 g_quark_from_string(module_name
),
368 if(type
== LTTV_NONE
) {
369 g_critical("Missing background calculator %s", module_name
);
373 bg_req
= g_new(BackgroundRequest
,1);
374 bg_req
->module_name
= g_quark_from_string(module_name
);
375 bg_req
->trace
= trace
;
377 *slist
= g_slist_append(*slist
, bg_req
);
379 /* Priority lower than live servicing */
380 g_idle_remove_by_data(trace
);
381 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
382 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
385 /* FIXME : show message in status bar, need context and message id */
386 g_info("Background computation for %s started for trace %p", module_name
,
389 gtk_message_dialog_new(
391 GTK_DIALOG_DESTROY_WITH_PARENT
,
392 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
393 "Background computation for %s started for trace %s",
395 trace
->traceset
->filename
);
396 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
397 g_signal_connect_swapped (dialog
, "response",
398 G_CALLBACK (destroy_dialog
),
400 bg_req
->dialog
= dialog
;
401 /* the parent window might vanish : only use this pointer for a
402 * comparison with existing windows */
403 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
404 gtk_widget_show(dialog
);
408 * Remove a background request from a trace.
410 * This should ONLY be used by the modules which registered the global hooks
411 * (module_name). If this is called by the viewers, it may lead to incomplete
412 * and incoherent background processing information.
414 * Even if the module which deals with the hooks removes the background
415 * requests, it may cause a problem if the module gets loaded again in the
416 * session : the data will be partially calculated. The calculation function
417 * must deal with this case correctly.
419 * @param trace the trace to compute
420 * @param module_name the name of the module which registered global computation
424 void lttvwindowtraces_background_request_remove
425 (LttvTrace
*trace
, gchar
*module_name
)
427 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
428 LttvAttributeValue value
;
433 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
439 slist
= (GSList
**)(value
.v_pointer
);
441 for(iter
=*slist
;iter
!=NULL
;) {
442 BackgroundRequest
*bg_req
=
443 (BackgroundRequest
*)iter
->data
;
445 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
446 GSList
*rem_iter
= iter
;
447 iter
=g_slist_next(iter
);
449 *slist
= g_slist_delete_link(*slist
, rem_iter
);
451 iter
=g_slist_next(iter
);
457 * Find a background request in a trace
461 __EXPORT gboolean lttvwindowtraces_background_request_find
462 (LttvTrace
*trace
, gchar
*module_name
)
464 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
465 LttvAttributeValue value
;
470 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
476 slist
= (GSList
**)(value
.v_pointer
);
478 for(iter
=*slist
;iter
!=NULL
;) {
479 BackgroundRequest
*bg_req
=
480 (BackgroundRequest
*)iter
->data
;
482 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
485 iter
=g_slist_next(iter
);
492 * Register a callback to be called when requested data is passed in the next
493 * queued background processing.
495 * @param owner owner of the background notification
496 * @param trace the trace computed
497 * @param notify_time time when notification hooks must be called
498 * @param notify_position position when notification hooks must be called
499 * @param notify Hook to call when the notify position is passed
502 __EXPORT
void lttvwindowtraces_background_notify_queue
506 const LttvTracesetPosition
*notify_position
,
507 const LttvHooks
*notify
)
510 BackgroundNotify
*bg_notify
;
511 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
512 LttvAttributeValue value
;
516 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
522 slist
= (GSList
**)(value
.v_pointer
);
524 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
525 LTTV_COMPUTATION_TRACESET_CONTEXT
,
530 LttvTraceset
*ts
= (LttvTraceset
)(value
.v_pointer
);
532 bg_notify
= g_new(BackgroundNotify
,1);
534 bg_notify
->owner
= owner
;
535 bg_notify
->trace
= trace
;
536 bg_notify
->notify_time
= notify_time
;
537 if(notify_position
!= NULL
) {
538 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
539 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
542 bg_notify
->notify_position
= NULL
;
545 bg_notify
->notify
= lttv_hooks_new();
546 lttv_hooks_add_list(bg_notify
->notify
, notify
);
548 *slist
= g_slist_append(*slist
, bg_notify
);
549 #endif /* BABEL_CLEANUP*/
553 * Register a callback to be called when requested data is passed in the current
554 * background processing.
556 * @param owner owner of the background notification
557 * @param trace the trace computed
558 * @param notify_time time when notification hooks must be called
559 * @param notify_position position when notification hooks must be called
560 * @param notify Hook to call when the notify position is passed
563 __EXPORT
void lttvwindowtraces_background_notify_current
567 const LttvTracesetPosition
*notify_position
,
568 const LttvHooks
*notify
)
571 BackgroundNotify
*bg_notify
;
572 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
573 LttvAttributeValue value
;
577 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
583 slist
= (GSList
**)(value
.v_pointer
);
585 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
586 LTTV_COMPUTATION_TRACESET_CONTEXT
,
591 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
594 bg_notify
= g_new(BackgroundNotify
,1);
596 bg_notify
->owner
= owner
;
597 bg_notify
->trace
= trace
;
598 bg_notify
->notify_time
= notify_time
;
599 if(notify_position
!= NULL
) {
600 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
601 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
604 bg_notify
->notify_position
= NULL
;
606 bg_notify
->notify
= lttv_hooks_new();
607 lttv_hooks_add_list(bg_notify
->notify
, notify
);
609 *slist
= g_slist_append(*slist
, bg_notify
);
610 #endif /* BABEL_CLEANUP */
614 static void notify_request_free(BackgroundNotify
*notify_req
)
617 if(notify_req
== NULL
) return;
619 if(notify_req
->notify_position
!= NULL
)
620 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
621 if(notify_req
->notify
!= NULL
)
622 lttv_hooks_destroy(notify_req
->notify
);
624 #endif /* BABEL_CLEANUP */
628 * Removes all the notifications requests from a specific viewer.
630 * @param owner owner of the background notification
633 __EXPORT
void lttvwindowtraces_background_notify_remove(gpointer owner
)
637 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
638 LttvAttribute
*attribute
;
639 LttvAttributeValue value
;
640 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
645 g_assert(trace_v
!= NULL
);
647 attribute
= lttv_trace_attribute(trace_v
);
649 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
655 slist
= (GSList
**)(value
.v_pointer
);
657 for(iter
=*slist
;iter
!=NULL
;) {
659 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
661 if(bg_notify
->owner
== owner
) {
662 GSList
*rem_iter
= iter
;
663 iter
=g_slist_next(iter
);
664 notify_request_free(bg_notify
);
665 *slist
= g_slist_remove_link(*slist
, rem_iter
);
667 iter
=g_slist_next(iter
);
671 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
677 slist
= (GSList
**)(value
.v_pointer
);
679 for(iter
=*slist
;iter
!=NULL
;) {
681 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
683 if(bg_notify
->owner
== owner
) {
684 GSList
*rem_iter
= iter
;
685 iter
=g_slist_next(iter
);
686 notify_request_free(bg_notify
);
687 *slist
= g_slist_remove_link(*slist
, rem_iter
);
689 iter
=g_slist_next(iter
);
696 /* Background processing helper functions */
698 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
700 LttvHooks
*hook_adder
)
703 LttvAttribute
*g_attribute
= lttv_global_attributes();
704 LttvAttribute
*module_attribute
;
705 LttvAttributeType type
;
706 LttvAttributeValue value
;
710 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
712 g_assert(module_attribute
);
715 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
716 LTTV_IATTRIBUTE(module_attribute
),
718 g_assert(module_attribute
);
720 /* Call the module's hook adder */
721 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
724 if(type
== LTTV_POINTER
) {
725 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
726 if(hook_adder
!= NULL
)
727 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
729 #endif /* BABEL_CLEANUP */
732 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
734 LttvHooks
*hook_remover
)
737 LttvAttribute
*g_attribute
= lttv_global_attributes();
738 LttvAttribute
*module_attribute
;
739 LttvAttributeType type
;
740 LttvAttributeValue value
;
743 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
745 g_assert(module_attribute
);
748 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
749 LTTV_IATTRIBUTE(module_attribute
),
751 g_assert(module_attribute
);
753 /* Call the module's hook remover */
754 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
757 if(type
== LTTV_POINTER
) {
758 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
759 if(hook_remover
!= NULL
)
760 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
762 #endif /* BABEL_CLEANUP */
765 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
769 LttvAttribute
*g_attribute
= lttv_global_attributes();
770 LttvAttribute
*module_attribute
;
771 LttvAttributeType type
;
772 LttvAttributeValue value
;
773 LttvHooks
*before_chunk_traceset
=NULL
;
774 LttvHooks
*before_chunk_trace
=NULL
;
775 LttvHooks
*before_chunk_tracefile
=NULL
;
776 LttvHooks
*event_hook
=NULL
;
777 LttvHooksByIdChannelArray
*event_hook_by_id_channel
=NULL
;
781 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
783 g_assert(module_attribute
);
786 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
787 LTTV_IATTRIBUTE(module_attribute
),
789 g_assert(module_attribute
);
791 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
792 LTTV_BEFORE_CHUNK_TRACESET
,
794 if(type
== LTTV_POINTER
) {
795 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
798 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
799 LTTV_BEFORE_CHUNK_TRACE
,
801 if(type
== LTTV_POINTER
) {
802 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
805 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
806 LTTV_BEFORE_CHUNK_TRACEFILE
,
808 if(type
== LTTV_POINTER
) {
809 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
812 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
815 if(type
== LTTV_POINTER
) {
816 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
819 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
820 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
822 if(type
== LTTV_POINTER
) {
823 event_hook_by_id_channel
= (LttvHooksByIdChannelArray
*)*(value
.v_pointer
);
826 lttv_process_traceset_begin(tsc
,
827 before_chunk_traceset
,
829 before_chunk_tracefile
,
831 event_hook_by_id_channel
);
832 #endif /* BABEL_CLEANUP */
837 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
840 LttvAttribute
*g_attribute
= lttv_global_attributes();
841 LttvAttribute
*module_attribute
;
842 LttvAttributeType type
;
843 LttvAttributeValue value
;
844 LttvHooks
*after_chunk_traceset
=NULL
;
845 LttvHooks
*after_chunk_trace
=NULL
;
846 LttvHooks
*after_chunk_tracefile
=NULL
;
847 LttvHooks
*event_hook
=NULL
;
850 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
852 g_assert(module_attribute
);
855 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
856 LTTV_IATTRIBUTE(module_attribute
),
858 g_assert(module_attribute
);
860 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
861 LTTV_AFTER_CHUNK_TRACESET
,
863 if(type
== LTTV_POINTER
) {
864 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
867 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
868 LTTV_AFTER_CHUNK_TRACE
,
870 if(type
== LTTV_POINTER
) {
871 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
874 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
875 LTTV_AFTER_CHUNK_TRACEFILE
,
877 if(type
== LTTV_POINTER
) {
878 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
881 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
884 if(type
== LTTV_POINTER
) {
885 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
888 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
889 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
892 lttv_process_traceset_end(tsc
,
893 after_chunk_traceset
,
895 after_chunk_tracefile
,
897 #endif /* BABEL_CLEANUP*/
902 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
905 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
908 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
912 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
915 /* the value is left unset. The only presence of the attribute is necessary.
919 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
922 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
925 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
929 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
933 __EXPORT gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
936 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
937 LttvAttributeType type
;
938 LttvAttributeValue value
;
941 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
945 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
948 /* The only presence of the attribute is necessary. */
949 if(type
== LTTV_NONE
)
955 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
958 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
961 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
965 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
968 /* the value is left unset. The only presence of the attribute is necessary.
972 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
975 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
978 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
982 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
986 __EXPORT gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
989 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
990 LttvAttributeType type
;
991 LttvAttributeValue value
;
994 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
998 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1001 /* The only presence of the attribute is necessary. */
1002 if(type
== LTTV_NONE
)
1008 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
1010 if(a
->mwindow
== b
) return 0;
1015 /* lttvwindowtraces_process_pending_requests
1017 * Process the pending background computation requests
1019 * This internal function gets called by g_idle, taking care of the pending
1025 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
1029 LttvAttribute
*attribute
;
1030 LttvAttribute
*g_attribute
= lttv_global_attributes();
1031 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
1032 LttvAttributeValue value
;
1033 LttvAttributeType type
;
1039 if(lttvwindow_preempt_count
> 0) return TRUE
;
1041 attribute
= lttv_trace_attribute(trace
);
1043 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1044 LTTV_REQUESTS_QUEUE
,
1046 g_assert(type
== LTTV_POINTER
);
1047 list_out
= (GSList
**)(value
.v_pointer
);
1049 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1050 LTTV_REQUESTS_CURRENT
,
1052 g_assert(type
== LTTV_POINTER
);
1053 list_in
= (GSList
**)(value
.v_pointer
);
1055 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1058 g_assert(type
== LTTV_POINTER
);
1059 notify_out
= (GSList
**)(value
.v_pointer
);
1061 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1062 LTTV_NOTIFY_CURRENT
,
1064 g_assert(type
== LTTV_POINTER
);
1065 notify_in
= (GSList
**)(value
.v_pointer
);
1067 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1068 LTTV_COMPUTATION_TRACESET
,
1070 g_assert(type
== LTTV_POINTER
);
1071 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1074 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1075 LTTV_COMPUTATION_SYNC_POSITION
,
1077 g_assert(type
== LTTV_POINTER
);
1078 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1080 #ifdef BABEL_CLEANUP
1081 /* There is no events requests pending : we should never have been called! */
1082 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1083 /* 0.1 Lock traces */
1088 iter_trace
<lttv_traceset_number(ts
->ts
);
1090 LttvTrace
*trace_v
= lttv_traceset_get(ts
->ts
,iter_trace
);
1092 if(lttvwindowtraces_lock(trace_v
) != 0)
1093 return TRUE
; /* Cannot get trace lock, try later */
1097 /* 0.2 Sync tracefiles */
1098 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1099 lttv_process_traceset_synchronize_tracefiles(tsc
);
1100 /* 1. Before processing */
1102 /* if list_in is empty */
1103 if(g_slist_length(*list_in
) == 0) {
1106 /* - Add all requests in list_out to list_in, empty list_out */
1107 GSList
*iter
= *list_out
;
1109 while(iter
!= NULL
) {
1110 gboolean remove
= FALSE
;
1111 gboolean free_data
= FALSE
;
1113 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1117 *list_in
= g_slist_append(*list_in
, bg_req
);
1122 GSList
*remove_iter
= iter
;
1124 iter
= g_slist_next(iter
);
1125 if(free_data
) g_free(remove_iter
->data
);
1126 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1127 } else { // not remove
1128 iter
= g_slist_next(iter
);
1134 GSList
*iter
= *list_in
;
1135 /* - for each request in list_in */
1136 while(iter
!= NULL
) {
1138 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1139 /* - set hooks'in_progress flag to TRUE */
1140 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1143 /* - call before request hook */
1144 /* Get before request hook */
1145 LttvAttribute
*module_attribute
;
1148 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1149 LTTV_IATTRIBUTE(g_attribute
),
1151 g_assert(module_attribute
);
1154 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1155 LTTV_IATTRIBUTE(module_attribute
),
1156 bg_req
->module_name
));
1157 g_assert(module_attribute
);
1159 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1160 LTTV_BEFORE_REQUEST
,
1162 g_assert(type
== LTTV_POINTER
);
1163 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1165 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1167 iter
= g_slist_next(iter
);
1171 /* - seek trace to start */
1173 LttTime start
= { 0, 0};
1174 lttv_process_traceset_seek_time(tsc
, start
);
1177 /* - Move all notifications from notify_out to notify_in. */
1179 GSList
*iter
= *notify_out
;
1180 g_assert(g_slist_length(*notify_in
) == 0);
1182 while(iter
!= NULL
) {
1183 gboolean remove
= FALSE
;
1184 gboolean free_data
= FALSE
;
1186 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1190 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1195 GSList
*remove_iter
= iter
;
1197 iter
= g_slist_next(iter
);
1199 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1200 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1201 } else { // not remove
1202 iter
= g_slist_next(iter
);
1207 GSList
*iter
= *list_in
;
1208 LttvHooks
*hook_adder
= lttv_hooks_new();
1209 /* - for each request in list_in */
1210 while(iter
!= NULL
) {
1212 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1213 /*- add hooks to context*/
1214 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1217 iter
= g_slist_next(iter
);
1219 lttv_hooks_call(hook_adder
,tsc
);
1220 lttv_hooks_destroy(hook_adder
);
1227 GSList
*iter
= *list_in
;
1228 /* - for each request in list_in */
1229 while(iter
!= NULL
) {
1231 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1232 /*- Call before chunk hooks for list_in*/
1233 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1235 iter
= g_slist_next(iter
);
1240 /* 2. call process traceset middle for a chunk */
1242 /*(assert list_in is not empty! : should not even be called in that case)*/
1243 LttTime end
= ltt_time_infinite
;
1244 g_assert(g_slist_length(*list_in
) != 0);
1246 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1249 /* 3. After the chunk */
1251 /* 3.1 call after_chunk hooks for list_in */
1253 GSList
*iter
= *list_in
;
1254 /* - for each request in list_in */
1255 while(iter
!= NULL
) {
1257 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1258 /* - Call after chunk hooks for list_in */
1259 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1261 iter
= g_slist_next(iter
);
1265 /* 3.2 for each notify_in */
1267 GSList
*iter
= *notify_in
;
1268 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1270 while(iter
!= NULL
) {
1271 gboolean remove
= FALSE
;
1272 gboolean free_data
= FALSE
;
1274 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1276 /* - if current time >= notify time, call notify and remove from
1278 * - if current position >= notify position, call notify and remove
1282 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1284 (notify_req
->notify_position
!= NULL
&&
1285 lttv_traceset_context_ctx_pos_compare(tsc
,
1286 notify_req
->notify_position
) >= 0)
1289 lttv_hooks_call(notify_req
->notify
, notify_req
);
1298 GSList
*remove_iter
= iter
;
1300 iter
= g_slist_next(iter
);
1302 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1303 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1304 } else { // not remove
1305 iter
= g_slist_next(iter
);
1311 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1312 /* 3.3 if end of trace reached */
1314 g_debug("Current time : %lu sec, %lu nsec",
1315 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1316 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1317 tsc
->time_span
.end_time
) > 0) {
1320 GSList
*iter
= *list_in
;
1321 LttvHooks
*hook_remover
= lttv_hooks_new();
1322 /* - for each request in list_in */
1323 while(iter
!= NULL
) {
1325 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1326 /* - remove hooks from context */
1327 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1330 iter
= g_slist_next(iter
);
1332 lttv_hooks_call(hook_remover
,tsc
);
1333 lttv_hooks_destroy(hook_remover
);
1336 /* - for each request in list_in */
1338 GSList
*iter
= *list_in
;
1340 while(iter
!= NULL
) {
1341 gboolean remove
= FALSE
;
1342 gboolean free_data
= FALSE
;
1344 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1346 /* - set hooks'in_progress flag to FALSE */
1347 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1349 /* - set hooks'ready flag to TRUE */
1350 lttvwindowtraces_set_ready(bg_req
->module_name
,
1352 /* - call after request hook */
1353 /* Get after request hook */
1354 LttvAttribute
*module_attribute
;
1357 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1358 LTTV_IATTRIBUTE(g_attribute
),
1360 g_assert(module_attribute
);
1363 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1364 LTTV_IATTRIBUTE(module_attribute
),
1365 bg_req
->module_name
));
1366 g_assert(module_attribute
);
1368 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1371 g_assert(type
== LTTV_POINTER
);
1372 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1374 struct sum_traceset_closure t_closure
;
1375 t_closure
.tss
= (LttvTracesetStats
*)tsc
;
1376 t_closure
.current_time
= ltt_time_infinite
;
1377 if(after_request
!= NULL
) lttv_hooks_call(after_request
,
1381 if(bg_req
->dialog
!= NULL
)
1382 gtk_widget_destroy(bg_req
->dialog
);
1383 GtkWidget
*parent_window
;
1384 if(g_slist_find_custom(g_main_window_list
,
1385 bg_req
->parent_window
,
1386 (GCompareFunc
)find_window_widget
))
1387 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1389 parent_window
= NULL
;
1392 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1393 GTK_DIALOG_DESTROY_WITH_PARENT
,
1394 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1395 "Background computation %s finished for trace %s",
1396 g_quark_to_string(bg_req
->module_name
),
1397 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1398 if(parent_window
!= NULL
)
1399 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1400 GTK_WINDOW(parent_window
));
1401 g_signal_connect_swapped (dialog
, "response",
1402 G_CALLBACK (gtk_widget_destroy
),
1404 gtk_widget_show(dialog
);
1406 /* - remove request */
1413 GSList
*remove_iter
= iter
;
1415 iter
= g_slist_next(iter
);
1416 if(free_data
) g_free(remove_iter
->data
);
1417 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1418 } else { // not remove
1419 iter
= g_slist_next(iter
);
1424 /* - for each notifications in notify_in */
1426 GSList
*iter
= *notify_in
;
1428 while(iter
!= NULL
) {
1429 gboolean remove
= FALSE
;
1430 gboolean free_data
= FALSE
;
1432 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1434 /* - call notify and remove from notify_in */
1435 lttv_hooks_call(notify_req
->notify
, notify_req
);
1442 GSList
*remove_iter
= iter
;
1444 iter
= g_slist_next(iter
);
1446 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1447 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1448 } else { // not remove
1449 iter
= g_slist_next(iter
);
1454 /* - reset the context */
1455 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1456 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1458 /* - if list_out is empty */
1459 if(g_slist_length(*list_out
) == 0) {
1460 /* - return FALSE (scheduler stopped) */
1461 g_debug("Background computation scheduler stopped");
1462 g_info("Background computation finished for trace %p", trace
);
1463 /* FIXME : remove status bar info, need context id and message id */
1470 /* 3.4 else, end of trace not reached */
1471 /* - return TRUE (scheduler still registered) */
1472 g_debug("Background computation left");
1477 /* 4. Unlock traces */
1479 lttv_process_traceset_get_sync_data(tsc
);
1480 //lttv_traceset_context_position_save(tsc, sync_position);
1484 iter_trace
<lttv_traceset_number(tsc
->ts
);
1486 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1488 lttvwindowtraces_unlock(trace_v
);
1491 #endif /* BABEL_CLEANUP */
1498 * Register the background computation hooks for a specific module. It adds the
1499 * computation hooks to the global attrubutes, under "computation/module name".
1501 * @param module_name A GQuark : the name of the module which computes the
1504 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1505 LttvHooks
*before_chunk_traceset
,
1506 LttvHooks
*before_chunk_trace
,
1507 LttvHooks
*before_chunk_tracefile
,
1508 LttvHooks
*after_chunk_traceset
,
1509 LttvHooks
*after_chunk_trace
,
1510 LttvHooks
*after_chunk_tracefile
,
1511 LttvHooks
*before_request
,
1512 LttvHooks
*after_request
,
1513 LttvHooks
*event_hook
,
1514 LttvHooks
*hook_adder
,
1515 LttvHooks
*hook_remover
)
1517 LttvAttribute
*g_attribute
= lttv_global_attributes();
1518 LttvAttribute
*attribute
;
1519 LttvAttributeValue value
;
1523 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1525 g_assert(attribute
);
1528 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1530 g_assert(attribute
);
1532 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1533 LTTV_BEFORE_CHUNK_TRACESET
,
1538 *(value
.v_pointer
) = before_chunk_traceset
;
1540 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1541 LTTV_BEFORE_CHUNK_TRACE
,
1545 *(value
.v_pointer
) = before_chunk_trace
;
1547 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1548 LTTV_BEFORE_CHUNK_TRACEFILE
,
1552 *(value
.v_pointer
) = before_chunk_tracefile
;
1554 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1555 LTTV_AFTER_CHUNK_TRACESET
,
1559 *(value
.v_pointer
) = after_chunk_traceset
;
1561 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1562 LTTV_AFTER_CHUNK_TRACE
,
1566 *(value
.v_pointer
) = after_chunk_trace
;
1568 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1569 LTTV_AFTER_CHUNK_TRACEFILE
,
1573 *(value
.v_pointer
) = after_chunk_tracefile
;
1575 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1576 LTTV_BEFORE_REQUEST
,
1580 *(value
.v_pointer
) = before_request
;
1582 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1587 *(value
.v_pointer
) = after_request
;
1589 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1594 *(value
.v_pointer
) = event_hook
;
1596 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1601 *(value
.v_pointer
) = hook_adder
;
1603 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1608 *(value
.v_pointer
) = hook_remover
;
1614 * It removes all the requests that can be currently processed by the
1615 * background computation algorithm for all the traces (list_in and list_out).
1617 * Leaves the flag to in_progress or none.. depending if current or queue
1619 * @param module_name A GQuark : the name of the module which computes the
1622 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1627 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1628 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1629 g_assert(trace_v
!= NULL
);
1630 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1631 LttvAttributeValue value
;
1632 GSList
**queue
, **current
;
1635 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1636 LTTV_REQUESTS_QUEUE
,
1641 queue
= (GSList
**)(value
.v_pointer
);
1644 while(iter
!= NULL
) {
1645 gboolean remove
= FALSE
;
1646 gboolean free_data
= FALSE
;
1648 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1650 if(bg_req
->module_name
== module_name
) {
1658 GSList
*remove_iter
= iter
;
1660 iter
= g_slist_next(iter
);
1661 if(free_data
) g_free(remove_iter
->data
);
1662 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1663 } else { // not remove
1664 iter
= g_slist_next(iter
);
1669 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1670 LTTV_REQUESTS_CURRENT
,
1675 current
= (GSList
**)(value
.v_pointer
);
1678 while(iter
!= NULL
) {
1679 gboolean remove
= FALSE
;
1680 gboolean free_data
= FALSE
;
1682 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1684 if(bg_req
->module_name
== module_name
) {
1692 GSList
*remove_iter
= iter
;
1694 iter
= g_slist_next(iter
);
1695 if(free_data
) g_free(remove_iter
->data
);
1696 *current
= g_slist_remove_link(*current
, remove_iter
);
1697 } else { // not remove
1698 iter
= g_slist_next(iter
);
1706 * Unregister the background computation hooks for a specific module.
1708 * It also removes all the requests that can be currently processed by the
1709 * background computation algorithm for all the traces (list_in and list_out).
1711 * @param module_name A GQuark : the name of the module which computes the
1715 void lttvwindowtraces_unregister_computation_hooks
1716 (LttvAttributeName module_name
)
1718 LttvAttribute
*g_attribute
= lttv_global_attributes();
1719 LttvAttribute
*attribute
;
1720 LttvAttributeValue value
;
1724 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1726 g_assert(attribute
);
1729 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1731 g_assert(attribute
);
1733 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1734 LTTV_BEFORE_CHUNK_TRACESET
,
1739 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1740 if(before_chunk_traceset
!= NULL
)
1741 lttv_hooks_destroy(before_chunk_traceset
);
1743 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1744 LTTV_BEFORE_CHUNK_TRACE
,
1749 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1750 if(before_chunk_trace
!= NULL
)
1751 lttv_hooks_destroy(before_chunk_trace
);
1753 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1754 LTTV_BEFORE_CHUNK_TRACEFILE
,
1759 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1760 if(before_chunk_tracefile
!= NULL
)
1761 lttv_hooks_destroy(before_chunk_tracefile
);
1763 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1764 LTTV_AFTER_CHUNK_TRACESET
,
1769 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1770 if(after_chunk_traceset
!= NULL
)
1771 lttv_hooks_destroy(after_chunk_traceset
);
1773 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1774 LTTV_AFTER_CHUNK_TRACE
,
1779 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1780 if(after_chunk_trace
!= NULL
)
1781 lttv_hooks_destroy(after_chunk_trace
);
1783 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1784 LTTV_AFTER_CHUNK_TRACEFILE
,
1789 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1790 if(after_chunk_tracefile
!= NULL
)
1791 lttv_hooks_destroy(after_chunk_tracefile
);
1793 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1794 LTTV_BEFORE_REQUEST
,
1799 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1800 if(before_request
!= NULL
)
1801 lttv_hooks_destroy(before_request
);
1803 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1809 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1810 if(after_request
!= NULL
)
1811 lttv_hooks_destroy(after_request
);
1813 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1819 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1820 if(event_hook
!= NULL
)
1821 lttv_hooks_destroy(event_hook
);
1823 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1824 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
1829 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1835 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1836 if(hook_adder
!= NULL
)
1837 lttv_hooks_destroy(hook_adder
);
1839 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1845 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1846 if(hook_remover
!= NULL
)
1847 lttv_hooks_destroy(hook_remover
);
1850 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1851 LTTV_EVENT_HOOK_BY_ID_CHANNEL
);
1852 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1855 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1856 LTTV_AFTER_REQUEST
);
1857 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1858 LTTV_BEFORE_REQUEST
);
1860 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1861 LTTV_AFTER_CHUNK_TRACEFILE
);
1862 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1863 LTTV_AFTER_CHUNK_TRACE
);
1864 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1865 LTTV_AFTER_CHUNK_TRACESET
);
1867 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1868 LTTV_BEFORE_CHUNK_TRACEFILE
);
1869 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1870 LTTV_BEFORE_CHUNK_TRACE
);
1871 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1872 LTTV_BEFORE_CHUNK_TRACESET
);
1873 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1875 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1878 /* finally, remove module name */
1880 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1882 g_assert(attribute
);
1883 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1889 * Lock a trace so no other instance can use it.
1891 * @param trace The trace to lock.
1892 * @return 0 on success, -1 if cannot get lock.
1894 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1896 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1897 LttvAttributeValue value
;
1898 LttvAttributeType type
;
1900 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1903 /* Verify the absence of the lock. */
1904 if(type
!= LTTV_NONE
) {
1905 g_critical("Cannot take trace lock");
1909 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1912 /* the value is left unset. The only presence of the attribute is necessary.
1921 * @param trace The trace to unlock.
1922 * @return 0 on success, -1 if cannot unlock (not locked ?).
1924 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1926 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1927 LttvAttributeType type
;
1928 LttvAttributeValue value
;
1930 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1933 /* Verify the presence of the lock. */
1934 if(type
== LTTV_NONE
) {
1935 g_critical("Cannot release trace lock");
1939 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1946 * Verify if a trace is locked.
1948 * @param trace The trace to verify.
1949 * @return TRUE if locked, FALSE is unlocked.
1951 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1953 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1954 LttvAttributeType type
;
1955 LttvAttributeValue value
;
1957 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1960 /* The only presence of the attribute is necessary. */
1961 if(type
== LTTV_NONE
)