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 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 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
;
109 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
112 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
114 if(type
== LTTV_POINTER
) {
115 return (LttvTrace
*)*(value
.v_pointer
);
121 /* Total number of traces */
123 guint
lttvwindowtraces_get_number()
125 LttvAttribute
*g_attribute
= lttv_global_attributes();
126 LttvAttribute
*attribute
;
127 LttvAttributeValue value
;
130 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
133 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
136 /* Add a trace to the global attributes */
138 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
140 LttvAttribute
*g_attribute
= lttv_global_attributes();
141 LttvAttribute
*attribute
;
142 LttvAttributeValue value
;
145 gchar attribute_path
[PATH_MAX
];
147 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
148 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
149 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
153 snprintf(attribute_path
, PATH_MAX
, "%llu:%llu", buf
.st_dev
, buf
.st_ino
) >= 0);
156 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
159 value
= lttv_attribute_add(attribute
,
160 g_quark_from_string(attribute_path
),
163 *(value
.v_pointer
) = (gpointer
)trace
;
165 /* create new traceset and tracesetcontext */
167 LttvTracesetStats
*tss
;
168 //LttvTracesetContextPosition *sync_position;
170 attribute
= lttv_trace_attribute(trace
);
171 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
172 LTTV_COMPUTATION_TRACESET
,
175 ts
= lttv_traceset_new();
176 *(value
.v_pointer
) = ts
;
178 lttv_traceset_add(ts
,trace
);
180 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
181 LTTV_COMPUTATION_TRACESET_CONTEXT
,
184 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
185 *(value
.v_pointer
) = tss
;
187 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
189 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
190 LTTV_COMPUTATION_SYNC_POSITION
,
194 sync_position
= lttv_traceset_context_position_new();
195 *(value
.v_pointer
) = sync_position
;
197 value
= lttv_attribute_add(attribute
,
201 value
= lttv_attribute_add(attribute
,
202 LTTV_REQUESTS_CURRENT
,
205 value
= lttv_attribute_add(attribute
,
209 value
= lttv_attribute_add(attribute
,
215 /* Remove a trace from the global attributes */
217 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
219 LttvAttribute
*g_attribute
= lttv_global_attributes();
220 LttvAttribute
*attribute
;
221 LttvAttributeValue value
;
225 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
228 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
229 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
231 g_assert(trace_v
!= NULL
);
233 /* Remove and background computation that could be in progress */
234 g_idle_remove_by_data(trace_v
);
236 if(trace_v
== trace
) {
238 LttvAttribute
*l_attribute
;
240 /* destroy traceset and tracesetcontext */
242 LttvTracesetStats
*tss
;
243 //LttvTracesetContextPosition *sync_position;
245 l_attribute
= lttv_trace_attribute(trace
);
248 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
249 LTTV_REQUESTS_QUEUE
);
251 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
252 LTTV_REQUESTS_CURRENT
);
254 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
257 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
258 LTTV_NOTIFY_CURRENT
);
260 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
261 LTTV_COMPUTATION_TRACESET
,
264 ts
= (LttvTraceset
*)*(value
.v_pointer
);
266 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
267 LTTV_COMPUTATION_SYNC_POSITION
,
270 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
271 lttv_traceset_context_position_destroy(sync_position
);
273 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
274 LTTV_COMPUTATION_SYNC_POSITION
);
277 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
278 LTTV_COMPUTATION_TRACESET_CONTEXT
,
281 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
283 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
285 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
286 LTTV_COMPUTATION_TRACESET_CONTEXT
);
287 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
288 LTTV_COMPUTATION_TRACESET
);
289 /* Destroy the traceset and the trace also */
290 lttv_traceset_destroy(ts
);
292 /* finally, remove the global attribute */
293 lttv_attribute_remove(attribute
, i
);
300 static void destroy_dialog(BackgroundRequest
*bg_req
)
302 gtk_widget_destroy(bg_req
->dialog
);
303 bg_req
->dialog
= NULL
;
308 * Function to request data from a specific trace
310 * The memory allocated for the request will be managed by the API.
312 * @param widget the current Window
313 * @param trace the trace to compute
314 * @param module_name the name of the module which registered global computation
318 void lttvwindowtraces_background_request_queue
319 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
321 BackgroundRequest
*bg_req
;
322 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
323 LttvAttribute
*g_attribute
= lttv_global_attributes();
324 LttvAttribute
*module_attribute
;
325 LttvAttributeValue value
;
326 LttvAttributeType type
;
330 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
334 slist
= (GSList
**)(value
.v_pointer
);
336 /* Verify that the calculator is loaded */
337 g_assert(module_attribute
=
338 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
342 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
343 g_quark_from_string(module_name
),
345 if(type
== LTTV_NONE
) {
346 g_critical("Missing background calculator %s", module_name
);
350 bg_req
= g_new(BackgroundRequest
,1);
351 bg_req
->module_name
= g_quark_from_string(module_name
);
352 bg_req
->trace
= trace
;
354 *slist
= g_slist_append(*slist
, bg_req
);
356 /* Priority lower than live servicing */
357 g_idle_remove_by_data(trace
);
358 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
359 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
362 /* FIXME : show message in status bar, need context and message id */
363 g_info("Background computation for %s started for trace %p", module_name
,
366 gtk_message_dialog_new(
368 GTK_DIALOG_DESTROY_WITH_PARENT
,
369 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
370 "Background computation for %s started for trace %s",
372 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
373 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
374 g_signal_connect_swapped (dialog
, "response",
375 G_CALLBACK (destroy_dialog
),
377 bg_req
->dialog
= dialog
;
378 /* the parent window might vanish : only use this pointer for a
379 * comparison with existing windows */
380 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
381 gtk_widget_show(dialog
);
385 * Remove a background request from a trace.
387 * This should ONLY be used by the modules which registered the global hooks
388 * (module_name). If this is called by the viewers, it may lead to incomplete
389 * and incoherent background processing information.
391 * Even if the module which deals with the hooks removes the background
392 * requests, it may cause a problem if the module gets loaded again in the
393 * session : the data will be partially calculated. The calculation function
394 * must deal with this case correctly.
396 * @param trace the trace to compute
397 * @param module_name the name of the module which registered global computation
401 void lttvwindowtraces_background_request_remove
402 (LttvTrace
*trace
, gchar
*module_name
)
404 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
405 LttvAttributeValue value
;
409 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
413 slist
= (GSList
**)(value
.v_pointer
);
415 for(iter
=*slist
;iter
!=NULL
;) {
416 BackgroundRequest
*bg_req
=
417 (BackgroundRequest
*)iter
->data
;
419 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
420 GSList
*rem_iter
= iter
;
421 iter
=g_slist_next(iter
);
423 *slist
= g_slist_delete_link(*slist
, rem_iter
);
425 iter
=g_slist_next(iter
);
431 * Find a background request in a trace
435 gboolean lttvwindowtraces_background_request_find
436 (LttvTrace
*trace
, gchar
*module_name
)
438 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
439 LttvAttributeValue value
;
443 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
447 slist
= (GSList
**)(value
.v_pointer
);
449 for(iter
=*slist
;iter
!=NULL
;) {
450 BackgroundRequest
*bg_req
=
451 (BackgroundRequest
*)iter
->data
;
453 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
456 iter
=g_slist_next(iter
);
463 * Register a callback to be called when requested data is passed in the next
464 * queued background processing.
466 * @param owner owner of the background notification
467 * @param trace the trace computed
468 * @param notify_time time when notification hooks must be called
469 * @param notify_position position when notification hooks must be called
470 * @param notify Hook to call when the notify position is passed
473 void lttvwindowtraces_background_notify_queue
477 const LttvTracesetContextPosition
*notify_position
,
478 const LttvHooks
*notify
)
480 BackgroundNotify
*bg_notify
;
481 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
482 LttvAttributeValue value
;
485 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
489 slist
= (GSList
**)(value
.v_pointer
);
491 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
492 LTTV_COMPUTATION_TRACESET_CONTEXT
,
495 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
497 bg_notify
= g_new(BackgroundNotify
,1);
499 bg_notify
->owner
= owner
;
500 bg_notify
->trace
= trace
;
501 bg_notify
->notify_time
= notify_time
;
502 if(notify_position
!= NULL
) {
503 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
504 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
507 bg_notify
->notify_position
= NULL
;
510 bg_notify
->notify
= lttv_hooks_new();
511 lttv_hooks_add_list(bg_notify
->notify
, notify
);
513 *slist
= g_slist_append(*slist
, bg_notify
);
517 * Register a callback to be called when requested data is passed in the current
518 * background processing.
520 * @param owner owner of the background notification
521 * @param trace the trace computed
522 * @param notify_time time when notification hooks must be called
523 * @param notify_position position when notification hooks must be called
524 * @param notify Hook to call when the notify position is passed
527 void lttvwindowtraces_background_notify_current
531 const LttvTracesetContextPosition
*notify_position
,
532 const LttvHooks
*notify
)
534 BackgroundNotify
*bg_notify
;
535 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
536 LttvAttributeValue value
;
539 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
543 slist
= (GSList
**)(value
.v_pointer
);
545 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
546 LTTV_COMPUTATION_TRACESET_CONTEXT
,
549 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
552 bg_notify
= g_new(BackgroundNotify
,1);
554 bg_notify
->owner
= owner
;
555 bg_notify
->trace
= trace
;
556 bg_notify
->notify_time
= notify_time
;
557 if(notify_position
!= NULL
) {
558 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
559 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
562 bg_notify
->notify_position
= NULL
;
564 bg_notify
->notify
= lttv_hooks_new();
565 lttv_hooks_add_list(bg_notify
->notify
, notify
);
567 *slist
= g_slist_append(*slist
, bg_notify
);
571 static void notify_request_free(BackgroundNotify
*notify_req
)
573 if(notify_req
== NULL
) return;
575 if(notify_req
->notify_position
!= NULL
)
576 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
577 if(notify_req
->notify
!= NULL
)
578 lttv_hooks_destroy(notify_req
->notify
);
583 * Removes all the notifications requests from a specific viewer.
585 * @param owner owner of the background notification
588 void lttvwindowtraces_background_notify_remove(gpointer owner
)
592 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
593 LttvAttribute
*attribute
;
594 LttvAttributeValue value
;
595 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
599 g_assert(trace_v
!= NULL
);
601 attribute
= lttv_trace_attribute(trace_v
);
603 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
607 slist
= (GSList
**)(value
.v_pointer
);
609 for(iter
=*slist
;iter
!=NULL
;) {
611 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
613 if(bg_notify
->owner
== owner
) {
614 GSList
*rem_iter
= iter
;
615 iter
=g_slist_next(iter
);
616 notify_request_free(bg_notify
);
617 *slist
= g_slist_remove_link(*slist
, rem_iter
);
619 iter
=g_slist_next(iter
);
623 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
627 slist
= (GSList
**)(value
.v_pointer
);
629 for(iter
=*slist
;iter
!=NULL
;) {
631 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
633 if(bg_notify
->owner
== owner
) {
634 GSList
*rem_iter
= iter
;
635 iter
=g_slist_next(iter
);
636 notify_request_free(bg_notify
);
637 *slist
= g_slist_remove_link(*slist
, rem_iter
);
639 iter
=g_slist_next(iter
);
646 /* Background processing helper functions */
648 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
649 LttvTracesetContext
*tsc
,
650 LttvHooks
*hook_adder
)
652 LttvAttribute
*g_attribute
= lttv_global_attributes();
653 LttvAttribute
*module_attribute
;
654 LttvAttributeType type
;
655 LttvAttributeValue value
;
658 g_assert(module_attribute
=
659 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
662 g_assert(module_attribute
=
663 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
664 LTTV_IATTRIBUTE(module_attribute
),
667 /* Call the module's hook adder */
668 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
671 if(type
== LTTV_POINTER
) {
672 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
673 if(hook_adder
!= NULL
)
674 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
678 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
679 LttvTracesetContext
*tsc
,
680 LttvHooks
*hook_remover
)
682 LttvAttribute
*g_attribute
= lttv_global_attributes();
683 LttvAttribute
*module_attribute
;
684 LttvAttributeType type
;
685 LttvAttributeValue value
;
687 g_assert(module_attribute
=
688 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
691 g_assert(module_attribute
=
692 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
693 LTTV_IATTRIBUTE(module_attribute
),
696 /* Call the module's hook remover */
697 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
700 if(type
== LTTV_POINTER
) {
701 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
702 if(hook_remover
!= NULL
)
703 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
707 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
708 LttvTracesetContext
*tsc
)
710 LttvAttribute
*g_attribute
= lttv_global_attributes();
711 LttvAttribute
*module_attribute
;
712 LttvAttributeType type
;
713 LttvAttributeValue value
;
714 LttvHooks
*before_chunk_traceset
=NULL
;
715 LttvHooks
*before_chunk_trace
=NULL
;
716 LttvHooks
*before_chunk_tracefile
=NULL
;
717 LttvHooks
*event_hook
=NULL
;
718 LttvHooksById
*event_hook_by_id
=NULL
;
719 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
722 g_assert(module_attribute
=
723 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
726 g_assert(module_attribute
=
727 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
728 LTTV_IATTRIBUTE(module_attribute
),
731 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
732 LTTV_BEFORE_CHUNK_TRACESET
,
734 if(type
== LTTV_POINTER
) {
735 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
738 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
739 LTTV_BEFORE_CHUNK_TRACE
,
741 if(type
== LTTV_POINTER
) {
742 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
745 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
746 LTTV_BEFORE_CHUNK_TRACEFILE
,
748 if(type
== LTTV_POINTER
) {
749 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
752 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
755 if(type
== LTTV_POINTER
) {
756 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
759 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
760 LTTV_EVENT_HOOK_BY_ID
,
762 if(type
== LTTV_POINTER
) {
763 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
766 lttv_process_traceset_begin(tsc
,
767 before_chunk_traceset
,
769 before_chunk_tracefile
,
776 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
777 LttvTracesetContext
*tsc
)
779 LttvAttribute
*g_attribute
= lttv_global_attributes();
780 LttvAttribute
*module_attribute
;
781 LttvAttributeType type
;
782 LttvAttributeValue value
;
783 LttvHooks
*after_chunk_traceset
=NULL
;
784 LttvHooks
*after_chunk_trace
=NULL
;
785 LttvHooks
*after_chunk_tracefile
=NULL
;
786 LttvHooks
*event_hook
=NULL
;
787 LttvHooksById
*event_hook_by_id
=NULL
;
788 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
790 g_assert(module_attribute
=
791 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
794 g_assert(module_attribute
=
795 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
796 LTTV_IATTRIBUTE(module_attribute
),
799 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
800 LTTV_AFTER_CHUNK_TRACESET
,
802 if(type
== LTTV_POINTER
) {
803 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
806 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
807 LTTV_AFTER_CHUNK_TRACE
,
809 if(type
== LTTV_POINTER
) {
810 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
813 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
814 LTTV_AFTER_CHUNK_TRACEFILE
,
816 if(type
== LTTV_POINTER
) {
817 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
820 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
823 if(type
== LTTV_POINTER
) {
824 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
827 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
828 LTTV_EVENT_HOOK_BY_ID
,
830 if(type
== LTTV_POINTER
) {
831 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
834 lttv_process_traceset_end(tsc
,
835 after_chunk_traceset
,
837 after_chunk_tracefile
,
844 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
847 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
848 LttvAttributeValue value
;
851 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
854 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
857 /* the value is left unset. The only presence of the attribute is necessary.
861 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
864 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
867 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
870 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
874 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
877 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
878 LttvAttributeType type
;
879 LttvAttributeValue value
;
882 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
885 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
888 /* The only presence of the attribute is necessary. */
889 if(type
== LTTV_NONE
)
895 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
898 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
899 LttvAttributeValue value
;
902 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
905 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
908 /* the value is left unset. The only presence of the attribute is necessary.
912 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
915 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
918 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
921 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
925 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
928 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
929 LttvAttributeType type
;
930 LttvAttributeValue value
;
933 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
936 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
939 /* The only presence of the attribute is necessary. */
940 if(type
== LTTV_NONE
)
946 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
948 if(a
->mwindow
== b
) return 0;
953 /* lttvwindowtraces_process_pending_requests
955 * This internal function gets called by g_idle, taking care of the pending
961 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
963 LttvTracesetContext
*tsc
;
964 LttvTracesetStats
*tss
;
966 //LttvTracesetContextPosition *sync_position;
967 LttvAttribute
*attribute
;
968 LttvAttribute
*g_attribute
= lttv_global_attributes();
969 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
970 LttvAttributeValue value
;
971 LttvAttributeType type
;
977 attribute
= lttv_trace_attribute(trace
);
979 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
982 g_assert(type
== LTTV_POINTER
);
983 list_out
= (GSList
**)(value
.v_pointer
);
985 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
986 LTTV_REQUESTS_CURRENT
,
988 g_assert(type
== LTTV_POINTER
);
989 list_in
= (GSList
**)(value
.v_pointer
);
991 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
994 g_assert(type
== LTTV_POINTER
);
995 notify_out
= (GSList
**)(value
.v_pointer
);
997 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1000 g_assert(type
== LTTV_POINTER
);
1001 notify_in
= (GSList
**)(value
.v_pointer
);
1003 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1004 LTTV_COMPUTATION_TRACESET
,
1006 g_assert(type
== LTTV_POINTER
);
1007 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1009 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1010 LTTV_COMPUTATION_TRACESET_CONTEXT
,
1012 g_assert(type
== LTTV_POINTER
);
1013 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
1014 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
1015 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
1016 g_assert(LTTV_IS_TRACESET_STATS(tss
));
1018 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1019 LTTV_COMPUTATION_SYNC_POSITION
,
1021 g_assert(type
== LTTV_POINTER
);
1022 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1024 /* There is no events requests pending : we should never have been called! */
1025 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1026 /* 0.1 Lock traces */
1031 iter_trace
<lttv_traceset_number(tsc
->ts
);
1033 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
1035 if(lttvwindowtraces_lock(trace_v
) != 0)
1036 return TRUE
; /* Cannot get trace lock, try later */
1040 /* 0.2 Sync tracefiles */
1041 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1042 lttv_process_traceset_synchronize_tracefiles(tsc
);
1043 /* 1. Before processing */
1045 /* if list_in is empty */
1046 if(g_slist_length(*list_in
) == 0) {
1049 /* - Add all requests in list_out to list_in, empty list_out */
1050 GSList
*iter
= *list_out
;
1052 while(iter
!= NULL
) {
1053 gboolean remove
= FALSE
;
1054 gboolean free_data
= FALSE
;
1056 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1060 *list_in
= g_slist_append(*list_in
, bg_req
);
1065 GSList
*remove_iter
= iter
;
1067 iter
= g_slist_next(iter
);
1068 if(free_data
) g_free(remove_iter
->data
);
1069 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1070 } else { // not remove
1071 iter
= g_slist_next(iter
);
1077 GSList
*iter
= *list_in
;
1078 /* - for each request in list_in */
1079 while(iter
!= NULL
) {
1081 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1082 /* - set hooks'in_progress flag to TRUE */
1083 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1086 /* - call before request hook */
1087 /* Get before request hook */
1088 LttvAttribute
*module_attribute
;
1090 g_assert(module_attribute
=
1091 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1092 LTTV_IATTRIBUTE(g_attribute
),
1093 LTTV_COMPUTATION
)));
1095 g_assert(module_attribute
=
1096 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1097 LTTV_IATTRIBUTE(module_attribute
),
1098 bg_req
->module_name
)));
1100 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1101 LTTV_BEFORE_REQUEST
,
1103 g_assert(type
== LTTV_POINTER
);
1104 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1106 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1108 iter
= g_slist_next(iter
);
1112 /* - seek trace to start */
1114 LttTime start
= { 0, 0};
1115 lttv_process_traceset_seek_time(tsc
, start
);
1118 /* - Move all notifications from notify_out to notify_in. */
1120 GSList
*iter
= *notify_out
;
1121 g_assert(g_slist_length(*notify_in
) == 0);
1123 while(iter
!= NULL
) {
1124 gboolean remove
= FALSE
;
1125 gboolean free_data
= FALSE
;
1127 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1131 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1136 GSList
*remove_iter
= iter
;
1138 iter
= g_slist_next(iter
);
1140 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1141 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1142 } else { // not remove
1143 iter
= g_slist_next(iter
);
1148 GSList
*iter
= *list_in
;
1149 LttvHooks
*hook_adder
= lttv_hooks_new();
1150 /* - for each request in list_in */
1151 while(iter
!= NULL
) {
1153 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1154 /*- add hooks to context*/
1155 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1158 iter
= g_slist_next(iter
);
1160 lttv_hooks_call(hook_adder
,tsc
);
1161 lttv_hooks_destroy(hook_adder
);
1168 GSList
*iter
= *list_in
;
1169 /* - for each request in list_in */
1170 while(iter
!= NULL
) {
1172 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1173 /*- Call before chunk hooks for list_in*/
1174 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1176 iter
= g_slist_next(iter
);
1181 /* 2. call process traceset middle for a chunk */
1183 /*(assert list_in is not empty! : should not even be called in that case)*/
1184 LttTime end
= ltt_time_infinite
;
1185 g_assert(g_slist_length(*list_in
) != 0);
1187 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1190 /* 3. After the chunk */
1192 /* 3.1 call after_chunk hooks for list_in */
1194 GSList
*iter
= *list_in
;
1195 /* - for each request in list_in */
1196 while(iter
!= NULL
) {
1198 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1199 /* - Call after chunk hooks for list_in */
1200 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1202 iter
= g_slist_next(iter
);
1206 /* 3.2 for each notify_in */
1208 GSList
*iter
= *notify_in
;
1209 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1211 while(iter
!= NULL
) {
1212 gboolean remove
= FALSE
;
1213 gboolean free_data
= FALSE
;
1215 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1217 /* - if current time >= notify time, call notify and remove from
1219 * - if current position >= notify position, call notify and remove
1223 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1225 (notify_req
->notify_position
!= NULL
&&
1226 lttv_traceset_context_ctx_pos_compare(tsc
,
1227 notify_req
->notify_position
) >= 0)
1230 lttv_hooks_call(notify_req
->notify
, notify_req
);
1239 GSList
*remove_iter
= iter
;
1241 iter
= g_slist_next(iter
);
1243 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1244 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1245 } else { // not remove
1246 iter
= g_slist_next(iter
);
1252 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1253 /* 3.3 if end of trace reached */
1255 g_debug("Current time : %lu sec, %lu nsec",
1256 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1257 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1258 tsc
->time_span
.end_time
) > 0) {
1261 GSList
*iter
= *list_in
;
1262 LttvHooks
*hook_remover
= lttv_hooks_new();
1263 /* - for each request in list_in */
1264 while(iter
!= NULL
) {
1266 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1267 /* - remove hooks from context */
1268 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1271 iter
= g_slist_next(iter
);
1273 lttv_hooks_call(hook_remover
,tsc
);
1274 lttv_hooks_destroy(hook_remover
);
1277 /* - for each request in list_in */
1279 GSList
*iter
= *list_in
;
1281 while(iter
!= NULL
) {
1282 gboolean remove
= FALSE
;
1283 gboolean free_data
= FALSE
;
1285 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1287 /* - set hooks'in_progress flag to FALSE */
1288 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1290 /* - set hooks'ready flag to TRUE */
1291 lttvwindowtraces_set_ready(bg_req
->module_name
,
1293 /* - call after request hook */
1294 /* Get after request hook */
1295 LttvAttribute
*module_attribute
;
1297 g_assert(module_attribute
=
1298 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1299 LTTV_IATTRIBUTE(g_attribute
),
1300 LTTV_COMPUTATION
)));
1302 g_assert(module_attribute
=
1303 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1304 LTTV_IATTRIBUTE(module_attribute
),
1305 bg_req
->module_name
)));
1307 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1310 g_assert(type
== LTTV_POINTER
);
1311 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1313 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1315 if(bg_req
->dialog
!= NULL
)
1316 gtk_widget_destroy(bg_req
->dialog
);
1317 GtkWidget
*parent_window
;
1318 if(g_slist_find_custom(g_main_window_list
,
1319 bg_req
->parent_window
,
1320 (GCompareFunc
)find_window_widget
))
1321 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1323 parent_window
= NULL
;
1326 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1327 GTK_DIALOG_DESTROY_WITH_PARENT
,
1328 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1329 "Background computation %s finished for trace %s",
1330 g_quark_to_string(bg_req
->module_name
),
1331 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1332 if(parent_window
!= NULL
)
1333 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1334 GTK_WINDOW(parent_window
));
1335 g_signal_connect_swapped (dialog
, "response",
1336 G_CALLBACK (gtk_widget_destroy
),
1338 gtk_widget_show(dialog
);
1340 /* - remove request */
1347 GSList
*remove_iter
= iter
;
1349 iter
= g_slist_next(iter
);
1350 if(free_data
) g_free(remove_iter
->data
);
1351 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1352 } else { // not remove
1353 iter
= g_slist_next(iter
);
1358 /* - for each notifications in notify_in */
1360 GSList
*iter
= *notify_in
;
1362 while(iter
!= NULL
) {
1363 gboolean remove
= FALSE
;
1364 gboolean free_data
= FALSE
;
1366 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1368 /* - call notify and remove from notify_in */
1369 lttv_hooks_call(notify_req
->notify
, notify_req
);
1376 GSList
*remove_iter
= iter
;
1378 iter
= g_slist_next(iter
);
1380 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1381 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1382 } else { // not remove
1383 iter
= g_slist_next(iter
);
1388 /* - reset the context */
1389 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1390 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1392 /* - if list_out is empty */
1393 if(g_slist_length(*list_out
) == 0) {
1394 /* - return FALSE (scheduler stopped) */
1395 g_debug("Background computation scheduler stopped");
1396 g_info("Background computation finished for trace %p", trace
);
1397 /* FIXME : remove status bar info, need context id and message id */
1404 /* 3.4 else, end of trace not reached */
1405 /* - return TRUE (scheduler still registered) */
1406 g_debug("Background computation left");
1411 /* 4. Unlock traces */
1413 lttv_process_traceset_get_sync_data(tsc
);
1414 //lttv_traceset_context_position_save(tsc, sync_position);
1418 iter_trace
<lttv_traceset_number(tsc
->ts
);
1420 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1422 lttvwindowtraces_unlock(trace_v
);
1431 * Register the background computation hooks for a specific module. It adds the
1432 * computation hooks to the global attrubutes, under "computation/module name".
1434 * @param module_name A GQuark : the name of the module which computes the
1437 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1438 LttvHooks
*before_chunk_traceset
,
1439 LttvHooks
*before_chunk_trace
,
1440 LttvHooks
*before_chunk_tracefile
,
1441 LttvHooks
*after_chunk_traceset
,
1442 LttvHooks
*after_chunk_trace
,
1443 LttvHooks
*after_chunk_tracefile
,
1444 LttvHooks
*before_request
,
1445 LttvHooks
*after_request
,
1446 LttvHooks
*event_hook
,
1447 LttvHooksById
*event_hook_by_id
,
1448 LttvHooks
*hook_adder
,
1449 LttvHooks
*hook_remover
)
1451 LttvAttribute
*g_attribute
= lttv_global_attributes();
1452 LttvAttribute
*attribute
;
1453 LttvAttributeValue value
;
1455 g_assert(attribute
=
1456 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1457 LTTV_COMPUTATION
)));
1459 g_assert(attribute
=
1460 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1463 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1464 LTTV_BEFORE_CHUNK_TRACESET
,
1467 *(value
.v_pointer
) = before_chunk_traceset
;
1469 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1470 LTTV_BEFORE_CHUNK_TRACE
,
1473 *(value
.v_pointer
) = before_chunk_trace
;
1475 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1476 LTTV_BEFORE_CHUNK_TRACEFILE
,
1479 *(value
.v_pointer
) = before_chunk_tracefile
;
1481 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1482 LTTV_AFTER_CHUNK_TRACESET
,
1485 *(value
.v_pointer
) = after_chunk_traceset
;
1487 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1488 LTTV_AFTER_CHUNK_TRACE
,
1491 *(value
.v_pointer
) = after_chunk_trace
;
1493 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1494 LTTV_AFTER_CHUNK_TRACEFILE
,
1497 *(value
.v_pointer
) = after_chunk_tracefile
;
1499 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1500 LTTV_BEFORE_REQUEST
,
1503 *(value
.v_pointer
) = before_request
;
1505 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1509 *(value
.v_pointer
) = after_request
;
1511 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1515 *(value
.v_pointer
) = event_hook
;
1517 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1518 LTTV_EVENT_HOOK_BY_ID
,
1521 *(value
.v_pointer
) = event_hook_by_id
;
1523 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1527 *(value
.v_pointer
) = hook_adder
;
1529 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1533 *(value
.v_pointer
) = hook_remover
;
1539 * It removes all the requests than can be currently processed by the
1540 * background computation algorithm for all the traces (list_in and list_out).
1542 * Leaves the flag to in_progress or none.. depending if current or queue
1544 * @param module_name A GQuark : the name of the module which computes the
1547 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1551 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1552 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1553 g_assert(trace_v
!= NULL
);
1555 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1556 LttvAttributeValue value
;
1557 GSList
**queue
, **current
;
1560 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1561 LTTV_REQUESTS_QUEUE
,
1564 queue
= (GSList
**)(value
.v_pointer
);
1567 while(iter
!= NULL
) {
1568 gboolean remove
= FALSE
;
1569 gboolean free_data
= FALSE
;
1571 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1573 if(bg_req
->module_name
== module_name
) {
1581 GSList
*remove_iter
= iter
;
1583 iter
= g_slist_next(iter
);
1584 if(free_data
) g_free(remove_iter
->data
);
1585 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1586 } else { // not remove
1587 iter
= g_slist_next(iter
);
1592 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1593 LTTV_REQUESTS_CURRENT
,
1596 current
= (GSList
**)(value
.v_pointer
);
1599 while(iter
!= NULL
) {
1600 gboolean remove
= FALSE
;
1601 gboolean free_data
= FALSE
;
1603 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1605 if(bg_req
->module_name
== module_name
) {
1613 GSList
*remove_iter
= iter
;
1615 iter
= g_slist_next(iter
);
1616 if(free_data
) g_free(remove_iter
->data
);
1617 *current
= g_slist_remove_link(*current
, remove_iter
);
1618 } else { // not remove
1619 iter
= g_slist_next(iter
);
1627 * Unregister the background computation hooks for a specific module.
1629 * It also removes all the requests than can be currently processed by the
1630 * background computation algorithm for all the traces (list_in and list_out).
1632 * @param module_name A GQuark : the name of the module which computes the
1636 void lttvwindowtraces_unregister_computation_hooks
1637 (LttvAttributeName module_name
)
1639 LttvAttribute
*g_attribute
= lttv_global_attributes();
1640 LttvAttribute
*attribute
;
1641 LttvAttributeValue value
;
1643 g_assert(attribute
=
1644 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1645 LTTV_COMPUTATION
)));
1646 g_assert(attribute
=
1647 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1651 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1652 LTTV_BEFORE_CHUNK_TRACESET
,
1655 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1656 if(before_chunk_traceset
!= NULL
)
1657 lttv_hooks_destroy(before_chunk_traceset
);
1659 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1660 LTTV_BEFORE_CHUNK_TRACE
,
1663 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1664 if(before_chunk_trace
!= NULL
)
1665 lttv_hooks_destroy(before_chunk_trace
);
1667 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1668 LTTV_BEFORE_CHUNK_TRACEFILE
,
1671 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1672 if(before_chunk_tracefile
!= NULL
)
1673 lttv_hooks_destroy(before_chunk_tracefile
);
1675 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1676 LTTV_AFTER_CHUNK_TRACESET
,
1679 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1680 if(after_chunk_traceset
!= NULL
)
1681 lttv_hooks_destroy(after_chunk_traceset
);
1683 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1684 LTTV_AFTER_CHUNK_TRACE
,
1687 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1688 if(after_chunk_trace
!= NULL
)
1689 lttv_hooks_destroy(after_chunk_trace
);
1691 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1692 LTTV_AFTER_CHUNK_TRACEFILE
,
1695 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1696 if(after_chunk_tracefile
!= NULL
)
1697 lttv_hooks_destroy(after_chunk_tracefile
);
1699 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1700 LTTV_BEFORE_REQUEST
,
1703 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1704 if(before_request
!= NULL
)
1705 lttv_hooks_destroy(before_request
);
1707 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1711 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1712 if(after_request
!= NULL
)
1713 lttv_hooks_destroy(after_request
);
1715 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1719 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1720 if(event_hook
!= NULL
)
1721 lttv_hooks_destroy(event_hook
);
1723 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1724 LTTV_EVENT_HOOK_BY_ID
,
1727 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1728 if(event_hook_by_id
!= NULL
)
1729 lttv_hooks_by_id_destroy(event_hook_by_id
);
1731 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1735 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1736 if(hook_adder
!= NULL
)
1737 lttv_hooks_destroy(hook_adder
);
1739 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1743 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1744 if(hook_remover
!= NULL
)
1745 lttv_hooks_destroy(hook_remover
);
1748 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1749 LTTV_EVENT_HOOK_BY_ID
);
1750 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1753 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1754 LTTV_AFTER_REQUEST
);
1755 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1756 LTTV_BEFORE_REQUEST
);
1758 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1759 LTTV_AFTER_CHUNK_TRACEFILE
);
1760 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1761 LTTV_AFTER_CHUNK_TRACE
);
1762 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1763 LTTV_AFTER_CHUNK_TRACESET
);
1765 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1766 LTTV_BEFORE_CHUNK_TRACEFILE
);
1767 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1768 LTTV_BEFORE_CHUNK_TRACE
);
1769 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1770 LTTV_BEFORE_CHUNK_TRACESET
);
1771 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1773 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1776 /* finally, remove module name */
1777 g_assert(attribute
=
1778 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1779 LTTV_COMPUTATION
)));
1780 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1786 * Lock a trace so no other instance can use it.
1788 * @param trace The trace to lock.
1789 * @return 0 on success, -1 if cannot get lock.
1791 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1793 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1794 LttvAttributeValue value
;
1795 LttvAttributeType type
;
1797 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1800 /* Verify the absence of the lock. */
1801 if(type
!= LTTV_NONE
) {
1802 g_critical("Cannot take trace lock");
1806 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1809 /* the value is left unset. The only presence of the attribute is necessary.
1818 * @param trace The trace to unlock.
1819 * @return 0 on success, -1 if cannot unlock (not locked ?).
1821 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1823 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1824 LttvAttributeType type
;
1825 LttvAttributeValue value
;
1827 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1830 /* Verify the presence of the lock. */
1831 if(type
== LTTV_NONE
) {
1832 g_critical("Cannot release trace lock");
1836 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1843 * Verify if a trace is locked.
1845 * @param trace The trace to verify.
1846 * @return TRUE if locked, FALSE is unlocked.
1848 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1850 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1851 LttvAttributeType type
;
1852 LttvAttributeValue value
;
1854 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1857 /* The only presence of the attribute is necessary. */
1858 if(type
== LTTV_NONE
)