1 /* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 /* This file is the API used to launch any background computation on a trace */
21 /* Here is the implementation of the API */
27 #include <sys/types.h>
33 #include <ltt/trace.h>
35 #include <lttv/lttv.h>
36 #include <lttv/traceset.h>
37 #include <lttv/attribute.h>
38 #include <lttv/tracecontext.h>
39 #include <lttvwindow/lttvwindowtraces.h>
40 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
41 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
43 extern GSList
* g_main_window_list
;
45 typedef struct _BackgroundRequest
{
46 LttvAttributeName module_name
; /* Hook path in global attributes,
47 where all standard hooks under computation/.
49 LttvTrace
*trace
; /* trace concerned */
50 GtkWidget
*dialog
; /* Dialog linked with the request, may be NULL */
51 GtkWidget
*parent_window
; /* Parent window the dialog must be transient for */
54 typedef struct _BackgroundNotify
{
56 LttvTrace
*trace
; /* trace */
58 LttvTracesetContextPosition
*notify_position
;
59 LttvHooks
*notify
; /* Hook to call when the notify is
60 passed, or at the end of trace */
66 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
68 /* Get a trace by its path name.
70 * @param path path of the trace on the virtual file system.
71 * @return Pointer to trace if found
72 * NULL is returned if the trace is not present
75 __EXPORT LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
79 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
80 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
83 g_assert(trace_v
!= NULL
);
85 trace
= lttv_trace(trace_v
);
86 g_assert(trace
!= NULL
);
87 name
= g_quark_to_string(ltt_trace_name(trace
));
89 if(strcmp(name
, path
) == 0) {
98 /* Get a trace by its number identifier */
100 __EXPORT LttvTrace
*lttvwindowtraces_get_trace(guint num
)
102 LttvAttribute
*g_attribute
= lttv_global_attributes();
103 LttvAttribute
*attribute
;
104 LttvAttributeType type
;
105 LttvAttributeName name
;
106 LttvAttributeValue value
;
110 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
114 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
,
117 if(type
== LTTV_POINTER
) {
118 return (LttvTrace
*)*(value
.v_pointer
);
124 /* Total number of traces */
126 __EXPORT guint
lttvwindowtraces_get_number()
128 LttvAttribute
*g_attribute
= lttv_global_attributes();
129 LttvAttribute
*attribute
;
132 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
136 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
139 /* Add a trace to the global attributes */
141 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
143 LttvAttribute
*g_attribute
= lttv_global_attributes();
144 LttvAttribute
*attribute
;
145 LttvAttributeValue value
;
147 gchar attribute_path
[PATH_MAX
];
151 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
152 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
153 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
156 result
= snprintf(attribute_path
, PATH_MAX
, "%llu:%llu", buf
.st_dev
, buf
.st_ino
);
157 g_assert(result
>= 0);
160 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
164 value
= lttv_attribute_add(attribute
,
165 g_quark_from_string(attribute_path
),
168 *(value
.v_pointer
) = (gpointer
)trace
;
170 /* create new traceset and tracesetcontext */
172 LttvTracesetStats
*tss
;
173 //LttvTracesetContextPosition *sync_position;
175 attribute
= lttv_trace_attribute(trace
);
176 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
177 LTTV_COMPUTATION_TRACESET
,
182 ts
= lttv_traceset_new();
183 *(value
.v_pointer
) = ts
;
185 lttv_traceset_add(ts
,trace
);
187 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
188 LTTV_COMPUTATION_TRACESET_CONTEXT
,
193 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
194 *(value
.v_pointer
) = tss
;
196 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
198 result_b
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
199 LTTV_COMPUTATION_SYNC_POSITION
,
204 sync_position
= lttv_traceset_context_position_new();
205 *(value
.v_pointer
) = sync_position
;
207 value
= lttv_attribute_add(attribute
,
211 value
= lttv_attribute_add(attribute
,
212 LTTV_REQUESTS_CURRENT
,
215 value
= lttv_attribute_add(attribute
,
219 value
= lttv_attribute_add(attribute
,
224 /* Remove a trace from the global attributes */
226 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
228 LttvAttribute
*g_attribute
= lttv_global_attributes();
229 LttvAttribute
*attribute
;
230 LttvAttributeValue value
;
235 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
239 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
240 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
242 g_assert(trace_v
!= NULL
);
244 /* Remove and background computation that could be in progress */
245 g_idle_remove_by_data(trace_v
);
247 if(trace_v
== trace
) {
249 LttvAttribute
*l_attribute
;
251 /* destroy traceset and tracesetcontext */
253 LttvTracesetStats
*tss
;
254 //LttvTracesetContextPosition *sync_position;
256 l_attribute
= lttv_trace_attribute(trace
);
259 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
260 LTTV_REQUESTS_QUEUE
);
262 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
263 LTTV_REQUESTS_CURRENT
);
265 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
268 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
269 LTTV_NOTIFY_CURRENT
);
271 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
272 LTTV_COMPUTATION_TRACESET
,
277 ts
= (LttvTraceset
*)*(value
.v_pointer
);
279 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
280 LTTV_COMPUTATION_SYNC_POSITION
,
285 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
286 lttv_traceset_context_position_destroy(sync_position
);
288 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
289 LTTV_COMPUTATION_SYNC_POSITION
);
292 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
293 LTTV_COMPUTATION_TRACESET_CONTEXT
,
298 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
300 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
302 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
303 LTTV_COMPUTATION_TRACESET_CONTEXT
);
304 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
305 LTTV_COMPUTATION_TRACESET
);
306 /* Destroy the traceset and the trace also */
307 lttv_traceset_destroy(ts
);
309 /* finally, remove the global attribute */
310 lttv_attribute_remove(attribute
, i
);
317 static void destroy_dialog(BackgroundRequest
*bg_req
)
319 gtk_widget_destroy(bg_req
->dialog
);
320 bg_req
->dialog
= NULL
;
325 * Function to request data from a specific trace
327 * The memory allocated for the request will be managed by the API.
329 * @param widget the current Window
330 * @param trace the trace to compute
331 * @param module_name the name of the module which registered global computation
335 __EXPORT
void lttvwindowtraces_background_request_queue
336 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
338 BackgroundRequest
*bg_req
;
339 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
340 LttvAttribute
*g_attribute
= lttv_global_attributes();
341 LttvAttribute
*module_attribute
;
342 LttvAttributeValue value
;
343 LttvAttributeType type
;
347 lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
353 slist
= (GSList
**)(value
.v_pointer
);
355 /* Verify that the calculator is loaded */
357 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
359 g_assert(module_attribute
);
361 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
362 g_quark_from_string(module_name
),
364 if(type
== LTTV_NONE
) {
365 g_critical("Missing background calculator %s", module_name
);
369 bg_req
= g_new(BackgroundRequest
,1);
370 bg_req
->module_name
= g_quark_from_string(module_name
);
371 bg_req
->trace
= trace
;
373 *slist
= g_slist_append(*slist
, bg_req
);
375 /* Priority lower than live servicing */
376 g_idle_remove_by_data(trace
);
377 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
378 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
381 /* FIXME : show message in status bar, need context and message id */
382 g_info("Background computation for %s started for trace %p", module_name
,
385 gtk_message_dialog_new(
387 GTK_DIALOG_DESTROY_WITH_PARENT
,
388 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
389 "Background computation for %s started for trace %s",
391 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
392 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
393 g_signal_connect_swapped (dialog
, "response",
394 G_CALLBACK (destroy_dialog
),
396 bg_req
->dialog
= dialog
;
397 /* the parent window might vanish : only use this pointer for a
398 * comparison with existing windows */
399 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
400 gtk_widget_show(dialog
);
404 * Remove a background request from a trace.
406 * This should ONLY be used by the modules which registered the global hooks
407 * (module_name). If this is called by the viewers, it may lead to incomplete
408 * and incoherent background processing information.
410 * Even if the module which deals with the hooks removes the background
411 * requests, it may cause a problem if the module gets loaded again in the
412 * session : the data will be partially calculated. The calculation function
413 * must deal with this case correctly.
415 * @param trace the trace to compute
416 * @param module_name the name of the module which registered global computation
420 void lttvwindowtraces_background_request_remove
421 (LttvTrace
*trace
, gchar
*module_name
)
423 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
424 LttvAttributeValue value
;
429 lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
435 slist
= (GSList
**)(value
.v_pointer
);
437 for(iter
=*slist
;iter
!=NULL
;) {
438 BackgroundRequest
*bg_req
=
439 (BackgroundRequest
*)iter
->data
;
441 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
442 GSList
*rem_iter
= iter
;
443 iter
=g_slist_next(iter
);
445 *slist
= g_slist_delete_link(*slist
, rem_iter
);
447 iter
=g_slist_next(iter
);
453 * Find a background request in a trace
457 __EXPORT gboolean lttvwindowtraces_background_request_find
458 (LttvTrace
*trace
, gchar
*module_name
)
460 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
461 LttvAttributeValue value
;
466 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
472 slist
= (GSList
**)(value
.v_pointer
);
474 for(iter
=*slist
;iter
!=NULL
;) {
475 BackgroundRequest
*bg_req
=
476 (BackgroundRequest
*)iter
->data
;
478 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
481 iter
=g_slist_next(iter
);
488 * Register a callback to be called when requested data is passed in the next
489 * queued background processing.
491 * @param owner owner of the background notification
492 * @param trace the trace computed
493 * @param notify_time time when notification hooks must be called
494 * @param notify_position position when notification hooks must be called
495 * @param notify Hook to call when the notify position is passed
498 __EXPORT
void lttvwindowtraces_background_notify_queue
502 const LttvTracesetContextPosition
*notify_position
,
503 const LttvHooks
*notify
)
505 BackgroundNotify
*bg_notify
;
506 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
507 LttvAttributeValue value
;
511 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
517 slist
= (GSList
**)(value
.v_pointer
);
519 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
520 LTTV_COMPUTATION_TRACESET_CONTEXT
,
525 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
527 bg_notify
= g_new(BackgroundNotify
,1);
529 bg_notify
->owner
= owner
;
530 bg_notify
->trace
= trace
;
531 bg_notify
->notify_time
= notify_time
;
532 if(notify_position
!= NULL
) {
533 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
534 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
537 bg_notify
->notify_position
= NULL
;
540 bg_notify
->notify
= lttv_hooks_new();
541 lttv_hooks_add_list(bg_notify
->notify
, notify
);
543 *slist
= g_slist_append(*slist
, bg_notify
);
547 * Register a callback to be called when requested data is passed in the current
548 * background processing.
550 * @param owner owner of the background notification
551 * @param trace the trace computed
552 * @param notify_time time when notification hooks must be called
553 * @param notify_position position when notification hooks must be called
554 * @param notify Hook to call when the notify position is passed
557 __EXPORT
void lttvwindowtraces_background_notify_current
561 const LttvTracesetContextPosition
*notify_position
,
562 const LttvHooks
*notify
)
564 BackgroundNotify
*bg_notify
;
565 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
566 LttvAttributeValue value
;
570 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
576 slist
= (GSList
**)(value
.v_pointer
);
578 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
579 LTTV_COMPUTATION_TRACESET_CONTEXT
,
584 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
587 bg_notify
= g_new(BackgroundNotify
,1);
589 bg_notify
->owner
= owner
;
590 bg_notify
->trace
= trace
;
591 bg_notify
->notify_time
= notify_time
;
592 if(notify_position
!= NULL
) {
593 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
594 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
597 bg_notify
->notify_position
= NULL
;
599 bg_notify
->notify
= lttv_hooks_new();
600 lttv_hooks_add_list(bg_notify
->notify
, notify
);
602 *slist
= g_slist_append(*slist
, bg_notify
);
606 static void notify_request_free(BackgroundNotify
*notify_req
)
608 if(notify_req
== NULL
) return;
610 if(notify_req
->notify_position
!= NULL
)
611 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
612 if(notify_req
->notify
!= NULL
)
613 lttv_hooks_destroy(notify_req
->notify
);
618 * Removes all the notifications requests from a specific viewer.
620 * @param owner owner of the background notification
623 __EXPORT
void lttvwindowtraces_background_notify_remove(gpointer owner
)
627 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
628 LttvAttribute
*attribute
;
629 LttvAttributeValue value
;
630 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
635 g_assert(trace_v
!= NULL
);
637 attribute
= lttv_trace_attribute(trace_v
);
639 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
645 slist
= (GSList
**)(value
.v_pointer
);
647 for(iter
=*slist
;iter
!=NULL
;) {
649 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
651 if(bg_notify
->owner
== owner
) {
652 GSList
*rem_iter
= iter
;
653 iter
=g_slist_next(iter
);
654 notify_request_free(bg_notify
);
655 *slist
= g_slist_remove_link(*slist
, rem_iter
);
657 iter
=g_slist_next(iter
);
661 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
667 slist
= (GSList
**)(value
.v_pointer
);
669 for(iter
=*slist
;iter
!=NULL
;) {
671 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
673 if(bg_notify
->owner
== owner
) {
674 GSList
*rem_iter
= iter
;
675 iter
=g_slist_next(iter
);
676 notify_request_free(bg_notify
);
677 *slist
= g_slist_remove_link(*slist
, rem_iter
);
679 iter
=g_slist_next(iter
);
686 /* Background processing helper functions */
688 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
689 LttvTracesetContext
*tsc
,
690 LttvHooks
*hook_adder
)
692 LttvAttribute
*g_attribute
= lttv_global_attributes();
693 LttvAttribute
*module_attribute
;
694 LttvAttributeType type
;
695 LttvAttributeValue value
;
699 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
701 g_assert(module_attribute
);
704 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
705 LTTV_IATTRIBUTE(module_attribute
),
707 g_assert(module_attribute
);
709 /* Call the module's hook adder */
710 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
713 if(type
== LTTV_POINTER
) {
714 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
715 if(hook_adder
!= NULL
)
716 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
720 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
721 LttvTracesetContext
*tsc
,
722 LttvHooks
*hook_remover
)
724 LttvAttribute
*g_attribute
= lttv_global_attributes();
725 LttvAttribute
*module_attribute
;
726 LttvAttributeType type
;
727 LttvAttributeValue value
;
730 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
732 g_assert(module_attribute
);
735 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
736 LTTV_IATTRIBUTE(module_attribute
),
738 g_assert(module_attribute
);
740 /* Call the module's hook remover */
741 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
744 if(type
== LTTV_POINTER
) {
745 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
746 if(hook_remover
!= NULL
)
747 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
751 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
752 LttvTracesetContext
*tsc
)
754 LttvAttribute
*g_attribute
= lttv_global_attributes();
755 LttvAttribute
*module_attribute
;
756 LttvAttributeType type
;
757 LttvAttributeValue value
;
758 LttvHooks
*before_chunk_traceset
=NULL
;
759 LttvHooks
*before_chunk_trace
=NULL
;
760 LttvHooks
*before_chunk_tracefile
=NULL
;
761 LttvHooks
*event_hook
=NULL
;
762 LttvHooksById
*event_hook_by_id
=NULL
;
766 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
768 g_assert(module_attribute
);
771 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
772 LTTV_IATTRIBUTE(module_attribute
),
774 g_assert(module_attribute
);
776 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
777 LTTV_BEFORE_CHUNK_TRACESET
,
779 if(type
== LTTV_POINTER
) {
780 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
783 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
784 LTTV_BEFORE_CHUNK_TRACE
,
786 if(type
== LTTV_POINTER
) {
787 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
790 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
791 LTTV_BEFORE_CHUNK_TRACEFILE
,
793 if(type
== LTTV_POINTER
) {
794 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
797 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
800 if(type
== LTTV_POINTER
) {
801 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
804 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
805 LTTV_EVENT_HOOK_BY_ID
,
807 if(type
== LTTV_POINTER
) {
808 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
811 lttv_process_traceset_begin(tsc
,
812 before_chunk_traceset
,
814 before_chunk_tracefile
,
821 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
822 LttvTracesetContext
*tsc
)
824 LttvAttribute
*g_attribute
= lttv_global_attributes();
825 LttvAttribute
*module_attribute
;
826 LttvAttributeType type
;
827 LttvAttributeValue value
;
828 LttvHooks
*after_chunk_traceset
=NULL
;
829 LttvHooks
*after_chunk_trace
=NULL
;
830 LttvHooks
*after_chunk_tracefile
=NULL
;
831 LttvHooks
*event_hook
=NULL
;
832 LttvHooksById
*event_hook_by_id
=NULL
;
835 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
837 g_assert(module_attribute
);
840 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
841 LTTV_IATTRIBUTE(module_attribute
),
843 g_assert(module_attribute
);
845 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
846 LTTV_AFTER_CHUNK_TRACESET
,
848 if(type
== LTTV_POINTER
) {
849 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
852 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
853 LTTV_AFTER_CHUNK_TRACE
,
855 if(type
== LTTV_POINTER
) {
856 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
859 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
860 LTTV_AFTER_CHUNK_TRACEFILE
,
862 if(type
== LTTV_POINTER
) {
863 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
866 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
869 if(type
== LTTV_POINTER
) {
870 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
873 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
874 LTTV_EVENT_HOOK_BY_ID
,
876 if(type
== LTTV_POINTER
) {
877 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
880 lttv_process_traceset_end(tsc
,
881 after_chunk_traceset
,
883 after_chunk_tracefile
,
890 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
893 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
894 LttvAttributeValue value
;
897 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
901 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
904 /* the value is left unset. The only presence of the attribute is necessary.
908 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
911 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
914 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
918 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
922 __EXPORT gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
925 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
926 LttvAttributeType type
;
927 LttvAttributeValue value
;
930 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
934 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
937 /* The only presence of the attribute is necessary. */
938 if(type
== LTTV_NONE
)
944 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
947 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
948 LttvAttributeValue value
;
951 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
955 value
= 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 * This internal function gets called by g_idle, taking care of the pending
1013 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
1015 LttvTracesetContext
*tsc
;
1016 LttvTracesetStats
*tss
;
1018 //LttvTracesetContextPosition *sync_position;
1019 LttvAttribute
*attribute
;
1020 LttvAttribute
*g_attribute
= lttv_global_attributes();
1021 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
1022 LttvAttributeValue value
;
1023 LttvAttributeType type
;
1029 if(lttvwindow_preempt_count
> 0) return TRUE
;
1031 attribute
= lttv_trace_attribute(trace
);
1033 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1034 LTTV_REQUESTS_QUEUE
,
1036 g_assert(type
== LTTV_POINTER
);
1037 list_out
= (GSList
**)(value
.v_pointer
);
1039 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1040 LTTV_REQUESTS_CURRENT
,
1042 g_assert(type
== LTTV_POINTER
);
1043 list_in
= (GSList
**)(value
.v_pointer
);
1045 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1048 g_assert(type
== LTTV_POINTER
);
1049 notify_out
= (GSList
**)(value
.v_pointer
);
1051 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1052 LTTV_NOTIFY_CURRENT
,
1054 g_assert(type
== LTTV_POINTER
);
1055 notify_in
= (GSList
**)(value
.v_pointer
);
1057 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1058 LTTV_COMPUTATION_TRACESET
,
1060 g_assert(type
== LTTV_POINTER
);
1061 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1063 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1064 LTTV_COMPUTATION_TRACESET_CONTEXT
,
1066 g_assert(type
== LTTV_POINTER
);
1067 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
1068 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
1069 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
1070 g_assert(LTTV_IS_TRACESET_STATS(tss
));
1072 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1073 LTTV_COMPUTATION_SYNC_POSITION
,
1075 g_assert(type
== LTTV_POINTER
);
1076 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1078 /* There is no events requests pending : we should never have been called! */
1079 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1080 /* 0.1 Lock traces */
1085 iter_trace
<lttv_traceset_number(tsc
->ts
);
1087 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
1089 if(lttvwindowtraces_lock(trace_v
) != 0)
1090 return TRUE
; /* Cannot get trace lock, try later */
1094 /* 0.2 Sync tracefiles */
1095 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1096 lttv_process_traceset_synchronize_tracefiles(tsc
);
1097 /* 1. Before processing */
1099 /* if list_in is empty */
1100 if(g_slist_length(*list_in
) == 0) {
1103 /* - Add all requests in list_out to list_in, empty list_out */
1104 GSList
*iter
= *list_out
;
1106 while(iter
!= NULL
) {
1107 gboolean remove
= FALSE
;
1108 gboolean free_data
= FALSE
;
1110 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1114 *list_in
= g_slist_append(*list_in
, bg_req
);
1119 GSList
*remove_iter
= iter
;
1121 iter
= g_slist_next(iter
);
1122 if(free_data
) g_free(remove_iter
->data
);
1123 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1124 } else { // not remove
1125 iter
= g_slist_next(iter
);
1131 GSList
*iter
= *list_in
;
1132 /* - for each request in list_in */
1133 while(iter
!= NULL
) {
1135 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1136 /* - set hooks'in_progress flag to TRUE */
1137 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1140 /* - call before request hook */
1141 /* Get before request hook */
1142 LttvAttribute
*module_attribute
;
1145 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1146 LTTV_IATTRIBUTE(g_attribute
),
1148 g_assert(module_attribute
);
1151 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1152 LTTV_IATTRIBUTE(module_attribute
),
1153 bg_req
->module_name
));
1154 g_assert(module_attribute
);
1156 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1157 LTTV_BEFORE_REQUEST
,
1159 g_assert(type
== LTTV_POINTER
);
1160 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1162 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1164 iter
= g_slist_next(iter
);
1168 /* - seek trace to start */
1170 LttTime start
= { 0, 0};
1171 lttv_process_traceset_seek_time(tsc
, start
);
1174 /* - Move all notifications from notify_out to notify_in. */
1176 GSList
*iter
= *notify_out
;
1177 g_assert(g_slist_length(*notify_in
) == 0);
1179 while(iter
!= NULL
) {
1180 gboolean remove
= FALSE
;
1181 gboolean free_data
= FALSE
;
1183 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1187 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1192 GSList
*remove_iter
= iter
;
1194 iter
= g_slist_next(iter
);
1196 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1197 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1198 } else { // not remove
1199 iter
= g_slist_next(iter
);
1204 GSList
*iter
= *list_in
;
1205 LttvHooks
*hook_adder
= lttv_hooks_new();
1206 /* - for each request in list_in */
1207 while(iter
!= NULL
) {
1209 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1210 /*- add hooks to context*/
1211 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1214 iter
= g_slist_next(iter
);
1216 lttv_hooks_call(hook_adder
,tsc
);
1217 lttv_hooks_destroy(hook_adder
);
1224 GSList
*iter
= *list_in
;
1225 /* - for each request in list_in */
1226 while(iter
!= NULL
) {
1228 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1229 /*- Call before chunk hooks for list_in*/
1230 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1232 iter
= g_slist_next(iter
);
1237 /* 2. call process traceset middle for a chunk */
1239 /*(assert list_in is not empty! : should not even be called in that case)*/
1240 LttTime end
= ltt_time_infinite
;
1241 g_assert(g_slist_length(*list_in
) != 0);
1243 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1246 /* 3. After the chunk */
1248 /* 3.1 call after_chunk hooks for list_in */
1250 GSList
*iter
= *list_in
;
1251 /* - for each request in list_in */
1252 while(iter
!= NULL
) {
1254 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1255 /* - Call after chunk hooks for list_in */
1256 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1258 iter
= g_slist_next(iter
);
1262 /* 3.2 for each notify_in */
1264 GSList
*iter
= *notify_in
;
1265 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1267 while(iter
!= NULL
) {
1268 gboolean remove
= FALSE
;
1269 gboolean free_data
= FALSE
;
1271 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1273 /* - if current time >= notify time, call notify and remove from
1275 * - if current position >= notify position, call notify and remove
1279 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1281 (notify_req
->notify_position
!= NULL
&&
1282 lttv_traceset_context_ctx_pos_compare(tsc
,
1283 notify_req
->notify_position
) >= 0)
1286 lttv_hooks_call(notify_req
->notify
, notify_req
);
1295 GSList
*remove_iter
= iter
;
1297 iter
= g_slist_next(iter
);
1299 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1300 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1301 } else { // not remove
1302 iter
= g_slist_next(iter
);
1308 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1309 /* 3.3 if end of trace reached */
1311 g_debug("Current time : %lu sec, %lu nsec",
1312 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1313 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1314 tsc
->time_span
.end_time
) > 0) {
1317 GSList
*iter
= *list_in
;
1318 LttvHooks
*hook_remover
= lttv_hooks_new();
1319 /* - for each request in list_in */
1320 while(iter
!= NULL
) {
1322 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1323 /* - remove hooks from context */
1324 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1327 iter
= g_slist_next(iter
);
1329 lttv_hooks_call(hook_remover
,tsc
);
1330 lttv_hooks_destroy(hook_remover
);
1333 /* - for each request in list_in */
1335 GSList
*iter
= *list_in
;
1337 while(iter
!= NULL
) {
1338 gboolean remove
= FALSE
;
1339 gboolean free_data
= FALSE
;
1341 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1343 /* - set hooks'in_progress flag to FALSE */
1344 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1346 /* - set hooks'ready flag to TRUE */
1347 lttvwindowtraces_set_ready(bg_req
->module_name
,
1349 /* - call after request hook */
1350 /* Get after request hook */
1351 LttvAttribute
*module_attribute
;
1354 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1355 LTTV_IATTRIBUTE(g_attribute
),
1357 g_assert(module_attribute
);
1360 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1361 LTTV_IATTRIBUTE(module_attribute
),
1362 bg_req
->module_name
));
1363 g_assert(module_attribute
);
1365 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1368 g_assert(type
== LTTV_POINTER
);
1369 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1371 struct sum_traceset_closure t_closure
;
1372 t_closure
.tss
= (LttvTracesetStats
*)tsc
;
1373 t_closure
.current_time
= ltt_time_infinite
;
1374 if(after_request
!= NULL
) lttv_hooks_call(after_request
,
1378 if(bg_req
->dialog
!= NULL
)
1379 gtk_widget_destroy(bg_req
->dialog
);
1380 GtkWidget
*parent_window
;
1381 if(g_slist_find_custom(g_main_window_list
,
1382 bg_req
->parent_window
,
1383 (GCompareFunc
)find_window_widget
))
1384 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1386 parent_window
= NULL
;
1389 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1390 GTK_DIALOG_DESTROY_WITH_PARENT
,
1391 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1392 "Background computation %s finished for trace %s",
1393 g_quark_to_string(bg_req
->module_name
),
1394 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1395 if(parent_window
!= NULL
)
1396 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1397 GTK_WINDOW(parent_window
));
1398 g_signal_connect_swapped (dialog
, "response",
1399 G_CALLBACK (gtk_widget_destroy
),
1401 gtk_widget_show(dialog
);
1403 /* - remove request */
1410 GSList
*remove_iter
= iter
;
1412 iter
= g_slist_next(iter
);
1413 if(free_data
) g_free(remove_iter
->data
);
1414 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1415 } else { // not remove
1416 iter
= g_slist_next(iter
);
1421 /* - for each notifications in notify_in */
1423 GSList
*iter
= *notify_in
;
1425 while(iter
!= NULL
) {
1426 gboolean remove
= FALSE
;
1427 gboolean free_data
= FALSE
;
1429 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1431 /* - call notify and remove from notify_in */
1432 lttv_hooks_call(notify_req
->notify
, notify_req
);
1439 GSList
*remove_iter
= iter
;
1441 iter
= g_slist_next(iter
);
1443 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1444 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1445 } else { // not remove
1446 iter
= g_slist_next(iter
);
1451 /* - reset the context */
1452 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1453 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1455 /* - if list_out is empty */
1456 if(g_slist_length(*list_out
) == 0) {
1457 /* - return FALSE (scheduler stopped) */
1458 g_debug("Background computation scheduler stopped");
1459 g_info("Background computation finished for trace %p", trace
);
1460 /* FIXME : remove status bar info, need context id and message id */
1467 /* 3.4 else, end of trace not reached */
1468 /* - return TRUE (scheduler still registered) */
1469 g_debug("Background computation left");
1474 /* 4. Unlock traces */
1476 lttv_process_traceset_get_sync_data(tsc
);
1477 //lttv_traceset_context_position_save(tsc, sync_position);
1481 iter_trace
<lttv_traceset_number(tsc
->ts
);
1483 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1485 lttvwindowtraces_unlock(trace_v
);
1494 * Register the background computation hooks for a specific module. It adds the
1495 * computation hooks to the global attrubutes, under "computation/module name".
1497 * @param module_name A GQuark : the name of the module which computes the
1500 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1501 LttvHooks
*before_chunk_traceset
,
1502 LttvHooks
*before_chunk_trace
,
1503 LttvHooks
*before_chunk_tracefile
,
1504 LttvHooks
*after_chunk_traceset
,
1505 LttvHooks
*after_chunk_trace
,
1506 LttvHooks
*after_chunk_tracefile
,
1507 LttvHooks
*before_request
,
1508 LttvHooks
*after_request
,
1509 LttvHooks
*event_hook
,
1510 LttvHooksById
*event_hook_by_id
,
1511 LttvHooks
*hook_adder
,
1512 LttvHooks
*hook_remover
)
1514 LttvAttribute
*g_attribute
= lttv_global_attributes();
1515 LttvAttribute
*attribute
;
1516 LttvAttributeValue value
;
1520 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1522 g_assert(attribute
);
1525 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1527 g_assert(attribute
);
1529 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1530 LTTV_BEFORE_CHUNK_TRACESET
,
1535 *(value
.v_pointer
) = before_chunk_traceset
;
1537 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1538 LTTV_BEFORE_CHUNK_TRACE
,
1542 *(value
.v_pointer
) = before_chunk_trace
;
1544 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1545 LTTV_BEFORE_CHUNK_TRACEFILE
,
1549 *(value
.v_pointer
) = before_chunk_tracefile
;
1551 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1552 LTTV_AFTER_CHUNK_TRACESET
,
1556 *(value
.v_pointer
) = after_chunk_traceset
;
1558 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1559 LTTV_AFTER_CHUNK_TRACE
,
1563 *(value
.v_pointer
) = after_chunk_trace
;
1565 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1566 LTTV_AFTER_CHUNK_TRACEFILE
,
1570 *(value
.v_pointer
) = after_chunk_tracefile
;
1572 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1573 LTTV_BEFORE_REQUEST
,
1577 *(value
.v_pointer
) = before_request
;
1579 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1584 *(value
.v_pointer
) = after_request
;
1586 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1591 *(value
.v_pointer
) = event_hook
;
1593 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1594 LTTV_EVENT_HOOK_BY_ID
,
1598 *(value
.v_pointer
) = event_hook_by_id
;
1600 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1605 *(value
.v_pointer
) = hook_adder
;
1607 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1612 *(value
.v_pointer
) = hook_remover
;
1618 * It removes all the requests than can be currently processed by the
1619 * background computation algorithm for all the traces (list_in and list_out).
1621 * Leaves the flag to in_progress or none.. depending if current or queue
1623 * @param module_name A GQuark : the name of the module which computes the
1626 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1631 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1632 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1633 g_assert(trace_v
!= NULL
);
1634 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1635 LttvAttributeValue value
;
1636 GSList
**queue
, **current
;
1639 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1640 LTTV_REQUESTS_QUEUE
,
1645 queue
= (GSList
**)(value
.v_pointer
);
1648 while(iter
!= NULL
) {
1649 gboolean remove
= FALSE
;
1650 gboolean free_data
= FALSE
;
1652 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1654 if(bg_req
->module_name
== module_name
) {
1662 GSList
*remove_iter
= iter
;
1664 iter
= g_slist_next(iter
);
1665 if(free_data
) g_free(remove_iter
->data
);
1666 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1667 } else { // not remove
1668 iter
= g_slist_next(iter
);
1673 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1674 LTTV_REQUESTS_CURRENT
,
1679 current
= (GSList
**)(value
.v_pointer
);
1682 while(iter
!= NULL
) {
1683 gboolean remove
= FALSE
;
1684 gboolean free_data
= FALSE
;
1686 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1688 if(bg_req
->module_name
== module_name
) {
1696 GSList
*remove_iter
= iter
;
1698 iter
= g_slist_next(iter
);
1699 if(free_data
) g_free(remove_iter
->data
);
1700 *current
= g_slist_remove_link(*current
, remove_iter
);
1701 } else { // not remove
1702 iter
= g_slist_next(iter
);
1710 * Unregister the background computation hooks for a specific module.
1712 * It also removes all the requests than can be currently processed by the
1713 * background computation algorithm for all the traces (list_in and list_out).
1715 * @param module_name A GQuark : the name of the module which computes the
1719 void lttvwindowtraces_unregister_computation_hooks
1720 (LttvAttributeName module_name
)
1722 LttvAttribute
*g_attribute
= lttv_global_attributes();
1723 LttvAttribute
*attribute
;
1724 LttvAttributeValue value
;
1728 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1730 g_assert(attribute
);
1733 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1735 g_assert(attribute
);
1737 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1738 LTTV_BEFORE_CHUNK_TRACESET
,
1743 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1744 if(before_chunk_traceset
!= NULL
)
1745 lttv_hooks_destroy(before_chunk_traceset
);
1747 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1748 LTTV_BEFORE_CHUNK_TRACE
,
1753 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1754 if(before_chunk_trace
!= NULL
)
1755 lttv_hooks_destroy(before_chunk_trace
);
1757 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1758 LTTV_BEFORE_CHUNK_TRACEFILE
,
1763 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1764 if(before_chunk_tracefile
!= NULL
)
1765 lttv_hooks_destroy(before_chunk_tracefile
);
1767 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1768 LTTV_AFTER_CHUNK_TRACESET
,
1773 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1774 if(after_chunk_traceset
!= NULL
)
1775 lttv_hooks_destroy(after_chunk_traceset
);
1777 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1778 LTTV_AFTER_CHUNK_TRACE
,
1783 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1784 if(after_chunk_trace
!= NULL
)
1785 lttv_hooks_destroy(after_chunk_trace
);
1787 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1788 LTTV_AFTER_CHUNK_TRACEFILE
,
1793 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1794 if(after_chunk_tracefile
!= NULL
)
1795 lttv_hooks_destroy(after_chunk_tracefile
);
1797 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1798 LTTV_BEFORE_REQUEST
,
1803 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1804 if(before_request
!= NULL
)
1805 lttv_hooks_destroy(before_request
);
1807 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1813 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1814 if(after_request
!= NULL
)
1815 lttv_hooks_destroy(after_request
);
1817 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1823 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1824 if(event_hook
!= NULL
)
1825 lttv_hooks_destroy(event_hook
);
1827 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1828 LTTV_EVENT_HOOK_BY_ID
,
1833 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1834 if(event_hook_by_id
!= NULL
)
1835 lttv_hooks_by_id_destroy(event_hook_by_id
);
1837 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1843 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1844 if(hook_adder
!= NULL
)
1845 lttv_hooks_destroy(hook_adder
);
1847 result
= lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1853 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1854 if(hook_remover
!= NULL
)
1855 lttv_hooks_destroy(hook_remover
);
1858 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1859 LTTV_EVENT_HOOK_BY_ID
);
1860 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1863 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1864 LTTV_AFTER_REQUEST
);
1865 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1866 LTTV_BEFORE_REQUEST
);
1868 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1869 LTTV_AFTER_CHUNK_TRACEFILE
);
1870 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1871 LTTV_AFTER_CHUNK_TRACE
);
1872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1873 LTTV_AFTER_CHUNK_TRACESET
);
1875 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1876 LTTV_BEFORE_CHUNK_TRACEFILE
);
1877 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1878 LTTV_BEFORE_CHUNK_TRACE
);
1879 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1880 LTTV_BEFORE_CHUNK_TRACESET
);
1881 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1883 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1886 /* finally, remove module name */
1888 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1890 g_assert(attribute
);
1891 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1897 * Lock a trace so no other instance can use it.
1899 * @param trace The trace to lock.
1900 * @return 0 on success, -1 if cannot get lock.
1902 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1904 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1905 LttvAttributeValue value
;
1906 LttvAttributeType type
;
1908 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1911 /* Verify the absence of the lock. */
1912 if(type
!= LTTV_NONE
) {
1913 g_critical("Cannot take trace lock");
1917 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1920 /* the value is left unset. The only presence of the attribute is necessary.
1929 * @param trace The trace to unlock.
1930 * @return 0 on success, -1 if cannot unlock (not locked ?).
1932 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1934 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1935 LttvAttributeType type
;
1936 LttvAttributeValue value
;
1938 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1941 /* Verify the presence of the lock. */
1942 if(type
== LTTV_NONE
) {
1943 g_critical("Cannot release trace lock");
1947 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1954 * Verify if a trace is locked.
1956 * @param trace The trace to verify.
1957 * @return TRUE if locked, FALSE is unlocked.
1959 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1961 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1962 LttvAttributeType type
;
1963 LttvAttributeValue value
;
1965 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1968 /* The only presence of the attribute is necessary. */
1969 if(type
== LTTV_NONE
)