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., 51 Franklin Street, Fifth Floor, 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
*attribute
;
146 LttvAttribute
*g_attribute
= lttv_global_attributes();
148 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 lttv_attribute_add(attribute
,
213 lttv_attribute_add(attribute
,
214 LTTV_REQUESTS_CURRENT
,
217 lttv_attribute_add(attribute
,
221 lttv_attribute_add(attribute
,
227 /* Remove a trace from the global attributes */
229 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
231 LttvAttribute
*g_attribute
= lttv_global_attributes();
232 LttvAttribute
*attribute
;
233 LttvAttributeValue value
;
238 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
242 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
243 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
245 g_assert(trace_v
!= NULL
);
247 /* Remove and background computation that could be in progress */
248 g_idle_remove_by_data(trace_v
);
250 if(trace_v
== trace
) {
252 LttvAttribute
*l_attribute
;
254 /* destroy traceset and tracesetcontext */
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 #endif /* BABEL_CLEANUP */
305 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
306 LTTV_COMPUTATION_TRACESET_CONTEXT
);
307 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
308 LTTV_COMPUTATION_TRACESET
);
309 /* Destroy the traceset and the trace also */
310 lttv_traceset_destroy(ts
);
312 /* finally, remove the global attribute */
313 lttv_attribute_remove(attribute
, i
);
320 static void destroy_dialog(BackgroundRequest
*bg_req
)
322 gtk_widget_destroy(bg_req
->dialog
);
323 bg_req
->dialog
= NULL
;
328 * Function to request data from a specific trace
330 * The memory allocated for the request will be managed by the API.
332 * @param widget the current Window
333 * @param trace the trace to compute
334 * @param module_name the name of the module which registered global computation
338 __EXPORT
void lttvwindowtraces_background_request_queue
339 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
341 BackgroundRequest
*bg_req
;
342 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
343 LttvAttribute
*g_attribute
= lttv_global_attributes();
344 LttvAttribute
*module_attribute
;
345 LttvAttributeValue value
;
346 LttvAttributeType type
;
350 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
356 slist
= (GSList
**)(value
.v_pointer
);
358 /* Verify that the calculator is loaded */
360 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
362 g_assert(module_attribute
);
364 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
365 g_quark_from_string(module_name
),
367 if(type
== LTTV_NONE
) {
368 g_critical("Missing background calculator %s", module_name
);
372 bg_req
= g_new(BackgroundRequest
,1);
373 bg_req
->module_name
= g_quark_from_string(module_name
);
374 bg_req
->trace
= trace
;
376 *slist
= g_slist_append(*slist
, bg_req
);
378 /* Priority lower than live servicing */
379 g_idle_remove_by_data(trace
);
380 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
381 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
384 /* FIXME : show message in status bar, need context and message id */
385 g_info("Background computation for %s started for trace %p", module_name
,
388 gtk_message_dialog_new(
390 GTK_DIALOG_DESTROY_WITH_PARENT
,
391 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
392 "Background computation for %s started for trace %s",
394 trace
->traceset
->filename
);
395 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
396 g_signal_connect_swapped (dialog
, "response",
397 G_CALLBACK (destroy_dialog
),
399 bg_req
->dialog
= dialog
;
400 /* the parent window might vanish : only use this pointer for a
401 * comparison with existing windows */
402 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
403 gtk_widget_show(dialog
);
407 * Remove a background request from a trace.
409 * This should ONLY be used by the modules which registered the global hooks
410 * (module_name). If this is called by the viewers, it may lead to incomplete
411 * and incoherent background processing information.
413 * Even if the module which deals with the hooks removes the background
414 * requests, it may cause a problem if the module gets loaded again in the
415 * session : the data will be partially calculated. The calculation function
416 * must deal with this case correctly.
418 * @param trace the trace to compute
419 * @param module_name the name of the module which registered global computation
423 void lttvwindowtraces_background_request_remove
424 (LttvTrace
*trace
, gchar
*module_name
)
426 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
427 LttvAttributeValue value
;
432 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
438 slist
= (GSList
**)(value
.v_pointer
);
440 for(iter
=*slist
;iter
!=NULL
;) {
441 BackgroundRequest
*bg_req
=
442 (BackgroundRequest
*)iter
->data
;
444 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
445 GSList
*rem_iter
= iter
;
446 iter
=g_slist_next(iter
);
448 *slist
= g_slist_delete_link(*slist
, rem_iter
);
450 iter
=g_slist_next(iter
);
456 * Find a background request in a trace
460 __EXPORT gboolean lttvwindowtraces_background_request_find
461 (LttvTrace
*trace
, gchar
*module_name
)
463 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
464 LttvAttributeValue value
;
469 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
475 slist
= (GSList
**)(value
.v_pointer
);
477 for(iter
=*slist
;iter
!=NULL
;) {
478 BackgroundRequest
*bg_req
=
479 (BackgroundRequest
*)iter
->data
;
481 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
484 iter
=g_slist_next(iter
);
491 * Register a callback to be called when requested data is passed in the next
492 * queued background processing.
494 * @param owner owner of the background notification
495 * @param trace the trace computed
496 * @param notify_time time when notification hooks must be called
497 * @param notify_position position when notification hooks must be called
498 * @param notify Hook to call when the notify position is passed
501 __EXPORT
void lttvwindowtraces_background_notify_queue
505 const LttvTracesetPosition
*notify_position
,
506 const LttvHooks
*notify
)
509 BackgroundNotify
*bg_notify
;
510 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
511 LttvAttributeValue value
;
515 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
521 slist
= (GSList
**)(value
.v_pointer
);
523 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
524 LTTV_COMPUTATION_TRACESET_CONTEXT
,
529 LttvTraceset
*ts
= (LttvTraceset
)(value
.v_pointer
);
531 bg_notify
= g_new(BackgroundNotify
,1);
533 bg_notify
->owner
= owner
;
534 bg_notify
->trace
= trace
;
535 bg_notify
->notify_time
= notify_time
;
536 if(notify_position
!= NULL
) {
537 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
538 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
541 bg_notify
->notify_position
= NULL
;
544 bg_notify
->notify
= lttv_hooks_new();
545 lttv_hooks_add_list(bg_notify
->notify
, notify
);
547 *slist
= g_slist_append(*slist
, bg_notify
);
548 #endif /* BABEL_CLEANUP*/
552 * Register a callback to be called when requested data is passed in the current
553 * background processing.
555 * @param owner owner of the background notification
556 * @param trace the trace computed
557 * @param notify_time time when notification hooks must be called
558 * @param notify_position position when notification hooks must be called
559 * @param notify Hook to call when the notify position is passed
562 __EXPORT
void lttvwindowtraces_background_notify_current
566 const LttvTracesetPosition
*notify_position
,
567 const LttvHooks
*notify
)
570 BackgroundNotify
*bg_notify
;
571 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
572 LttvAttributeValue value
;
576 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
582 slist
= (GSList
**)(value
.v_pointer
);
584 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
585 LTTV_COMPUTATION_TRACESET_CONTEXT
,
590 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
593 bg_notify
= g_new(BackgroundNotify
,1);
595 bg_notify
->owner
= owner
;
596 bg_notify
->trace
= trace
;
597 bg_notify
->notify_time
= notify_time
;
598 if(notify_position
!= NULL
) {
599 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
600 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
603 bg_notify
->notify_position
= NULL
;
605 bg_notify
->notify
= lttv_hooks_new();
606 lttv_hooks_add_list(bg_notify
->notify
, notify
);
608 *slist
= g_slist_append(*slist
, bg_notify
);
609 #endif /* BABEL_CLEANUP */
613 static void notify_request_free(BackgroundNotify
*notify_req
)
616 if(notify_req
== NULL
) return;
618 if(notify_req
->notify_position
!= NULL
)
619 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
620 if(notify_req
->notify
!= NULL
)
621 lttv_hooks_destroy(notify_req
->notify
);
623 #endif /* BABEL_CLEANUP */
627 * Removes all the notifications requests from a specific viewer.
629 * @param owner owner of the background notification
632 __EXPORT
void lttvwindowtraces_background_notify_remove(gpointer owner
)
636 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
637 LttvAttribute
*attribute
;
638 LttvAttributeValue value
;
639 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
644 g_assert(trace_v
!= NULL
);
646 attribute
= lttv_trace_attribute(trace_v
);
648 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
654 slist
= (GSList
**)(value
.v_pointer
);
656 for(iter
=*slist
;iter
!=NULL
;) {
658 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
660 if(bg_notify
->owner
== owner
) {
661 GSList
*rem_iter
= iter
;
662 iter
=g_slist_next(iter
);
663 notify_request_free(bg_notify
);
664 *slist
= g_slist_remove_link(*slist
, rem_iter
);
666 iter
=g_slist_next(iter
);
670 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
676 slist
= (GSList
**)(value
.v_pointer
);
678 for(iter
=*slist
;iter
!=NULL
;) {
680 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
682 if(bg_notify
->owner
== owner
) {
683 GSList
*rem_iter
= iter
;
684 iter
=g_slist_next(iter
);
685 notify_request_free(bg_notify
);
686 *slist
= g_slist_remove_link(*slist
, rem_iter
);
688 iter
=g_slist_next(iter
);
695 /* Background processing helper functions */
697 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
699 LttvHooks
*hook_adder
)
702 LttvAttribute
*g_attribute
= lttv_global_attributes();
703 LttvAttribute
*module_attribute
;
704 LttvAttributeType type
;
705 LttvAttributeValue value
;
709 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
711 g_assert(module_attribute
);
714 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
715 LTTV_IATTRIBUTE(module_attribute
),
717 g_assert(module_attribute
);
719 /* Call the module's hook adder */
720 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
723 if(type
== LTTV_POINTER
) {
724 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
725 if(hook_adder
!= NULL
)
726 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
728 #endif /* BABEL_CLEANUP */
731 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
733 LttvHooks
*hook_remover
)
736 LttvAttribute
*g_attribute
= lttv_global_attributes();
737 LttvAttribute
*module_attribute
;
738 LttvAttributeType type
;
739 LttvAttributeValue value
;
742 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
744 g_assert(module_attribute
);
747 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
748 LTTV_IATTRIBUTE(module_attribute
),
750 g_assert(module_attribute
);
752 /* Call the module's hook remover */
753 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
756 if(type
== LTTV_POINTER
) {
757 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
758 if(hook_remover
!= NULL
)
759 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
761 #endif /* BABEL_CLEANUP */
764 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
768 LttvAttribute
*g_attribute
= lttv_global_attributes();
769 LttvAttribute
*module_attribute
;
770 LttvAttributeType type
;
771 LttvAttributeValue value
;
772 LttvHooks
*before_chunk_traceset
=NULL
;
773 LttvHooks
*before_chunk_trace
=NULL
;
774 LttvHooks
*before_chunk_tracefile
=NULL
;
775 LttvHooks
*event_hook
=NULL
;
776 LttvHooksByIdChannelArray
*event_hook_by_id_channel
=NULL
;
780 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
782 g_assert(module_attribute
);
785 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
786 LTTV_IATTRIBUTE(module_attribute
),
788 g_assert(module_attribute
);
790 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
791 LTTV_BEFORE_CHUNK_TRACESET
,
793 if(type
== LTTV_POINTER
) {
794 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
797 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
798 LTTV_BEFORE_CHUNK_TRACE
,
800 if(type
== LTTV_POINTER
) {
801 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
804 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
805 LTTV_BEFORE_CHUNK_TRACEFILE
,
807 if(type
== LTTV_POINTER
) {
808 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
811 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
814 if(type
== LTTV_POINTER
) {
815 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
818 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
819 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
821 if(type
== LTTV_POINTER
) {
822 event_hook_by_id_channel
= (LttvHooksByIdChannelArray
*)*(value
.v_pointer
);
825 lttv_process_traceset_begin(tsc
,
826 before_chunk_traceset
,
828 before_chunk_tracefile
,
830 event_hook_by_id_channel
);
831 #endif /* BABEL_CLEANUP */
836 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
839 #warning "lttvwindowtraces_call_after_chunk does nothing"
841 LttvAttribute
*g_attribute
= lttv_global_attributes();
842 LttvAttribute
*module_attribute
;
843 LttvAttributeType type
;
844 LttvAttributeValue value
;
845 LttvHooks
*after_chunk_traceset
=NULL
;
846 LttvHooks
*after_chunk_trace
=NULL
;
847 LttvHooks
*after_chunk_tracefile
=NULL
;
848 LttvHooks
*event_hook
=NULL
;
851 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
853 g_assert(module_attribute
);
856 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
857 LTTV_IATTRIBUTE(module_attribute
),
859 g_assert(module_attribute
);
861 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
862 LTTV_AFTER_CHUNK_TRACESET
,
864 if(type
== LTTV_POINTER
) {
865 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
868 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
869 LTTV_AFTER_CHUNK_TRACE
,
871 if(type
== LTTV_POINTER
) {
872 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
875 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
876 LTTV_AFTER_CHUNK_TRACEFILE
,
878 if(type
== LTTV_POINTER
) {
879 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
882 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
885 if(type
== LTTV_POINTER
) {
886 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
889 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
890 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
892 lttv_process_traceset_end(tsc
,
893 after_chunk_traceset
,
895 after_chunk_tracefile
,
897 #endif /* BABEL_CLEANUP*/
902 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
905 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
908 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
912 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
915 /* the value is left unset. The only presence of the attribute is necessary.
919 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
922 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
925 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
929 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
933 __EXPORT gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
936 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
937 LttvAttributeType type
;
938 LttvAttributeValue value
;
941 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
945 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
948 /* The only presence of the attribute is necessary. */
949 if(type
== LTTV_NONE
)
955 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
958 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
961 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
965 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
968 /* the value is left unset. The only presence of the attribute is necessary.
972 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
975 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
978 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
982 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
986 __EXPORT gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
989 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
990 LttvAttributeType type
;
991 LttvAttributeValue value
;
994 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
998 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1001 /* The only presence of the attribute is necessary. */
1002 if(type
== LTTV_NONE
)
1007 #ifdef BABEL_CLEANUP
1008 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
1010 if(a
->mwindow
== b
) return 0;
1015 /* lttvwindowtraces_process_pending_requests
1017 * Process the pending background computation requests
1019 * This internal function gets called by g_idle, taking care of the pending
1025 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
1027 gboolean ret_val
= FALSE
;
1028 #ifdef BABEL_CLEANUP
1029 LttvAttribute
*attribute
;
1030 LttvAttribute
*g_attribute
= lttv_global_attributes();
1031 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
1032 LttvAttributeValue value
;
1033 LttvAttributeType type
;
1039 if(lttvwindow_preempt_count
> 0) return TRUE
;
1041 attribute
= lttv_trace_attribute(trace
);
1043 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1044 LTTV_REQUESTS_QUEUE
,
1046 g_assert(type
== LTTV_POINTER
);
1047 list_out
= (GSList
**)(value
.v_pointer
);
1049 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1050 LTTV_REQUESTS_CURRENT
,
1052 g_assert(type
== LTTV_POINTER
);
1053 list_in
= (GSList
**)(value
.v_pointer
);
1055 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1058 g_assert(type
== LTTV_POINTER
);
1059 notify_out
= (GSList
**)(value
.v_pointer
);
1061 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1062 LTTV_NOTIFY_CURRENT
,
1064 g_assert(type
== LTTV_POINTER
);
1065 notify_in
= (GSList
**)(value
.v_pointer
);
1067 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1068 LTTV_COMPUTATION_TRACESET
,
1070 g_assert(type
== LTTV_POINTER
);
1071 #ifdef BABEL_CLEANUP
1072 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1075 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1076 LTTV_COMPUTATION_SYNC_POSITION
,
1078 g_assert(type
== LTTV_POINTER
);
1079 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1081 //#ifdef BABEL_CLEANUP moved at the beginning of the function
1082 /* There is no events requests pending : we should never have been called! */
1083 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1084 /* 0.1 Lock traces */
1089 iter_trace
<lttv_traceset_number(ts
->ts
);
1091 LttvTrace
*trace_v
= lttv_traceset_get(ts
->ts
,iter_trace
);
1093 if(lttvwindowtraces_lock(trace_v
) != 0)
1094 return TRUE
; /* Cannot get trace lock, try later */
1098 /* 0.2 Sync tracefiles */
1099 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1100 lttv_process_traceset_synchronize_tracefiles(tsc
);
1101 /* 1. Before processing */
1103 /* if list_in is empty */
1104 if(g_slist_length(*list_in
) == 0) {
1107 /* - Add all requests in list_out to list_in, empty list_out */
1108 GSList
*iter
= *list_out
;
1110 while(iter
!= NULL
) {
1111 gboolean remove
= FALSE
;
1112 gboolean free_data
= FALSE
;
1114 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1118 *list_in
= g_slist_append(*list_in
, bg_req
);
1123 GSList
*remove_iter
= iter
;
1125 iter
= g_slist_next(iter
);
1126 if(free_data
) g_free(remove_iter
->data
);
1127 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1128 } else { // not remove
1129 iter
= g_slist_next(iter
);
1135 GSList
*iter
= *list_in
;
1136 /* - for each request in list_in */
1137 while(iter
!= NULL
) {
1139 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1140 /* - set hooks'in_progress flag to TRUE */
1141 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1144 /* - call before request hook */
1145 /* Get before request hook */
1146 LttvAttribute
*module_attribute
;
1149 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1150 LTTV_IATTRIBUTE(g_attribute
),
1152 g_assert(module_attribute
);
1155 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1156 LTTV_IATTRIBUTE(module_attribute
),
1157 bg_req
->module_name
));
1158 g_assert(module_attribute
);
1160 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1161 LTTV_BEFORE_REQUEST
,
1163 g_assert(type
== LTTV_POINTER
);
1164 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1166 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1168 iter
= g_slist_next(iter
);
1172 /* - seek trace to start */
1174 LttTime start
= { 0, 0};
1175 lttv_process_traceset_seek_time(tsc
, start
);
1178 /* - Move all notifications from notify_out to notify_in. */
1180 GSList
*iter
= *notify_out
;
1181 g_assert(g_slist_length(*notify_in
) == 0);
1183 while(iter
!= NULL
) {
1184 gboolean remove
= FALSE
;
1185 gboolean free_data
= FALSE
;
1187 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1191 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1196 GSList
*remove_iter
= iter
;
1198 iter
= g_slist_next(iter
);
1200 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1201 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1202 } else { // not remove
1203 iter
= g_slist_next(iter
);
1208 GSList
*iter
= *list_in
;
1209 LttvHooks
*hook_adder
= lttv_hooks_new();
1210 /* - for each request in list_in */
1211 while(iter
!= NULL
) {
1213 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1214 /*- add hooks to context*/
1215 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1218 iter
= g_slist_next(iter
);
1220 lttv_hooks_call(hook_adder
,tsc
);
1221 lttv_hooks_destroy(hook_adder
);
1228 GSList
*iter
= *list_in
;
1229 /* - for each request in list_in */
1230 while(iter
!= NULL
) {
1232 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1233 /*- Call before chunk hooks for list_in*/
1234 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1236 iter
= g_slist_next(iter
);
1241 /* 2. call process traceset middle for a chunk */
1243 /*(assert list_in is not empty! : should not even be called in that case)*/
1244 LttTime end
= ltt_time_infinite
;
1245 g_assert(g_slist_length(*list_in
) != 0);
1247 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1250 /* 3. After the chunk */
1252 /* 3.1 call after_chunk hooks for list_in */
1254 GSList
*iter
= *list_in
;
1255 /* - for each request in list_in */
1256 while(iter
!= NULL
) {
1258 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1259 /* - Call after chunk hooks for list_in */
1260 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1262 iter
= g_slist_next(iter
);
1266 /* 3.2 for each notify_in */
1268 GSList
*iter
= *notify_in
;
1269 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1271 while(iter
!= NULL
) {
1272 gboolean remove
= FALSE
;
1273 gboolean free_data
= FALSE
;
1275 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1277 /* - if current time >= notify time, call notify and remove from
1279 * - if current position >= notify position, call notify and remove
1283 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1285 (notify_req
->notify_position
!= NULL
&&
1286 lttv_traceset_context_ctx_pos_compare(tsc
,
1287 notify_req
->notify_position
) >= 0)
1290 lttv_hooks_call(notify_req
->notify
, notify_req
);
1299 GSList
*remove_iter
= iter
;
1301 iter
= g_slist_next(iter
);
1303 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1304 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1305 } else { // not remove
1306 iter
= g_slist_next(iter
);
1312 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1313 /* 3.3 if end of trace reached */
1315 g_debug("Current time : %lu sec, %lu nsec",
1316 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1317 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1318 tsc
->time_span
.end_time
) > 0) {
1321 GSList
*iter
= *list_in
;
1322 LttvHooks
*hook_remover
= lttv_hooks_new();
1323 /* - for each request in list_in */
1324 while(iter
!= NULL
) {
1326 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1327 /* - remove hooks from context */
1328 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1331 iter
= g_slist_next(iter
);
1333 lttv_hooks_call(hook_remover
,tsc
);
1334 lttv_hooks_destroy(hook_remover
);
1337 /* - for each request in list_in */
1339 GSList
*iter
= *list_in
;
1341 while(iter
!= NULL
) {
1342 gboolean remove
= FALSE
;
1343 gboolean free_data
= FALSE
;
1345 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1347 /* - set hooks'in_progress flag to FALSE */
1348 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1350 /* - set hooks'ready flag to TRUE */
1351 lttvwindowtraces_set_ready(bg_req
->module_name
,
1353 /* - call after request hook */
1354 /* Get after request hook */
1355 LttvAttribute
*module_attribute
;
1358 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1359 LTTV_IATTRIBUTE(g_attribute
),
1361 g_assert(module_attribute
);
1364 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1365 LTTV_IATTRIBUTE(module_attribute
),
1366 bg_req
->module_name
));
1367 g_assert(module_attribute
);
1369 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1372 g_assert(type
== LTTV_POINTER
);
1373 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1375 struct sum_traceset_closure t_closure
;
1376 t_closure
.tss
= (LttvTracesetStats
*)tsc
;
1377 t_closure
.current_time
= ltt_time_infinite
;
1378 if(after_request
!= NULL
) lttv_hooks_call(after_request
,
1382 if(bg_req
->dialog
!= NULL
)
1383 gtk_widget_destroy(bg_req
->dialog
);
1384 GtkWidget
*parent_window
;
1385 if(g_slist_find_custom(g_main_window_list
,
1386 bg_req
->parent_window
,
1387 (GCompareFunc
)find_window_widget
))
1388 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1390 parent_window
= NULL
;
1393 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1394 GTK_DIALOG_DESTROY_WITH_PARENT
,
1395 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1396 "Background computation %s finished for trace %s",
1397 g_quark_to_string(bg_req
->module_name
),
1398 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1399 if(parent_window
!= NULL
)
1400 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1401 GTK_WINDOW(parent_window
));
1402 g_signal_connect_swapped (dialog
, "response",
1403 G_CALLBACK (gtk_widget_destroy
),
1405 gtk_widget_show(dialog
);
1407 /* - remove request */
1414 GSList
*remove_iter
= iter
;
1416 iter
= g_slist_next(iter
);
1417 if(free_data
) g_free(remove_iter
->data
);
1418 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1419 } else { // not remove
1420 iter
= g_slist_next(iter
);
1425 /* - for each notifications in notify_in */
1427 GSList
*iter
= *notify_in
;
1429 while(iter
!= NULL
) {
1430 gboolean remove
= FALSE
;
1431 gboolean free_data
= FALSE
;
1433 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1435 /* - call notify and remove from notify_in */
1436 lttv_hooks_call(notify_req
->notify
, notify_req
);
1443 GSList
*remove_iter
= iter
;
1445 iter
= g_slist_next(iter
);
1447 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1448 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1449 } else { // not remove
1450 iter
= g_slist_next(iter
);
1455 /* - reset the context */
1456 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1457 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1459 /* - if list_out is empty */
1460 if(g_slist_length(*list_out
) == 0) {
1461 /* - return FALSE (scheduler stopped) */
1462 g_debug("Background computation scheduler stopped");
1463 g_info("Background computation finished for trace %p", trace
);
1464 /* FIXME : remove status bar info, need context id and message id */
1471 /* 3.4 else, end of trace not reached */
1472 /* - return TRUE (scheduler still registered) */
1473 g_debug("Background computation left");
1478 /* 4. Unlock traces */
1480 lttv_process_traceset_get_sync_data(tsc
);
1481 //lttv_traceset_context_position_save(tsc, sync_position);
1485 iter_trace
<lttv_traceset_number(tsc
->ts
);
1487 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1489 lttvwindowtraces_unlock(trace_v
);
1492 #endif /* BABEL_CLEANUP */
1499 * Register the background computation hooks for a specific module. It adds the
1500 * computation hooks to the global attrubutes, under "computation/module name".
1502 * @param module_name A GQuark : the name of the module which computes the
1505 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1506 LttvHooks
*before_chunk_traceset
,
1507 LttvHooks
*before_chunk_trace
,
1508 LttvHooks
*before_chunk_tracefile
,
1509 LttvHooks
*after_chunk_traceset
,
1510 LttvHooks
*after_chunk_trace
,
1511 LttvHooks
*after_chunk_tracefile
,
1512 LttvHooks
*before_request
,
1513 LttvHooks
*after_request
,
1514 LttvHooks
*event_hook
,
1515 LttvHooks
*hook_adder
,
1516 LttvHooks
*hook_remover
)
1518 LttvAttribute
*g_attribute
= lttv_global_attributes();
1519 LttvAttribute
*attribute
;
1520 LttvAttributeValue value
;
1524 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1526 g_assert(attribute
);
1529 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1531 g_assert(attribute
);
1533 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1534 LTTV_BEFORE_CHUNK_TRACESET
,
1539 *(value
.v_pointer
) = before_chunk_traceset
;
1541 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1542 LTTV_BEFORE_CHUNK_TRACE
,
1546 *(value
.v_pointer
) = before_chunk_trace
;
1548 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1549 LTTV_BEFORE_CHUNK_TRACEFILE
,
1553 *(value
.v_pointer
) = before_chunk_tracefile
;
1555 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1556 LTTV_AFTER_CHUNK_TRACESET
,
1560 *(value
.v_pointer
) = after_chunk_traceset
;
1562 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1563 LTTV_AFTER_CHUNK_TRACE
,
1567 *(value
.v_pointer
) = after_chunk_trace
;
1569 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1570 LTTV_AFTER_CHUNK_TRACEFILE
,
1574 *(value
.v_pointer
) = after_chunk_tracefile
;
1576 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1577 LTTV_BEFORE_REQUEST
,
1581 *(value
.v_pointer
) = before_request
;
1583 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1588 *(value
.v_pointer
) = after_request
;
1590 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1595 *(value
.v_pointer
) = event_hook
;
1597 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1602 *(value
.v_pointer
) = hook_adder
;
1604 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1609 *(value
.v_pointer
) = hook_remover
;
1615 * It removes all the requests that can be currently processed by the
1616 * background computation algorithm for all the traces (list_in and list_out).
1618 * Leaves the flag to in_progress or none.. depending if current or queue
1620 * @param module_name A GQuark : the name of the module which computes the
1623 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1628 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1629 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1630 g_assert(trace_v
!= NULL
);
1631 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1632 LttvAttributeValue value
;
1633 GSList
**queue
, **current
;
1636 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1637 LTTV_REQUESTS_QUEUE
,
1642 queue
= (GSList
**)(value
.v_pointer
);
1645 while(iter
!= NULL
) {
1646 gboolean remove
= FALSE
;
1647 gboolean free_data
= FALSE
;
1649 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1651 if(bg_req
->module_name
== module_name
) {
1659 GSList
*remove_iter
= iter
;
1661 iter
= g_slist_next(iter
);
1662 if(free_data
) g_free(remove_iter
->data
);
1663 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1664 } else { // not remove
1665 iter
= g_slist_next(iter
);
1670 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1671 LTTV_REQUESTS_CURRENT
,
1676 current
= (GSList
**)(value
.v_pointer
);
1679 while(iter
!= NULL
) {
1680 gboolean remove
= FALSE
;
1681 gboolean free_data
= FALSE
;
1683 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1685 if(bg_req
->module_name
== module_name
) {
1693 GSList
*remove_iter
= iter
;
1695 iter
= g_slist_next(iter
);
1696 if(free_data
) g_free(remove_iter
->data
);
1697 *current
= g_slist_remove_link(*current
, remove_iter
);
1698 } else { // not remove
1699 iter
= g_slist_next(iter
);
1707 * Unregister the background computation hooks for a specific module.
1709 * It also removes all the requests that can be currently processed by the
1710 * background computation algorithm for all the traces (list_in and list_out).
1712 * @param module_name A GQuark : the name of the module which computes the
1716 void lttvwindowtraces_unregister_computation_hooks
1717 (LttvAttributeName module_name
)
1719 LttvAttribute
*g_attribute
= lttv_global_attributes();
1720 LttvAttribute
*attribute
;
1721 LttvAttributeValue value
;
1725 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1727 g_assert(attribute
);
1730 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1732 g_assert(attribute
);
1734 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1735 LTTV_BEFORE_CHUNK_TRACESET
,
1740 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1741 if(before_chunk_traceset
!= NULL
)
1742 lttv_hooks_destroy(before_chunk_traceset
);
1744 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1745 LTTV_BEFORE_CHUNK_TRACE
,
1750 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1751 if(before_chunk_trace
!= NULL
)
1752 lttv_hooks_destroy(before_chunk_trace
);
1754 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1755 LTTV_BEFORE_CHUNK_TRACEFILE
,
1760 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1761 if(before_chunk_tracefile
!= NULL
)
1762 lttv_hooks_destroy(before_chunk_tracefile
);
1764 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1765 LTTV_AFTER_CHUNK_TRACESET
,
1770 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1771 if(after_chunk_traceset
!= NULL
)
1772 lttv_hooks_destroy(after_chunk_traceset
);
1774 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1775 LTTV_AFTER_CHUNK_TRACE
,
1780 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1781 if(after_chunk_trace
!= NULL
)
1782 lttv_hooks_destroy(after_chunk_trace
);
1784 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1785 LTTV_AFTER_CHUNK_TRACEFILE
,
1790 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1791 if(after_chunk_tracefile
!= NULL
)
1792 lttv_hooks_destroy(after_chunk_tracefile
);
1794 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1795 LTTV_BEFORE_REQUEST
,
1800 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1801 if(before_request
!= NULL
)
1802 lttv_hooks_destroy(before_request
);
1804 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1810 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1811 if(after_request
!= NULL
)
1812 lttv_hooks_destroy(after_request
);
1814 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1820 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1821 if(event_hook
!= NULL
)
1822 lttv_hooks_destroy(event_hook
);
1824 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1825 LTTV_EVENT_HOOK_BY_ID_CHANNEL
,
1830 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1836 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1837 if(hook_adder
!= NULL
)
1838 lttv_hooks_destroy(hook_adder
);
1840 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1846 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1847 if(hook_remover
!= NULL
)
1848 lttv_hooks_destroy(hook_remover
);
1851 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1852 LTTV_EVENT_HOOK_BY_ID_CHANNEL
);
1853 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1856 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1857 LTTV_AFTER_REQUEST
);
1858 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1859 LTTV_BEFORE_REQUEST
);
1861 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1862 LTTV_AFTER_CHUNK_TRACEFILE
);
1863 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1864 LTTV_AFTER_CHUNK_TRACE
);
1865 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1866 LTTV_AFTER_CHUNK_TRACESET
);
1868 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1869 LTTV_BEFORE_CHUNK_TRACEFILE
);
1870 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1871 LTTV_BEFORE_CHUNK_TRACE
);
1872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1873 LTTV_BEFORE_CHUNK_TRACESET
);
1874 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1876 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1879 /* finally, remove module name */
1881 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1883 g_assert(attribute
);
1884 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1890 * Lock a trace so no other instance can use it.
1892 * @param trace The trace to lock.
1893 * @return 0 on success, -1 if cannot get lock.
1895 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1897 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1898 LttvAttributeValue value
;
1899 LttvAttributeType type
;
1901 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1904 /* Verify the absence of the lock. */
1905 if(type
!= LTTV_NONE
) {
1906 g_critical("Cannot take trace lock");
1910 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1913 /* the value is left unset. The only presence of the attribute is necessary.
1922 * @param trace The trace to unlock.
1923 * @return 0 on success, -1 if cannot unlock (not locked ?).
1925 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1927 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1928 LttvAttributeType type
;
1929 LttvAttributeValue value
;
1931 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1934 /* Verify the presence of the lock. */
1935 if(type
== LTTV_NONE
) {
1936 g_critical("Cannot release trace lock");
1940 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1947 * Verify if a trace is locked.
1949 * @param trace The trace to verify.
1950 * @return TRUE if locked, FALSE is unlocked.
1952 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1954 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1955 LttvAttributeType type
;
1956 LttvAttributeValue value
;
1958 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1961 /* The only presence of the attribute is necessary. */
1962 if(type
== LTTV_NONE
)