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 <lttv/lttv.h>
35 #include <lttv/traceset.h>
36 #include <lttv/attribute.h>
37 #include <lttvwindow/lttvwindowtraces.h>
38 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
39 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
41 extern GSList
* g_main_window_list
;
43 typedef struct _BackgroundRequest
{
44 LttvAttributeName module_name
; /* Hook path in global attributes,
45 where all standard hooks under computation/.
47 LttvTrace
*trace
; /* trace concerned */
48 GtkWidget
*dialog
; /* Dialog linked with the request, may be NULL */
49 GtkWidget
*parent_window
; /* Parent window the dialog must be transient for */
52 typedef struct _BackgroundNotify
{
54 LttvTrace
*trace
; /* trace */
56 LttvTracesetPosition
*notify_position
;
57 LttvHooks
*notify
; /* Hook to call when the notify is
58 passed, or at the end of trace */
64 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
66 /* Get a trace by its path name.
68 * @param path path of the trace on the virtual file system.
69 * @return Pointer to trace if found
70 * NULL is returned if the trace is not present
73 __EXPORT LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
78 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
79 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
82 g_assert(trace_v
!= NULL
);
84 trace
= lttv_trace(trace_v
);
85 g_assert(trace
!= NULL
);
86 name
= g_quark_to_string(ltt_trace_name(trace
));
88 if(strcmp(name
, path
) == 0) {
97 /* Get a trace by its number identifier */
99 __EXPORT LttvTrace
*lttvwindowtraces_get_trace(guint num
)
101 LttvAttribute
*g_attribute
= lttv_global_attributes();
102 LttvAttribute
*attribute
;
103 LttvAttributeType type
;
104 LttvAttributeName name
;
105 LttvAttributeValue value
;
109 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 __EXPORT guint
lttvwindowtraces_get_number()
127 LttvAttribute
*g_attribute
= lttv_global_attributes();
128 LttvAttribute
*attribute
;
131 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
)
143 LttvAttribute
*g_attribute
= lttv_global_attributes();
144 LttvAttribute
*attribute
;
145 LttvAttributeValue value
;
147 gchar attribute_path
[PATH_MAX
];
151 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
152 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
153 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
156 result
= snprintf(attribute_path
, PATH_MAX
, "%" PRIu64
":%" PRIu64
,
157 buf
.st_dev
, buf
.st_ino
);
158 g_assert(result
>= 0);
161 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
165 value
= lttv_attribute_add(attribute
,
166 g_quark_from_string(attribute_path
),
169 *(value
.v_pointer
) = (gpointer
)trace
;
171 /* create new traceset and tracesetcontext */
173 LttvTracesetStats
*tss
;
174 //LttvTracesetContextPosition *sync_position;
176 attribute
= lttv_trace_attribute(trace
);
177 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
178 LTTV_COMPUTATION_TRACESET
,
183 ts
= lttv_traceset_new();
184 *(value
.v_pointer
) = ts
;
186 lttv_traceset_add(ts
,trace
);
188 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
189 LTTV_COMPUTATION_TRACESET_CONTEXT
,
194 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
195 *(value
.v_pointer
) = tss
;
197 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
200 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
201 LTTV_COMPUTATION_SYNC_POSITION
,
206 sync_position
= lttv_traceset_context_position_new();
207 *(value
.v_pointer
) = sync_position
;
209 value
= lttv_attribute_add(attribute
,
213 value
= lttv_attribute_add(attribute
,
214 LTTV_REQUESTS_CURRENT
,
217 value
= lttv_attribute_add(attribute
,
221 value
= lttv_attribute_add(attribute
,
226 /* Remove a trace from the global attributes */
228 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
230 LttvAttribute
*g_attribute
= lttv_global_attributes();
231 LttvAttribute
*attribute
;
232 LttvAttributeValue value
;
237 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
241 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
242 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
244 g_assert(trace_v
!= NULL
);
246 /* Remove and background computation that could be in progress */
247 g_idle_remove_by_data(trace_v
);
249 if(trace_v
== trace
) {
251 LttvAttribute
*l_attribute
;
253 /* destroy traceset and tracesetcontext */
255 //LttvTracesetContextPosition *sync_position;
257 l_attribute
= lttv_trace_attribute(trace
);
260 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
261 LTTV_REQUESTS_QUEUE
);
263 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
264 LTTV_REQUESTS_CURRENT
);
266 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
269 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
270 LTTV_NOTIFY_CURRENT
);
272 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
273 LTTV_COMPUTATION_TRACESET
,
278 ts
= (LttvTraceset
*)*(value
.v_pointer
);
280 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
281 LTTV_COMPUTATION_SYNC_POSITION
,
286 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
287 lttv_traceset_context_position_destroy(sync_position
);
289 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
290 LTTV_COMPUTATION_SYNC_POSITION
);
293 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
294 LTTV_COMPUTATION_TRACESET_CONTEXT
,
299 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
301 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
303 #endif /* BABEL_CLEANUP */
304 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
305 LTTV_COMPUTATION_TRACESET_CONTEXT
);
306 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
307 LTTV_COMPUTATION_TRACESET
);
308 /* Destroy the traceset and the trace also */
309 lttv_traceset_destroy(ts
);
311 /* finally, remove the global attribute */
312 lttv_attribute_remove(attribute
, i
);
319 static void destroy_dialog(BackgroundRequest
*bg_req
)
321 gtk_widget_destroy(bg_req
->dialog
);
322 bg_req
->dialog
= NULL
;
327 * Function to request data from a specific trace
329 * The memory allocated for the request will be managed by the API.
331 * @param widget the current Window
332 * @param trace the trace to compute
333 * @param module_name the name of the module which registered global computation
337 __EXPORT
void lttvwindowtraces_background_request_queue
338 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
340 BackgroundRequest
*bg_req
;
341 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
342 LttvAttribute
*g_attribute
= lttv_global_attributes();
343 LttvAttribute
*module_attribute
;
344 LttvAttributeValue value
;
345 LttvAttributeType type
;
349 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
355 slist
= (GSList
**)(value
.v_pointer
);
357 /* Verify that the calculator is loaded */
359 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
361 g_assert(module_attribute
);
363 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
364 g_quark_from_string(module_name
),
366 if(type
== LTTV_NONE
) {
367 g_critical("Missing background calculator %s", module_name
);
371 bg_req
= g_new(BackgroundRequest
,1);
372 bg_req
->module_name
= g_quark_from_string(module_name
);
373 bg_req
->trace
= trace
;
375 *slist
= g_slist_append(*slist
, bg_req
);
377 /* Priority lower than live servicing */
378 g_idle_remove_by_data(trace
);
379 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
380 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
383 /* FIXME : show message in status bar, need context and message id */
384 g_info("Background computation for %s started for trace %p", module_name
,
387 gtk_message_dialog_new(
389 GTK_DIALOG_DESTROY_WITH_PARENT
,
390 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
391 "Background computation for %s started for trace %s",
393 trace
->traceset
->filename
);
394 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
395 g_signal_connect_swapped (dialog
, "response",
396 G_CALLBACK (destroy_dialog
),
398 bg_req
->dialog
= dialog
;
399 /* the parent window might vanish : only use this pointer for a
400 * comparison with existing windows */
401 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
402 gtk_widget_show(dialog
);
406 * Remove a background request from a trace.
408 * This should ONLY be used by the modules which registered the global hooks
409 * (module_name). If this is called by the viewers, it may lead to incomplete
410 * and incoherent background processing information.
412 * Even if the module which deals with the hooks removes the background
413 * requests, it may cause a problem if the module gets loaded again in the
414 * session : the data will be partially calculated. The calculation function
415 * must deal with this case correctly.
417 * @param trace the trace to compute
418 * @param module_name the name of the module which registered global computation
422 void lttvwindowtraces_background_request_remove
423 (LttvTrace
*trace
, gchar
*module_name
)
425 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
426 LttvAttributeValue value
;
431 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
437 slist
= (GSList
**)(value
.v_pointer
);
439 for(iter
=*slist
;iter
!=NULL
;) {
440 BackgroundRequest
*bg_req
=
441 (BackgroundRequest
*)iter
->data
;
443 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
444 GSList
*rem_iter
= iter
;
445 iter
=g_slist_next(iter
);
447 *slist
= g_slist_delete_link(*slist
, rem_iter
);
449 iter
=g_slist_next(iter
);
455 * Find a background request in a trace
459 __EXPORT gboolean lttvwindowtraces_background_request_find
460 (LttvTrace
*trace
, gchar
*module_name
)
462 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
463 LttvAttributeValue value
;
468 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
474 slist
= (GSList
**)(value
.v_pointer
);
476 for(iter
=*slist
;iter
!=NULL
;) {
477 BackgroundRequest
*bg_req
=
478 (BackgroundRequest
*)iter
->data
;
480 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
483 iter
=g_slist_next(iter
);
490 * Register a callback to be called when requested data is passed in the next
491 * queued background processing.
493 * @param owner owner of the background notification
494 * @param trace the trace computed
495 * @param notify_time time when notification hooks must be called
496 * @param notify_position position when notification hooks must be called
497 * @param notify Hook to call when the notify position is passed
500 __EXPORT
void lttvwindowtraces_background_notify_queue
504 const LttvTracesetPosition
*notify_position
,
505 const LttvHooks
*notify
)
508 BackgroundNotify
*bg_notify
;
509 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
510 LttvAttributeValue value
;
514 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
520 slist
= (GSList
**)(value
.v_pointer
);
522 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
523 LTTV_COMPUTATION_TRACESET_CONTEXT
,
528 LttvTraceset
*ts
= (LttvTraceset
)(value
.v_pointer
);
530 bg_notify
= g_new(BackgroundNotify
,1);
532 bg_notify
->owner
= owner
;
533 bg_notify
->trace
= trace
;
534 bg_notify
->notify_time
= notify_time
;
535 if(notify_position
!= NULL
) {
536 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
537 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
540 bg_notify
->notify_position
= NULL
;
543 bg_notify
->notify
= lttv_hooks_new();
544 lttv_hooks_add_list(bg_notify
->notify
, notify
);
546 *slist
= g_slist_append(*slist
, bg_notify
);
547 #endif /* BABEL_CLEANUP*/
551 * Register a callback to be called when requested data is passed in the current
552 * background processing.
554 * @param owner owner of the background notification
555 * @param trace the trace computed
556 * @param notify_time time when notification hooks must be called
557 * @param notify_position position when notification hooks must be called
558 * @param notify Hook to call when the notify position is passed
561 __EXPORT
void lttvwindowtraces_background_notify_current
565 const LttvTracesetPosition
*notify_position
,
566 const LttvHooks
*notify
)
569 BackgroundNotify
*bg_notify
;
570 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
571 LttvAttributeValue value
;
575 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
581 slist
= (GSList
**)(value
.v_pointer
);
583 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
584 LTTV_COMPUTATION_TRACESET_CONTEXT
,
589 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
592 bg_notify
= g_new(BackgroundNotify
,1);
594 bg_notify
->owner
= owner
;
595 bg_notify
->trace
= trace
;
596 bg_notify
->notify_time
= notify_time
;
597 if(notify_position
!= NULL
) {
598 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
599 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
602 bg_notify
->notify_position
= NULL
;
604 bg_notify
->notify
= lttv_hooks_new();
605 lttv_hooks_add_list(bg_notify
->notify
, notify
);
607 *slist
= g_slist_append(*slist
, bg_notify
);
608 #endif /* BABEL_CLEANUP */
612 static void notify_request_free(BackgroundNotify
*notify_req
)
615 if(notify_req
== NULL
) return;
617 if(notify_req
->notify_position
!= NULL
)
618 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
619 if(notify_req
->notify
!= NULL
)
620 lttv_hooks_destroy(notify_req
->notify
);
622 #endif /* BABEL_CLEANUP */
626 * Removes all the notifications requests from a specific viewer.
628 * @param owner owner of the background notification
631 __EXPORT
void lttvwindowtraces_background_notify_remove(gpointer owner
)
635 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
636 LttvAttribute
*attribute
;
637 LttvAttributeValue value
;
638 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
643 g_assert(trace_v
!= NULL
);
645 attribute
= lttv_trace_attribute(trace_v
);
647 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
653 slist
= (GSList
**)(value
.v_pointer
);
655 for(iter
=*slist
;iter
!=NULL
;) {
657 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
659 if(bg_notify
->owner
== owner
) {
660 GSList
*rem_iter
= iter
;
661 iter
=g_slist_next(iter
);
662 notify_request_free(bg_notify
);
663 *slist
= g_slist_remove_link(*slist
, rem_iter
);
665 iter
=g_slist_next(iter
);
669 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
675 slist
= (GSList
**)(value
.v_pointer
);
677 for(iter
=*slist
;iter
!=NULL
;) {
679 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
681 if(bg_notify
->owner
== owner
) {
682 GSList
*rem_iter
= iter
;
683 iter
=g_slist_next(iter
);
684 notify_request_free(bg_notify
);
685 *slist
= g_slist_remove_link(*slist
, rem_iter
);
687 iter
=g_slist_next(iter
);
694 /* Background processing helper functions */
696 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
698 LttvHooks
*hook_adder
)
701 LttvAttribute
*g_attribute
= lttv_global_attributes();
702 LttvAttribute
*module_attribute
;
703 LttvAttributeType type
;
704 LttvAttributeValue value
;
708 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
710 g_assert(module_attribute
);
713 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
714 LTTV_IATTRIBUTE(module_attribute
),
716 g_assert(module_attribute
);
718 /* Call the module's hook adder */
719 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
722 if(type
== LTTV_POINTER
) {
723 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
724 if(hook_adder
!= NULL
)
725 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
727 #endif /* BABEL_CLEANUP */
730 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
732 LttvHooks
*hook_remover
)
735 LttvAttribute
*g_attribute
= lttv_global_attributes();
736 LttvAttribute
*module_attribute
;
737 LttvAttributeType type
;
738 LttvAttributeValue value
;
741 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
743 g_assert(module_attribute
);
746 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
747 LTTV_IATTRIBUTE(module_attribute
),
749 g_assert(module_attribute
);
751 /* Call the module's hook remover */
752 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
755 if(type
== LTTV_POINTER
) {
756 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
757 if(hook_remover
!= NULL
)
758 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
760 #endif /* BABEL_CLEANUP */
763 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
767 LttvAttribute
*g_attribute
= lttv_global_attributes();
768 LttvAttribute
*module_attribute
;
769 LttvAttributeType type
;
770 LttvAttributeValue value
;
771 LttvHooks
*before_chunk_traceset
=NULL
;
772 LttvHooks
*before_chunk_trace
=NULL
;
773 LttvHooks
*before_chunk_tracefile
=NULL
;
774 LttvHooks
*event_hook
=NULL
;
775 LttvHooksByIdChannelArray
*event_hook_by_id_channel
=NULL
;
779 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
781 g_assert(module_attribute
);
784 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
785 LTTV_IATTRIBUTE(module_attribute
),
787 g_assert(module_attribute
);
789 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
790 LTTV_BEFORE_CHUNK_TRACESET
,
792 if(type
== LTTV_POINTER
) {
793 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
796 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
797 LTTV_BEFORE_CHUNK_TRACE
,
799 if(type
== LTTV_POINTER
) {
800 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
803 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
804 LTTV_BEFORE_CHUNK_TRACEFILE
,
806 if(type
== LTTV_POINTER
) {
807 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
810 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
813 if(type
== LTTV_POINTER
) {
814 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
817 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
818 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
820 if(type
== LTTV_POINTER
) {
821 event_hook_by_id_channel
= (LttvHooksByIdChannelArray
*)*(value
.v_pointer
);
824 lttv_process_traceset_begin(tsc
,
825 before_chunk_traceset
,
827 before_chunk_tracefile
,
829 event_hook_by_id_channel
);
830 #endif /* BABEL_CLEANUP */
835 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
838 LttvAttribute
*g_attribute
= lttv_global_attributes();
839 LttvAttribute
*module_attribute
;
840 LttvAttributeType type
;
841 LttvAttributeValue value
;
842 LttvHooks
*after_chunk_traceset
=NULL
;
843 LttvHooks
*after_chunk_trace
=NULL
;
844 LttvHooks
*after_chunk_tracefile
=NULL
;
845 LttvHooks
*event_hook
=NULL
;
848 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
850 g_assert(module_attribute
);
853 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
854 LTTV_IATTRIBUTE(module_attribute
),
856 g_assert(module_attribute
);
858 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
859 LTTV_AFTER_CHUNK_TRACESET
,
861 if(type
== LTTV_POINTER
) {
862 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
865 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
866 LTTV_AFTER_CHUNK_TRACE
,
868 if(type
== LTTV_POINTER
) {
869 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
872 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
873 LTTV_AFTER_CHUNK_TRACEFILE
,
875 if(type
== LTTV_POINTER
) {
876 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
879 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
882 if(type
== LTTV_POINTER
) {
883 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
886 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
887 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
890 lttv_process_traceset_end(tsc
,
891 after_chunk_traceset
,
893 after_chunk_tracefile
,
895 #endif /* BABEL_CLEANUP*/
900 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
903 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
906 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
910 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
913 /* the value is left unset. The only presence of the attribute is necessary.
917 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
920 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
923 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
927 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
931 __EXPORT gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
934 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
935 LttvAttributeType type
;
936 LttvAttributeValue value
;
939 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
943 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
946 /* The only presence of the attribute is necessary. */
947 if(type
== LTTV_NONE
)
953 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
956 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
959 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
963 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
966 /* the value is left unset. The only presence of the attribute is necessary.
970 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
973 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
976 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
980 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
984 __EXPORT gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
987 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
988 LttvAttributeType type
;
989 LttvAttributeValue value
;
992 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
996 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
999 /* The only presence of the attribute is necessary. */
1000 if(type
== LTTV_NONE
)
1006 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
1008 if(a
->mwindow
== b
) return 0;
1013 /* lttvwindowtraces_process_pending_requests
1015 * Process the pending background computation requests
1017 * This internal function gets called by g_idle, taking care of the pending
1023 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
1027 LttvAttribute
*attribute
;
1028 LttvAttribute
*g_attribute
= lttv_global_attributes();
1029 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
1030 LttvAttributeValue value
;
1031 LttvAttributeType type
;
1037 if(lttvwindow_preempt_count
> 0) return TRUE
;
1039 attribute
= lttv_trace_attribute(trace
);
1041 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1042 LTTV_REQUESTS_QUEUE
,
1044 g_assert(type
== LTTV_POINTER
);
1045 list_out
= (GSList
**)(value
.v_pointer
);
1047 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1048 LTTV_REQUESTS_CURRENT
,
1050 g_assert(type
== LTTV_POINTER
);
1051 list_in
= (GSList
**)(value
.v_pointer
);
1053 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1056 g_assert(type
== LTTV_POINTER
);
1057 notify_out
= (GSList
**)(value
.v_pointer
);
1059 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1060 LTTV_NOTIFY_CURRENT
,
1062 g_assert(type
== LTTV_POINTER
);
1063 notify_in
= (GSList
**)(value
.v_pointer
);
1065 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1066 LTTV_COMPUTATION_TRACESET
,
1068 g_assert(type
== LTTV_POINTER
);
1069 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1072 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1073 LTTV_COMPUTATION_SYNC_POSITION
,
1075 g_assert(type
== LTTV_POINTER
);
1076 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1078 #ifdef BABEL_CLEANUP
1079 /* There is no events requests pending : we should never have been called! */
1080 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1081 /* 0.1 Lock traces */
1086 iter_trace
<lttv_traceset_number(ts
->ts
);
1088 LttvTrace
*trace_v
= lttv_traceset_get(ts
->ts
,iter_trace
);
1090 if(lttvwindowtraces_lock(trace_v
) != 0)
1091 return TRUE
; /* Cannot get trace lock, try later */
1095 /* 0.2 Sync tracefiles */
1096 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1097 lttv_process_traceset_synchronize_tracefiles(tsc
);
1098 /* 1. Before processing */
1100 /* if list_in is empty */
1101 if(g_slist_length(*list_in
) == 0) {
1104 /* - Add all requests in list_out to list_in, empty list_out */
1105 GSList
*iter
= *list_out
;
1107 while(iter
!= NULL
) {
1108 gboolean remove
= FALSE
;
1109 gboolean free_data
= FALSE
;
1111 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1115 *list_in
= g_slist_append(*list_in
, bg_req
);
1120 GSList
*remove_iter
= iter
;
1122 iter
= g_slist_next(iter
);
1123 if(free_data
) g_free(remove_iter
->data
);
1124 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1125 } else { // not remove
1126 iter
= g_slist_next(iter
);
1132 GSList
*iter
= *list_in
;
1133 /* - for each request in list_in */
1134 while(iter
!= NULL
) {
1136 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1137 /* - set hooks'in_progress flag to TRUE */
1138 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1141 /* - call before request hook */
1142 /* Get before request hook */
1143 LttvAttribute
*module_attribute
;
1146 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1147 LTTV_IATTRIBUTE(g_attribute
),
1149 g_assert(module_attribute
);
1152 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1153 LTTV_IATTRIBUTE(module_attribute
),
1154 bg_req
->module_name
));
1155 g_assert(module_attribute
);
1157 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1158 LTTV_BEFORE_REQUEST
,
1160 g_assert(type
== LTTV_POINTER
);
1161 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1163 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1165 iter
= g_slist_next(iter
);
1169 /* - seek trace to start */
1171 LttTime start
= { 0, 0};
1172 lttv_process_traceset_seek_time(tsc
, start
);
1175 /* - Move all notifications from notify_out to notify_in. */
1177 GSList
*iter
= *notify_out
;
1178 g_assert(g_slist_length(*notify_in
) == 0);
1180 while(iter
!= NULL
) {
1181 gboolean remove
= FALSE
;
1182 gboolean free_data
= FALSE
;
1184 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1188 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1193 GSList
*remove_iter
= iter
;
1195 iter
= g_slist_next(iter
);
1197 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1198 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1199 } else { // not remove
1200 iter
= g_slist_next(iter
);
1205 GSList
*iter
= *list_in
;
1206 LttvHooks
*hook_adder
= lttv_hooks_new();
1207 /* - for each request in list_in */
1208 while(iter
!= NULL
) {
1210 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1211 /*- add hooks to context*/
1212 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1215 iter
= g_slist_next(iter
);
1217 lttv_hooks_call(hook_adder
,tsc
);
1218 lttv_hooks_destroy(hook_adder
);
1225 GSList
*iter
= *list_in
;
1226 /* - for each request in list_in */
1227 while(iter
!= NULL
) {
1229 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1230 /*- Call before chunk hooks for list_in*/
1231 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1233 iter
= g_slist_next(iter
);
1238 /* 2. call process traceset middle for a chunk */
1240 /*(assert list_in is not empty! : should not even be called in that case)*/
1241 LttTime end
= ltt_time_infinite
;
1242 g_assert(g_slist_length(*list_in
) != 0);
1244 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1247 /* 3. After the chunk */
1249 /* 3.1 call after_chunk hooks for list_in */
1251 GSList
*iter
= *list_in
;
1252 /* - for each request in list_in */
1253 while(iter
!= NULL
) {
1255 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1256 /* - Call after chunk hooks for list_in */
1257 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1259 iter
= g_slist_next(iter
);
1263 /* 3.2 for each notify_in */
1265 GSList
*iter
= *notify_in
;
1266 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1268 while(iter
!= NULL
) {
1269 gboolean remove
= FALSE
;
1270 gboolean free_data
= FALSE
;
1272 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1274 /* - if current time >= notify time, call notify and remove from
1276 * - if current position >= notify position, call notify and remove
1280 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1282 (notify_req
->notify_position
!= NULL
&&
1283 lttv_traceset_context_ctx_pos_compare(tsc
,
1284 notify_req
->notify_position
) >= 0)
1287 lttv_hooks_call(notify_req
->notify
, notify_req
);
1296 GSList
*remove_iter
= iter
;
1298 iter
= g_slist_next(iter
);
1300 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1301 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1302 } else { // not remove
1303 iter
= g_slist_next(iter
);
1309 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1310 /* 3.3 if end of trace reached */
1312 g_debug("Current time : %lu sec, %lu nsec",
1313 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1314 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1315 tsc
->time_span
.end_time
) > 0) {
1318 GSList
*iter
= *list_in
;
1319 LttvHooks
*hook_remover
= lttv_hooks_new();
1320 /* - for each request in list_in */
1321 while(iter
!= NULL
) {
1323 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1324 /* - remove hooks from context */
1325 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1328 iter
= g_slist_next(iter
);
1330 lttv_hooks_call(hook_remover
,tsc
);
1331 lttv_hooks_destroy(hook_remover
);
1334 /* - for each request in list_in */
1336 GSList
*iter
= *list_in
;
1338 while(iter
!= NULL
) {
1339 gboolean remove
= FALSE
;
1340 gboolean free_data
= FALSE
;
1342 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1344 /* - set hooks'in_progress flag to FALSE */
1345 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1347 /* - set hooks'ready flag to TRUE */
1348 lttvwindowtraces_set_ready(bg_req
->module_name
,
1350 /* - call after request hook */
1351 /* Get after request hook */
1352 LttvAttribute
*module_attribute
;
1355 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1356 LTTV_IATTRIBUTE(g_attribute
),
1358 g_assert(module_attribute
);
1361 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1362 LTTV_IATTRIBUTE(module_attribute
),
1363 bg_req
->module_name
));
1364 g_assert(module_attribute
);
1366 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1369 g_assert(type
== LTTV_POINTER
);
1370 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1372 struct sum_traceset_closure t_closure
;
1373 t_closure
.tss
= (LttvTracesetStats
*)tsc
;
1374 t_closure
.current_time
= ltt_time_infinite
;
1375 if(after_request
!= NULL
) lttv_hooks_call(after_request
,
1379 if(bg_req
->dialog
!= NULL
)
1380 gtk_widget_destroy(bg_req
->dialog
);
1381 GtkWidget
*parent_window
;
1382 if(g_slist_find_custom(g_main_window_list
,
1383 bg_req
->parent_window
,
1384 (GCompareFunc
)find_window_widget
))
1385 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1387 parent_window
= NULL
;
1390 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1391 GTK_DIALOG_DESTROY_WITH_PARENT
,
1392 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1393 "Background computation %s finished for trace %s",
1394 g_quark_to_string(bg_req
->module_name
),
1395 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1396 if(parent_window
!= NULL
)
1397 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1398 GTK_WINDOW(parent_window
));
1399 g_signal_connect_swapped (dialog
, "response",
1400 G_CALLBACK (gtk_widget_destroy
),
1402 gtk_widget_show(dialog
);
1404 /* - remove request */
1411 GSList
*remove_iter
= iter
;
1413 iter
= g_slist_next(iter
);
1414 if(free_data
) g_free(remove_iter
->data
);
1415 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1416 } else { // not remove
1417 iter
= g_slist_next(iter
);
1422 /* - for each notifications in notify_in */
1424 GSList
*iter
= *notify_in
;
1426 while(iter
!= NULL
) {
1427 gboolean remove
= FALSE
;
1428 gboolean free_data
= FALSE
;
1430 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1432 /* - call notify and remove from notify_in */
1433 lttv_hooks_call(notify_req
->notify
, notify_req
);
1440 GSList
*remove_iter
= iter
;
1442 iter
= g_slist_next(iter
);
1444 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1445 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1446 } else { // not remove
1447 iter
= g_slist_next(iter
);
1452 /* - reset the context */
1453 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1454 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1456 /* - if list_out is empty */
1457 if(g_slist_length(*list_out
) == 0) {
1458 /* - return FALSE (scheduler stopped) */
1459 g_debug("Background computation scheduler stopped");
1460 g_info("Background computation finished for trace %p", trace
);
1461 /* FIXME : remove status bar info, need context id and message id */
1468 /* 3.4 else, end of trace not reached */
1469 /* - return TRUE (scheduler still registered) */
1470 g_debug("Background computation left");
1475 /* 4. Unlock traces */
1477 lttv_process_traceset_get_sync_data(tsc
);
1478 //lttv_traceset_context_position_save(tsc, sync_position);
1482 iter_trace
<lttv_traceset_number(tsc
->ts
);
1484 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1486 lttvwindowtraces_unlock(trace_v
);
1489 #endif /* BABEL_CLEANUP */
1496 * Register the background computation hooks for a specific module. It adds the
1497 * computation hooks to the global attrubutes, under "computation/module name".
1499 * @param module_name A GQuark : the name of the module which computes the
1502 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1503 LttvHooks
*before_chunk_traceset
,
1504 LttvHooks
*before_chunk_trace
,
1505 LttvHooks
*before_chunk_tracefile
,
1506 LttvHooks
*after_chunk_traceset
,
1507 LttvHooks
*after_chunk_trace
,
1508 LttvHooks
*after_chunk_tracefile
,
1509 LttvHooks
*before_request
,
1510 LttvHooks
*after_request
,
1511 LttvHooks
*event_hook
,
1512 LttvHooks
*hook_adder
,
1513 LttvHooks
*hook_remover
)
1515 LttvAttribute
*g_attribute
= lttv_global_attributes();
1516 LttvAttribute
*attribute
;
1517 LttvAttributeValue value
;
1521 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1523 g_assert(attribute
);
1526 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1528 g_assert(attribute
);
1530 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1531 LTTV_BEFORE_CHUNK_TRACESET
,
1536 *(value
.v_pointer
) = before_chunk_traceset
;
1538 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1539 LTTV_BEFORE_CHUNK_TRACE
,
1543 *(value
.v_pointer
) = before_chunk_trace
;
1545 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1546 LTTV_BEFORE_CHUNK_TRACEFILE
,
1550 *(value
.v_pointer
) = before_chunk_tracefile
;
1552 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1553 LTTV_AFTER_CHUNK_TRACESET
,
1557 *(value
.v_pointer
) = after_chunk_traceset
;
1559 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1560 LTTV_AFTER_CHUNK_TRACE
,
1564 *(value
.v_pointer
) = after_chunk_trace
;
1566 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1567 LTTV_AFTER_CHUNK_TRACEFILE
,
1571 *(value
.v_pointer
) = after_chunk_tracefile
;
1573 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1574 LTTV_BEFORE_REQUEST
,
1578 *(value
.v_pointer
) = before_request
;
1580 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1585 *(value
.v_pointer
) = after_request
;
1587 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1592 *(value
.v_pointer
) = event_hook
;
1594 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1599 *(value
.v_pointer
) = hook_adder
;
1601 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1606 *(value
.v_pointer
) = hook_remover
;
1612 * It removes all the requests that can be currently processed by the
1613 * background computation algorithm for all the traces (list_in and list_out).
1615 * Leaves the flag to in_progress or none.. depending if current or queue
1617 * @param module_name A GQuark : the name of the module which computes the
1620 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1625 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1626 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1627 g_assert(trace_v
!= NULL
);
1628 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1629 LttvAttributeValue value
;
1630 GSList
**queue
, **current
;
1633 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1634 LTTV_REQUESTS_QUEUE
,
1639 queue
= (GSList
**)(value
.v_pointer
);
1642 while(iter
!= NULL
) {
1643 gboolean remove
= FALSE
;
1644 gboolean free_data
= FALSE
;
1646 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1648 if(bg_req
->module_name
== module_name
) {
1656 GSList
*remove_iter
= iter
;
1658 iter
= g_slist_next(iter
);
1659 if(free_data
) g_free(remove_iter
->data
);
1660 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1661 } else { // not remove
1662 iter
= g_slist_next(iter
);
1667 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1668 LTTV_REQUESTS_CURRENT
,
1673 current
= (GSList
**)(value
.v_pointer
);
1676 while(iter
!= NULL
) {
1677 gboolean remove
= FALSE
;
1678 gboolean free_data
= FALSE
;
1680 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1682 if(bg_req
->module_name
== module_name
) {
1690 GSList
*remove_iter
= iter
;
1692 iter
= g_slist_next(iter
);
1693 if(free_data
) g_free(remove_iter
->data
);
1694 *current
= g_slist_remove_link(*current
, remove_iter
);
1695 } else { // not remove
1696 iter
= g_slist_next(iter
);
1704 * Unregister the background computation hooks for a specific module.
1706 * It also removes all the requests that can be currently processed by the
1707 * background computation algorithm for all the traces (list_in and list_out).
1709 * @param module_name A GQuark : the name of the module which computes the
1713 void lttvwindowtraces_unregister_computation_hooks
1714 (LttvAttributeName module_name
)
1716 LttvAttribute
*g_attribute
= lttv_global_attributes();
1717 LttvAttribute
*attribute
;
1718 LttvAttributeValue value
;
1722 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1724 g_assert(attribute
);
1727 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1729 g_assert(attribute
);
1731 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1732 LTTV_BEFORE_CHUNK_TRACESET
,
1737 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1738 if(before_chunk_traceset
!= NULL
)
1739 lttv_hooks_destroy(before_chunk_traceset
);
1741 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1742 LTTV_BEFORE_CHUNK_TRACE
,
1747 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1748 if(before_chunk_trace
!= NULL
)
1749 lttv_hooks_destroy(before_chunk_trace
);
1751 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1752 LTTV_BEFORE_CHUNK_TRACEFILE
,
1757 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1758 if(before_chunk_tracefile
!= NULL
)
1759 lttv_hooks_destroy(before_chunk_tracefile
);
1761 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1762 LTTV_AFTER_CHUNK_TRACESET
,
1767 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1768 if(after_chunk_traceset
!= NULL
)
1769 lttv_hooks_destroy(after_chunk_traceset
);
1771 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1772 LTTV_AFTER_CHUNK_TRACE
,
1777 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1778 if(after_chunk_trace
!= NULL
)
1779 lttv_hooks_destroy(after_chunk_trace
);
1781 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1782 LTTV_AFTER_CHUNK_TRACEFILE
,
1787 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1788 if(after_chunk_tracefile
!= NULL
)
1789 lttv_hooks_destroy(after_chunk_tracefile
);
1791 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1792 LTTV_BEFORE_REQUEST
,
1797 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1798 if(before_request
!= NULL
)
1799 lttv_hooks_destroy(before_request
);
1801 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1807 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1808 if(after_request
!= NULL
)
1809 lttv_hooks_destroy(after_request
);
1811 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1817 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1818 if(event_hook
!= NULL
)
1819 lttv_hooks_destroy(event_hook
);
1821 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1822 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
1827 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1833 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1834 if(hook_adder
!= NULL
)
1835 lttv_hooks_destroy(hook_adder
);
1837 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1843 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1844 if(hook_remover
!= NULL
)
1845 lttv_hooks_destroy(hook_remover
);
1848 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1849 LTTV_EVENT_HOOK_BY_ID_CHANNEL
);
1850 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1853 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1854 LTTV_AFTER_REQUEST
);
1855 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1856 LTTV_BEFORE_REQUEST
);
1858 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1859 LTTV_AFTER_CHUNK_TRACEFILE
);
1860 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1861 LTTV_AFTER_CHUNK_TRACE
);
1862 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1863 LTTV_AFTER_CHUNK_TRACESET
);
1865 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1866 LTTV_BEFORE_CHUNK_TRACEFILE
);
1867 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1868 LTTV_BEFORE_CHUNK_TRACE
);
1869 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1870 LTTV_BEFORE_CHUNK_TRACESET
);
1871 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1873 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1876 /* finally, remove module name */
1878 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1880 g_assert(attribute
);
1881 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1887 * Lock a trace so no other instance can use it.
1889 * @param trace The trace to lock.
1890 * @return 0 on success, -1 if cannot get lock.
1892 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1894 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1895 LttvAttributeValue value
;
1896 LttvAttributeType type
;
1898 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1901 /* Verify the absence of the lock. */
1902 if(type
!= LTTV_NONE
) {
1903 g_critical("Cannot take trace lock");
1907 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1910 /* the value is left unset. The only presence of the attribute is necessary.
1919 * @param trace The trace to unlock.
1920 * @return 0 on success, -1 if cannot unlock (not locked ?).
1922 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1924 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1925 LttvAttributeType type
;
1926 LttvAttributeValue value
;
1928 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1931 /* Verify the presence of the lock. */
1932 if(type
== LTTV_NONE
) {
1933 g_critical("Cannot release trace lock");
1937 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1944 * Verify if a trace is locked.
1946 * @param trace The trace to verify.
1947 * @return TRUE if locked, FALSE is unlocked.
1949 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1951 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1952 LttvAttributeType type
;
1953 LttvAttributeValue value
;
1955 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1958 /* The only presence of the attribute is necessary. */
1959 if(type
== LTTV_NONE
)