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 <lttv/tracecontext.h>
40 #include <lttvwindow/lttvwindowtraces.h>
41 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
42 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
44 extern GSList
* g_main_window_list
;
46 typedef struct _BackgroundRequest
{
47 LttvAttributeName module_name
; /* Hook path in global attributes,
48 where all standard hooks under computation/.
50 LttvTrace
*trace
; /* trace concerned */
51 GtkWidget
*dialog
; /* Dialog linked with the request, may be NULL */
52 GtkWidget
*parent_window
; /* Parent window the dialog must be transient for */
55 typedef struct _BackgroundNotify
{
57 LttvTrace
*trace
; /* trace */
59 LttvTracesetContextPosition
*notify_position
;
60 LttvHooks
*notify
; /* Hook to call when the notify is
61 passed, or at the end of trace */
67 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
69 /* Get a trace by its path name.
71 * @param path path of the trace on the virtual file system.
72 * @return Pointer to trace if found
73 * NULL is returned if the trace is not present
76 __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
)
144 LttvAttribute
*g_attribute
= lttv_global_attributes();
145 LttvAttribute
*attribute
;
146 LttvAttributeValue value
;
148 gchar attribute_path
[PATH_MAX
];
152 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
153 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
154 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
157 result
= snprintf(attribute_path
, PATH_MAX
, "%" PRIu64
":%" PRIu64
,
158 buf
.st_dev
, buf
.st_ino
);
159 g_assert(result
>= 0);
162 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
166 value
= lttv_attribute_add(attribute
,
167 g_quark_from_string(attribute_path
),
170 *(value
.v_pointer
) = (gpointer
)trace
;
172 /* create new traceset and tracesetcontext */
174 LttvTracesetStats
*tss
;
175 //LttvTracesetContextPosition *sync_position;
177 attribute
= lttv_trace_attribute(trace
);
178 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
179 LTTV_COMPUTATION_TRACESET
,
184 ts
= lttv_traceset_new();
185 *(value
.v_pointer
) = ts
;
187 lttv_traceset_add(ts
,trace
);
189 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
190 LTTV_COMPUTATION_TRACESET_CONTEXT
,
195 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
196 *(value
.v_pointer
) = tss
;
198 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 LttvTracesetStats
*tss
;
256 //LttvTracesetContextPosition *sync_position;
258 l_attribute
= lttv_trace_attribute(trace
);
261 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
262 LTTV_REQUESTS_QUEUE
);
264 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
265 LTTV_REQUESTS_CURRENT
);
267 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
270 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
271 LTTV_NOTIFY_CURRENT
);
273 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
274 LTTV_COMPUTATION_TRACESET
,
279 ts
= (LttvTraceset
*)*(value
.v_pointer
);
281 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
282 LTTV_COMPUTATION_SYNC_POSITION
,
287 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
288 lttv_traceset_context_position_destroy(sync_position
);
290 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
291 LTTV_COMPUTATION_SYNC_POSITION
);
294 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
295 LTTV_COMPUTATION_TRACESET_CONTEXT
,
300 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
302 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
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 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
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 LttvTracesetContextPosition
*notify_position
,
505 const LttvHooks
*notify
)
507 BackgroundNotify
*bg_notify
;
508 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
509 LttvAttributeValue value
;
513 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
519 slist
= (GSList
**)(value
.v_pointer
);
521 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
522 LTTV_COMPUTATION_TRACESET_CONTEXT
,
527 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
529 bg_notify
= g_new(BackgroundNotify
,1);
531 bg_notify
->owner
= owner
;
532 bg_notify
->trace
= trace
;
533 bg_notify
->notify_time
= notify_time
;
534 if(notify_position
!= NULL
) {
535 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
536 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
539 bg_notify
->notify_position
= NULL
;
542 bg_notify
->notify
= lttv_hooks_new();
543 lttv_hooks_add_list(bg_notify
->notify
, notify
);
545 *slist
= g_slist_append(*slist
, bg_notify
);
549 * Register a callback to be called when requested data is passed in the current
550 * background processing.
552 * @param owner owner of the background notification
553 * @param trace the trace computed
554 * @param notify_time time when notification hooks must be called
555 * @param notify_position position when notification hooks must be called
556 * @param notify Hook to call when the notify position is passed
559 __EXPORT
void lttvwindowtraces_background_notify_current
563 const LttvTracesetContextPosition
*notify_position
,
564 const LttvHooks
*notify
)
566 BackgroundNotify
*bg_notify
;
567 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
568 LttvAttributeValue value
;
572 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
578 slist
= (GSList
**)(value
.v_pointer
);
580 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
581 LTTV_COMPUTATION_TRACESET_CONTEXT
,
586 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
589 bg_notify
= g_new(BackgroundNotify
,1);
591 bg_notify
->owner
= owner
;
592 bg_notify
->trace
= trace
;
593 bg_notify
->notify_time
= notify_time
;
594 if(notify_position
!= NULL
) {
595 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
596 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
599 bg_notify
->notify_position
= NULL
;
601 bg_notify
->notify
= lttv_hooks_new();
602 lttv_hooks_add_list(bg_notify
->notify
, notify
);
604 *slist
= g_slist_append(*slist
, bg_notify
);
608 static void notify_request_free(BackgroundNotify
*notify_req
)
610 if(notify_req
== NULL
) return;
612 if(notify_req
->notify_position
!= NULL
)
613 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
614 if(notify_req
->notify
!= NULL
)
615 lttv_hooks_destroy(notify_req
->notify
);
620 * Removes all the notifications requests from a specific viewer.
622 * @param owner owner of the background notification
625 __EXPORT
void lttvwindowtraces_background_notify_remove(gpointer owner
)
629 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
630 LttvAttribute
*attribute
;
631 LttvAttributeValue value
;
632 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
637 g_assert(trace_v
!= NULL
);
639 attribute
= lttv_trace_attribute(trace_v
);
641 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
647 slist
= (GSList
**)(value
.v_pointer
);
649 for(iter
=*slist
;iter
!=NULL
;) {
651 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
653 if(bg_notify
->owner
== owner
) {
654 GSList
*rem_iter
= iter
;
655 iter
=g_slist_next(iter
);
656 notify_request_free(bg_notify
);
657 *slist
= g_slist_remove_link(*slist
, rem_iter
);
659 iter
=g_slist_next(iter
);
663 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
669 slist
= (GSList
**)(value
.v_pointer
);
671 for(iter
=*slist
;iter
!=NULL
;) {
673 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
675 if(bg_notify
->owner
== owner
) {
676 GSList
*rem_iter
= iter
;
677 iter
=g_slist_next(iter
);
678 notify_request_free(bg_notify
);
679 *slist
= g_slist_remove_link(*slist
, rem_iter
);
681 iter
=g_slist_next(iter
);
688 /* Background processing helper functions */
690 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
691 LttvTracesetContext
*tsc
,
692 LttvHooks
*hook_adder
)
694 LttvAttribute
*g_attribute
= lttv_global_attributes();
695 LttvAttribute
*module_attribute
;
696 LttvAttributeType type
;
697 LttvAttributeValue value
;
701 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
703 g_assert(module_attribute
);
706 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
707 LTTV_IATTRIBUTE(module_attribute
),
709 g_assert(module_attribute
);
711 /* Call the module's hook adder */
712 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
715 if(type
== LTTV_POINTER
) {
716 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
717 if(hook_adder
!= NULL
)
718 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
722 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
723 LttvTracesetContext
*tsc
,
724 LttvHooks
*hook_remover
)
726 LttvAttribute
*g_attribute
= lttv_global_attributes();
727 LttvAttribute
*module_attribute
;
728 LttvAttributeType type
;
729 LttvAttributeValue value
;
732 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
734 g_assert(module_attribute
);
737 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
738 LTTV_IATTRIBUTE(module_attribute
),
740 g_assert(module_attribute
);
742 /* Call the module's hook remover */
743 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
746 if(type
== LTTV_POINTER
) {
747 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
748 if(hook_remover
!= NULL
)
749 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
753 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
754 LttvTracesetContext
*tsc
)
756 LttvAttribute
*g_attribute
= lttv_global_attributes();
757 LttvAttribute
*module_attribute
;
758 LttvAttributeType type
;
759 LttvAttributeValue value
;
760 LttvHooks
*before_chunk_traceset
=NULL
;
761 LttvHooks
*before_chunk_trace
=NULL
;
762 LttvHooks
*before_chunk_tracefile
=NULL
;
763 LttvHooks
*event_hook
=NULL
;
764 LttvHooksByIdChannelArray
*event_hook_by_id_channel
=NULL
;
768 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
770 g_assert(module_attribute
);
773 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
774 LTTV_IATTRIBUTE(module_attribute
),
776 g_assert(module_attribute
);
778 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
779 LTTV_BEFORE_CHUNK_TRACESET
,
781 if(type
== LTTV_POINTER
) {
782 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
785 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
786 LTTV_BEFORE_CHUNK_TRACE
,
788 if(type
== LTTV_POINTER
) {
789 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
792 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
793 LTTV_BEFORE_CHUNK_TRACEFILE
,
795 if(type
== LTTV_POINTER
) {
796 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
799 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
802 if(type
== LTTV_POINTER
) {
803 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
806 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
807 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
809 if(type
== LTTV_POINTER
) {
810 event_hook_by_id_channel
= (LttvHooksByIdChannelArray
*)*(value
.v_pointer
);
813 lttv_process_traceset_begin(tsc
,
814 before_chunk_traceset
,
816 before_chunk_tracefile
,
818 event_hook_by_id_channel
);
823 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
824 LttvTracesetContext
*tsc
)
826 LttvAttribute
*g_attribute
= lttv_global_attributes();
827 LttvAttribute
*module_attribute
;
828 LttvAttributeType type
;
829 LttvAttributeValue value
;
830 LttvHooks
*after_chunk_traceset
=NULL
;
831 LttvHooks
*after_chunk_trace
=NULL
;
832 LttvHooks
*after_chunk_tracefile
=NULL
;
833 LttvHooks
*event_hook
=NULL
;
834 LttvHooksByIdChannelArray
*event_hook_by_id_channel
=NULL
;
837 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
839 g_assert(module_attribute
);
842 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
843 LTTV_IATTRIBUTE(module_attribute
),
845 g_assert(module_attribute
);
847 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
848 LTTV_AFTER_CHUNK_TRACESET
,
850 if(type
== LTTV_POINTER
) {
851 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
854 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
855 LTTV_AFTER_CHUNK_TRACE
,
857 if(type
== LTTV_POINTER
) {
858 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
861 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
862 LTTV_AFTER_CHUNK_TRACEFILE
,
864 if(type
== LTTV_POINTER
) {
865 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
868 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
871 if(type
== LTTV_POINTER
) {
872 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
875 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
876 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
878 if(type
== LTTV_POINTER
) {
879 event_hook_by_id_channel
= (LttvHooksByIdChannelArray
*)*(value
.v_pointer
);
882 lttv_process_traceset_end(tsc
,
883 after_chunk_traceset
,
885 after_chunk_tracefile
,
887 event_hook_by_id_channel
);
892 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
895 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
898 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
902 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
905 /* the value is left unset. The only presence of the attribute is necessary.
909 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
912 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
915 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
919 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
923 __EXPORT gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
926 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
927 LttvAttributeType type
;
928 LttvAttributeValue value
;
931 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
935 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
938 /* The only presence of the attribute is necessary. */
939 if(type
== LTTV_NONE
)
945 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
948 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
951 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
955 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
958 /* the value is left unset. The only presence of the attribute is necessary.
962 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
965 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
968 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
972 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
976 __EXPORT gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
979 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
980 LttvAttributeType type
;
981 LttvAttributeValue value
;
984 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
988 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
991 /* The only presence of the attribute is necessary. */
992 if(type
== LTTV_NONE
)
998 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
1000 if(a
->mwindow
== b
) return 0;
1005 /* lttvwindowtraces_process_pending_requests
1007 * Process the pending background computation requests
1009 * This internal function gets called by g_idle, taking care of the pending
1015 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
1017 LttvTracesetContext
*tsc
;
1018 LttvTracesetStats
*tss
;
1020 //LttvTracesetContextPosition *sync_position;
1021 LttvAttribute
*attribute
;
1022 LttvAttribute
*g_attribute
= lttv_global_attributes();
1023 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
1024 LttvAttributeValue value
;
1025 LttvAttributeType type
;
1031 if(lttvwindow_preempt_count
> 0) return TRUE
;
1033 attribute
= lttv_trace_attribute(trace
);
1035 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1036 LTTV_REQUESTS_QUEUE
,
1038 g_assert(type
== LTTV_POINTER
);
1039 list_out
= (GSList
**)(value
.v_pointer
);
1041 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1042 LTTV_REQUESTS_CURRENT
,
1044 g_assert(type
== LTTV_POINTER
);
1045 list_in
= (GSList
**)(value
.v_pointer
);
1047 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1050 g_assert(type
== LTTV_POINTER
);
1051 notify_out
= (GSList
**)(value
.v_pointer
);
1053 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1054 LTTV_NOTIFY_CURRENT
,
1056 g_assert(type
== LTTV_POINTER
);
1057 notify_in
= (GSList
**)(value
.v_pointer
);
1059 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1060 LTTV_COMPUTATION_TRACESET
,
1062 g_assert(type
== LTTV_POINTER
);
1063 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1065 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1066 LTTV_COMPUTATION_TRACESET_CONTEXT
,
1068 g_assert(type
== LTTV_POINTER
);
1069 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
1070 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
1071 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
1072 g_assert(LTTV_IS_TRACESET_STATS(tss
));
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 /* There is no events requests pending : we should never have been called! */
1081 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1082 /* 0.1 Lock traces */
1087 iter_trace
<lttv_traceset_number(tsc
->ts
);
1089 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
1091 if(lttvwindowtraces_lock(trace_v
) != 0)
1092 return TRUE
; /* Cannot get trace lock, try later */
1096 /* 0.2 Sync tracefiles */
1097 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1098 lttv_process_traceset_synchronize_tracefiles(tsc
);
1099 /* 1. Before processing */
1101 /* if list_in is empty */
1102 if(g_slist_length(*list_in
) == 0) {
1105 /* - Add all requests in list_out to list_in, empty list_out */
1106 GSList
*iter
= *list_out
;
1108 while(iter
!= NULL
) {
1109 gboolean remove
= FALSE
;
1110 gboolean free_data
= FALSE
;
1112 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1116 *list_in
= g_slist_append(*list_in
, bg_req
);
1121 GSList
*remove_iter
= iter
;
1123 iter
= g_slist_next(iter
);
1124 if(free_data
) g_free(remove_iter
->data
);
1125 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1126 } else { // not remove
1127 iter
= g_slist_next(iter
);
1133 GSList
*iter
= *list_in
;
1134 /* - for each request in list_in */
1135 while(iter
!= NULL
) {
1137 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1138 /* - set hooks'in_progress flag to TRUE */
1139 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1142 /* - call before request hook */
1143 /* Get before request hook */
1144 LttvAttribute
*module_attribute
;
1147 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1148 LTTV_IATTRIBUTE(g_attribute
),
1150 g_assert(module_attribute
);
1153 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1154 LTTV_IATTRIBUTE(module_attribute
),
1155 bg_req
->module_name
));
1156 g_assert(module_attribute
);
1158 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1159 LTTV_BEFORE_REQUEST
,
1161 g_assert(type
== LTTV_POINTER
);
1162 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1164 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1166 iter
= g_slist_next(iter
);
1170 /* - seek trace to start */
1172 LttTime start
= { 0, 0};
1173 lttv_process_traceset_seek_time(tsc
, start
);
1176 /* - Move all notifications from notify_out to notify_in. */
1178 GSList
*iter
= *notify_out
;
1179 g_assert(g_slist_length(*notify_in
) == 0);
1181 while(iter
!= NULL
) {
1182 gboolean remove
= FALSE
;
1183 gboolean free_data
= FALSE
;
1185 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1189 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1194 GSList
*remove_iter
= iter
;
1196 iter
= g_slist_next(iter
);
1198 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1199 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1200 } else { // not remove
1201 iter
= g_slist_next(iter
);
1206 GSList
*iter
= *list_in
;
1207 LttvHooks
*hook_adder
= lttv_hooks_new();
1208 /* - for each request in list_in */
1209 while(iter
!= NULL
) {
1211 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1212 /*- add hooks to context*/
1213 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1216 iter
= g_slist_next(iter
);
1218 lttv_hooks_call(hook_adder
,tsc
);
1219 lttv_hooks_destroy(hook_adder
);
1226 GSList
*iter
= *list_in
;
1227 /* - for each request in list_in */
1228 while(iter
!= NULL
) {
1230 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1231 /*- Call before chunk hooks for list_in*/
1232 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1234 iter
= g_slist_next(iter
);
1239 /* 2. call process traceset middle for a chunk */
1241 /*(assert list_in is not empty! : should not even be called in that case)*/
1242 LttTime end
= ltt_time_infinite
;
1243 g_assert(g_slist_length(*list_in
) != 0);
1245 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1248 /* 3. After the chunk */
1250 /* 3.1 call after_chunk hooks for list_in */
1252 GSList
*iter
= *list_in
;
1253 /* - for each request in list_in */
1254 while(iter
!= NULL
) {
1256 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1257 /* - Call after chunk hooks for list_in */
1258 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1260 iter
= g_slist_next(iter
);
1264 /* 3.2 for each notify_in */
1266 GSList
*iter
= *notify_in
;
1267 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1269 while(iter
!= NULL
) {
1270 gboolean remove
= FALSE
;
1271 gboolean free_data
= FALSE
;
1273 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1275 /* - if current time >= notify time, call notify and remove from
1277 * - if current position >= notify position, call notify and remove
1281 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1283 (notify_req
->notify_position
!= NULL
&&
1284 lttv_traceset_context_ctx_pos_compare(tsc
,
1285 notify_req
->notify_position
) >= 0)
1288 lttv_hooks_call(notify_req
->notify
, notify_req
);
1297 GSList
*remove_iter
= iter
;
1299 iter
= g_slist_next(iter
);
1301 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1302 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1303 } else { // not remove
1304 iter
= g_slist_next(iter
);
1310 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1311 /* 3.3 if end of trace reached */
1313 g_debug("Current time : %lu sec, %lu nsec",
1314 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1315 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1316 tsc
->time_span
.end_time
) > 0) {
1319 GSList
*iter
= *list_in
;
1320 LttvHooks
*hook_remover
= lttv_hooks_new();
1321 /* - for each request in list_in */
1322 while(iter
!= NULL
) {
1324 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1325 /* - remove hooks from context */
1326 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1329 iter
= g_slist_next(iter
);
1331 lttv_hooks_call(hook_remover
,tsc
);
1332 lttv_hooks_destroy(hook_remover
);
1335 /* - for each request in list_in */
1337 GSList
*iter
= *list_in
;
1339 while(iter
!= NULL
) {
1340 gboolean remove
= FALSE
;
1341 gboolean free_data
= FALSE
;
1343 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1345 /* - set hooks'in_progress flag to FALSE */
1346 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1348 /* - set hooks'ready flag to TRUE */
1349 lttvwindowtraces_set_ready(bg_req
->module_name
,
1351 /* - call after request hook */
1352 /* Get after request hook */
1353 LttvAttribute
*module_attribute
;
1356 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1357 LTTV_IATTRIBUTE(g_attribute
),
1359 g_assert(module_attribute
);
1362 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1363 LTTV_IATTRIBUTE(module_attribute
),
1364 bg_req
->module_name
));
1365 g_assert(module_attribute
);
1367 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1370 g_assert(type
== LTTV_POINTER
);
1371 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1373 struct sum_traceset_closure t_closure
;
1374 t_closure
.tss
= (LttvTracesetStats
*)tsc
;
1375 t_closure
.current_time
= ltt_time_infinite
;
1376 if(after_request
!= NULL
) lttv_hooks_call(after_request
,
1380 if(bg_req
->dialog
!= NULL
)
1381 gtk_widget_destroy(bg_req
->dialog
);
1382 GtkWidget
*parent_window
;
1383 if(g_slist_find_custom(g_main_window_list
,
1384 bg_req
->parent_window
,
1385 (GCompareFunc
)find_window_widget
))
1386 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1388 parent_window
= NULL
;
1391 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1392 GTK_DIALOG_DESTROY_WITH_PARENT
,
1393 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1394 "Background computation %s finished for trace %s",
1395 g_quark_to_string(bg_req
->module_name
),
1396 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1397 if(parent_window
!= NULL
)
1398 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1399 GTK_WINDOW(parent_window
));
1400 g_signal_connect_swapped (dialog
, "response",
1401 G_CALLBACK (gtk_widget_destroy
),
1403 gtk_widget_show(dialog
);
1405 /* - remove request */
1412 GSList
*remove_iter
= iter
;
1414 iter
= g_slist_next(iter
);
1415 if(free_data
) g_free(remove_iter
->data
);
1416 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1417 } else { // not remove
1418 iter
= g_slist_next(iter
);
1423 /* - for each notifications in notify_in */
1425 GSList
*iter
= *notify_in
;
1427 while(iter
!= NULL
) {
1428 gboolean remove
= FALSE
;
1429 gboolean free_data
= FALSE
;
1431 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1433 /* - call notify and remove from notify_in */
1434 lttv_hooks_call(notify_req
->notify
, notify_req
);
1441 GSList
*remove_iter
= iter
;
1443 iter
= g_slist_next(iter
);
1445 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1446 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1447 } else { // not remove
1448 iter
= g_slist_next(iter
);
1453 /* - reset the context */
1454 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1455 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1457 /* - if list_out is empty */
1458 if(g_slist_length(*list_out
) == 0) {
1459 /* - return FALSE (scheduler stopped) */
1460 g_debug("Background computation scheduler stopped");
1461 g_info("Background computation finished for trace %p", trace
);
1462 /* FIXME : remove status bar info, need context id and message id */
1469 /* 3.4 else, end of trace not reached */
1470 /* - return TRUE (scheduler still registered) */
1471 g_debug("Background computation left");
1476 /* 4. Unlock traces */
1478 lttv_process_traceset_get_sync_data(tsc
);
1479 //lttv_traceset_context_position_save(tsc, sync_position);
1483 iter_trace
<lttv_traceset_number(tsc
->ts
);
1485 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1487 lttvwindowtraces_unlock(trace_v
);
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 LttvHooksById
*event_hook_by_id_channel
,
1513 LttvHooks
*hook_adder
,
1514 LttvHooks
*hook_remover
)
1516 LttvAttribute
*g_attribute
= lttv_global_attributes();
1517 LttvAttribute
*attribute
;
1518 LttvAttributeValue value
;
1522 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1524 g_assert(attribute
);
1527 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1529 g_assert(attribute
);
1531 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1532 LTTV_BEFORE_CHUNK_TRACESET
,
1537 *(value
.v_pointer
) = before_chunk_traceset
;
1539 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1540 LTTV_BEFORE_CHUNK_TRACE
,
1544 *(value
.v_pointer
) = before_chunk_trace
;
1546 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1547 LTTV_BEFORE_CHUNK_TRACEFILE
,
1551 *(value
.v_pointer
) = before_chunk_tracefile
;
1553 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1554 LTTV_AFTER_CHUNK_TRACESET
,
1558 *(value
.v_pointer
) = after_chunk_traceset
;
1560 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1561 LTTV_AFTER_CHUNK_TRACE
,
1565 *(value
.v_pointer
) = after_chunk_trace
;
1567 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1568 LTTV_AFTER_CHUNK_TRACEFILE
,
1572 *(value
.v_pointer
) = after_chunk_tracefile
;
1574 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1575 LTTV_BEFORE_REQUEST
,
1579 *(value
.v_pointer
) = before_request
;
1581 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1586 *(value
.v_pointer
) = after_request
;
1588 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1593 *(value
.v_pointer
) = event_hook
;
1595 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1596 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
1600 *(value
.v_pointer
) = event_hook_by_id_channel
;
1602 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1607 *(value
.v_pointer
) = hook_adder
;
1609 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1614 *(value
.v_pointer
) = hook_remover
;
1620 * It removes all the requests that can be currently processed by the
1621 * background computation algorithm for all the traces (list_in and list_out).
1623 * Leaves the flag to in_progress or none.. depending if current or queue
1625 * @param module_name A GQuark : the name of the module which computes the
1628 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1633 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1634 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1635 g_assert(trace_v
!= NULL
);
1636 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1637 LttvAttributeValue value
;
1638 GSList
**queue
, **current
;
1641 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1642 LTTV_REQUESTS_QUEUE
,
1647 queue
= (GSList
**)(value
.v_pointer
);
1650 while(iter
!= NULL
) {
1651 gboolean remove
= FALSE
;
1652 gboolean free_data
= FALSE
;
1654 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1656 if(bg_req
->module_name
== module_name
) {
1664 GSList
*remove_iter
= iter
;
1666 iter
= g_slist_next(iter
);
1667 if(free_data
) g_free(remove_iter
->data
);
1668 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1669 } else { // not remove
1670 iter
= g_slist_next(iter
);
1675 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1676 LTTV_REQUESTS_CURRENT
,
1681 current
= (GSList
**)(value
.v_pointer
);
1684 while(iter
!= NULL
) {
1685 gboolean remove
= FALSE
;
1686 gboolean free_data
= FALSE
;
1688 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1690 if(bg_req
->module_name
== module_name
) {
1698 GSList
*remove_iter
= iter
;
1700 iter
= g_slist_next(iter
);
1701 if(free_data
) g_free(remove_iter
->data
);
1702 *current
= g_slist_remove_link(*current
, remove_iter
);
1703 } else { // not remove
1704 iter
= g_slist_next(iter
);
1712 * Unregister the background computation hooks for a specific module.
1714 * It also removes all the requests that can be currently processed by the
1715 * background computation algorithm for all the traces (list_in and list_out).
1717 * @param module_name A GQuark : the name of the module which computes the
1721 void lttvwindowtraces_unregister_computation_hooks
1722 (LttvAttributeName module_name
)
1724 LttvAttribute
*g_attribute
= lttv_global_attributes();
1725 LttvAttribute
*attribute
;
1726 LttvAttributeValue value
;
1730 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1732 g_assert(attribute
);
1735 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1737 g_assert(attribute
);
1739 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1740 LTTV_BEFORE_CHUNK_TRACESET
,
1745 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1746 if(before_chunk_traceset
!= NULL
)
1747 lttv_hooks_destroy(before_chunk_traceset
);
1749 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1750 LTTV_BEFORE_CHUNK_TRACE
,
1755 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1756 if(before_chunk_trace
!= NULL
)
1757 lttv_hooks_destroy(before_chunk_trace
);
1759 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1760 LTTV_BEFORE_CHUNK_TRACEFILE
,
1765 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1766 if(before_chunk_tracefile
!= NULL
)
1767 lttv_hooks_destroy(before_chunk_tracefile
);
1769 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1770 LTTV_AFTER_CHUNK_TRACESET
,
1775 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1776 if(after_chunk_traceset
!= NULL
)
1777 lttv_hooks_destroy(after_chunk_traceset
);
1779 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1780 LTTV_AFTER_CHUNK_TRACE
,
1785 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1786 if(after_chunk_trace
!= NULL
)
1787 lttv_hooks_destroy(after_chunk_trace
);
1789 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1790 LTTV_AFTER_CHUNK_TRACEFILE
,
1795 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1796 if(after_chunk_tracefile
!= NULL
)
1797 lttv_hooks_destroy(after_chunk_tracefile
);
1799 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1800 LTTV_BEFORE_REQUEST
,
1805 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1806 if(before_request
!= NULL
)
1807 lttv_hooks_destroy(before_request
);
1809 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1815 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1816 if(after_request
!= NULL
)
1817 lttv_hooks_destroy(after_request
);
1819 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1825 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1826 if(event_hook
!= NULL
)
1827 lttv_hooks_destroy(event_hook
);
1829 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1830 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
1835 LttvHooksByIdChannelArray
*event_hook_by_id_channel
= (LttvHooksByIdChannelArray
*)*(value
.v_pointer
);
1836 if(event_hook_by_id_channel
!= NULL
)
1837 lttv_hooks_by_id_channel_destroy(event_hook_by_id_channel
);
1839 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1845 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1846 if(hook_adder
!= NULL
)
1847 lttv_hooks_destroy(hook_adder
);
1849 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1855 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1856 if(hook_remover
!= NULL
)
1857 lttv_hooks_destroy(hook_remover
);
1860 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1861 LTTV_EVENT_HOOK_BY_ID_CHANNEL
);
1862 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1865 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1866 LTTV_AFTER_REQUEST
);
1867 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1868 LTTV_BEFORE_REQUEST
);
1870 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1871 LTTV_AFTER_CHUNK_TRACEFILE
);
1872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1873 LTTV_AFTER_CHUNK_TRACE
);
1874 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1875 LTTV_AFTER_CHUNK_TRACESET
);
1877 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1878 LTTV_BEFORE_CHUNK_TRACEFILE
);
1879 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1880 LTTV_BEFORE_CHUNK_TRACE
);
1881 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1882 LTTV_BEFORE_CHUNK_TRACESET
);
1883 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1885 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1888 /* finally, remove module name */
1890 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1892 g_assert(attribute
);
1893 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1899 * Lock a trace so no other instance can use it.
1901 * @param trace The trace to lock.
1902 * @return 0 on success, -1 if cannot get lock.
1904 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1906 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1907 LttvAttributeValue value
;
1908 LttvAttributeType type
;
1910 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1913 /* Verify the absence of the lock. */
1914 if(type
!= LTTV_NONE
) {
1915 g_critical("Cannot take trace lock");
1919 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1922 /* the value is left unset. The only presence of the attribute is necessary.
1931 * @param trace The trace to unlock.
1932 * @return 0 on success, -1 if cannot unlock (not locked ?).
1934 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1936 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1937 LttvAttributeType type
;
1938 LttvAttributeValue value
;
1940 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1943 /* Verify the presence of the lock. */
1944 if(type
== LTTV_NONE
) {
1945 g_critical("Cannot release trace lock");
1949 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1956 * Verify if a trace is locked.
1958 * @param trace The trace to verify.
1959 * @return TRUE if locked, FALSE is unlocked.
1961 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1963 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1964 LttvAttributeType type
;
1965 LttvAttributeValue value
;
1967 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1970 /* The only presence of the attribute is necessary. */
1971 if(type
== LTTV_NONE
)