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
43 typedef struct _BackgroundRequest
{
44 LttvAttributeName module_name
; /* Hook path in global attributes,
45 where all standard hooks under computation/.
47 LttvTrace
*trace
; /* trace concerned */
48 GtkWidget
*dialog
; /* Dialog linked with the request, may be NULL */
51 typedef struct _BackgroundNotify
{
53 LttvTrace
*trace
; /* trace */
55 LttvTracesetContextPosition
*notify_position
;
56 LttvHooks
*notify
; /* Hook to call when the notify is
57 passed, or at the end of trace */
63 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
65 /* Get a trace by its path name.
67 * @param path path of the trace on the virtual file system.
68 * @return Pointer to trace if found
69 * NULL is returned if the trace is not present
72 LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
76 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
77 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
80 g_assert(trace_v
!= NULL
);
82 trace
= lttv_trace(trace_v
);
83 g_assert(trace
!= NULL
);
84 name
= g_quark_to_string(ltt_trace_name(trace
));
86 if(strcmp(name
, path
) == 0) {
95 /* Get a trace by its number identifier */
97 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
99 LttvAttribute
*g_attribute
= lttv_global_attributes();
100 LttvAttribute
*attribute
;
101 LttvAttributeType type
;
102 LttvAttributeName name
;
103 LttvAttributeValue value
;
106 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
109 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
111 if(type
== LTTV_POINTER
) {
112 return (LttvTrace
*)*(value
.v_pointer
);
118 /* Total number of traces */
120 guint
lttvwindowtraces_get_number()
122 LttvAttribute
*g_attribute
= lttv_global_attributes();
123 LttvAttribute
*attribute
;
124 LttvAttributeValue value
;
127 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
130 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
133 /* Add a trace to the global attributes */
135 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
137 LttvAttribute
*g_attribute
= lttv_global_attributes();
138 LttvAttribute
*attribute
;
139 LttvAttributeValue value
;
142 gchar attribute_path
[PATH_MAX
];
144 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
145 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
146 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
150 snprintf(attribute_path
, PATH_MAX
, "%llu:%llu", buf
.st_dev
, buf
.st_ino
) >= 0);
153 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
156 value
= lttv_attribute_add(attribute
,
157 g_quark_from_string(attribute_path
),
160 *(value
.v_pointer
) = (gpointer
)trace
;
162 /* create new traceset and tracesetcontext */
164 LttvTracesetStats
*tss
;
165 //LttvTracesetContextPosition *sync_position;
167 attribute
= lttv_trace_attribute(trace
);
168 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
169 LTTV_COMPUTATION_TRACESET
,
172 ts
= lttv_traceset_new();
173 *(value
.v_pointer
) = ts
;
175 lttv_traceset_add(ts
,trace
);
177 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
178 LTTV_COMPUTATION_TRACESET_CONTEXT
,
181 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
182 *(value
.v_pointer
) = tss
;
184 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
186 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
187 LTTV_COMPUTATION_SYNC_POSITION
,
191 sync_position
= lttv_traceset_context_position_new();
192 *(value
.v_pointer
) = sync_position
;
194 value
= lttv_attribute_add(attribute
,
198 value
= lttv_attribute_add(attribute
,
199 LTTV_REQUESTS_CURRENT
,
202 value
= lttv_attribute_add(attribute
,
206 value
= lttv_attribute_add(attribute
,
212 /* Remove a trace from the global attributes */
214 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
216 LttvAttribute
*g_attribute
= lttv_global_attributes();
217 LttvAttribute
*attribute
;
218 LttvAttributeValue value
;
222 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
225 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
226 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
228 g_assert(trace_v
!= NULL
);
230 /* Remove and background computation that could be in progress */
231 g_idle_remove_by_data(trace_v
);
233 if(trace_v
== trace
) {
235 LttvAttribute
*l_attribute
;
237 /* destroy traceset and tracesetcontext */
239 LttvTracesetStats
*tss
;
240 //LttvTracesetContextPosition *sync_position;
242 l_attribute
= lttv_trace_attribute(trace
);
245 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
246 LTTV_REQUESTS_QUEUE
);
248 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
249 LTTV_REQUESTS_CURRENT
);
251 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
254 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
255 LTTV_NOTIFY_CURRENT
);
257 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
258 LTTV_COMPUTATION_TRACESET
,
261 ts
= (LttvTraceset
*)*(value
.v_pointer
);
263 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
264 LTTV_COMPUTATION_SYNC_POSITION
,
267 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
268 lttv_traceset_context_position_destroy(sync_position
);
270 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
271 LTTV_COMPUTATION_SYNC_POSITION
);
274 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
275 LTTV_COMPUTATION_TRACESET_CONTEXT
,
278 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
280 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
282 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
283 LTTV_COMPUTATION_TRACESET_CONTEXT
);
284 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
285 LTTV_COMPUTATION_TRACESET
);
286 /* Destroy the traceset and the trace also */
287 lttv_traceset_destroy(ts
);
289 /* finally, remove the global attribute */
290 lttv_attribute_remove(attribute
, i
);
297 static void destroy_dialog(BackgroundRequest
*bg_req
)
299 gtk_widget_destroy(bg_req
->dialog
);
300 bg_req
->dialog
= NULL
;
305 * Function to request data from a specific trace
307 * The memory allocated for the request will be managed by the API.
309 * @param trace the trace to compute
310 * @param module_name the name of the module which registered global computation
314 void lttvwindowtraces_background_request_queue
315 (LttvTrace
*trace
, gchar
*module_name
)
317 BackgroundRequest
*bg_req
;
318 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
319 LttvAttribute
*g_attribute
= lttv_global_attributes();
320 LttvAttribute
*module_attribute
;
321 LttvAttributeValue value
;
322 LttvAttributeType type
;
326 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
330 slist
= (GSList
**)(value
.v_pointer
);
332 /* Verify that the calculator is loaded */
333 g_assert(module_attribute
=
334 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
338 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
339 g_quark_from_string(module_name
),
341 if(type
== LTTV_NONE
) {
342 g_critical("Missing background calculator %s", module_name
);
346 bg_req
= g_new(BackgroundRequest
,1);
347 bg_req
->module_name
= g_quark_from_string(module_name
);
348 bg_req
->trace
= trace
;
350 *slist
= g_slist_append(*slist
, bg_req
);
352 /* Priority lower than live servicing */
353 g_idle_remove_by_data(trace
);
354 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
355 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
358 /* FIXME : show message in status bar, need context and message id */
359 g_info("Background computation for %s started for trace %p", module_name
,
362 gtk_message_dialog_new(NULL
, 0, GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
363 "Background computation for %s started for trace %s",
365 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
366 g_signal_connect_swapped (dialog
, "response",
367 G_CALLBACK (destroy_dialog
),
369 bg_req
->dialog
= dialog
;
370 gtk_widget_show(dialog
);
374 * Remove a background request from a trace.
376 * This should ONLY be used by the modules which registered the global hooks
377 * (module_name). If this is called by the viewers, it may lead to incomplete
378 * and incoherent background processing information.
380 * Even if the module which deals with the hooks removes the background
381 * requests, it may cause a problem if the module gets loaded again in the
382 * session : the data will be partially calculated. The calculation function
383 * must deal with this case correctly.
385 * @param trace the trace to compute
386 * @param module_name the name of the module which registered global computation
390 void lttvwindowtraces_background_request_remove
391 (LttvTrace
*trace
, gchar
*module_name
)
393 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
394 LttvAttributeValue value
;
398 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
402 slist
= (GSList
**)(value
.v_pointer
);
404 for(iter
=*slist
;iter
!=NULL
;) {
405 BackgroundRequest
*bg_req
=
406 (BackgroundRequest
*)iter
->data
;
408 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
409 GSList
*rem_iter
= iter
;
410 iter
=g_slist_next(iter
);
412 *slist
= g_slist_delete_link(*slist
, rem_iter
);
414 iter
=g_slist_next(iter
);
420 * Find a background request in a trace
424 gboolean lttvwindowtraces_background_request_find
425 (LttvTrace
*trace
, gchar
*module_name
)
427 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
428 LttvAttributeValue value
;
432 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
436 slist
= (GSList
**)(value
.v_pointer
);
438 for(iter
=*slist
;iter
!=NULL
;) {
439 BackgroundRequest
*bg_req
=
440 (BackgroundRequest
*)iter
->data
;
442 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
445 iter
=g_slist_next(iter
);
452 * Register a callback to be called when requested data is passed in the next
453 * queued background processing.
455 * @param owner owner of the background notification
456 * @param trace the trace computed
457 * @param notify_time time when notification hooks must be called
458 * @param notify_position position when notification hooks must be called
459 * @param notify Hook to call when the notify position is passed
462 void lttvwindowtraces_background_notify_queue
466 const LttvTracesetContextPosition
*notify_position
,
467 const LttvHooks
*notify
)
469 BackgroundNotify
*bg_notify
;
470 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
471 LttvAttributeValue value
;
474 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
478 slist
= (GSList
**)(value
.v_pointer
);
480 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
481 LTTV_COMPUTATION_TRACESET_CONTEXT
,
484 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
486 bg_notify
= g_new(BackgroundNotify
,1);
488 bg_notify
->owner
= owner
;
489 bg_notify
->trace
= trace
;
490 bg_notify
->notify_time
= notify_time
;
491 if(notify_position
!= NULL
) {
492 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
493 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
496 bg_notify
->notify_position
= NULL
;
499 bg_notify
->notify
= lttv_hooks_new();
500 lttv_hooks_add_list(bg_notify
->notify
, notify
);
502 *slist
= g_slist_append(*slist
, bg_notify
);
506 * Register a callback to be called when requested data is passed in the current
507 * background processing.
509 * @param owner owner of the background notification
510 * @param trace the trace computed
511 * @param notify_time time when notification hooks must be called
512 * @param notify_position position when notification hooks must be called
513 * @param notify Hook to call when the notify position is passed
516 void lttvwindowtraces_background_notify_current
520 const LttvTracesetContextPosition
*notify_position
,
521 const LttvHooks
*notify
)
523 BackgroundNotify
*bg_notify
;
524 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
525 LttvAttributeValue value
;
528 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
532 slist
= (GSList
**)(value
.v_pointer
);
534 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
535 LTTV_COMPUTATION_TRACESET_CONTEXT
,
538 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
541 bg_notify
= g_new(BackgroundNotify
,1);
543 bg_notify
->owner
= owner
;
544 bg_notify
->trace
= trace
;
545 bg_notify
->notify_time
= notify_time
;
546 if(notify_position
!= NULL
) {
547 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
548 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
551 bg_notify
->notify_position
= NULL
;
553 bg_notify
->notify
= lttv_hooks_new();
554 lttv_hooks_add_list(bg_notify
->notify
, notify
);
556 *slist
= g_slist_append(*slist
, bg_notify
);
560 static void notify_request_free(BackgroundNotify
*notify_req
)
562 if(notify_req
== NULL
) return;
564 if(notify_req
->notify_position
!= NULL
)
565 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
566 if(notify_req
->notify
!= NULL
)
567 lttv_hooks_destroy(notify_req
->notify
);
572 * Removes all the notifications requests from a specific viewer.
574 * @param owner owner of the background notification
577 void lttvwindowtraces_background_notify_remove(gpointer owner
)
581 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
582 LttvAttribute
*attribute
;
583 LttvAttributeValue value
;
584 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
588 g_assert(trace_v
!= NULL
);
590 attribute
= lttv_trace_attribute(trace_v
);
592 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
596 slist
= (GSList
**)(value
.v_pointer
);
598 for(iter
=*slist
;iter
!=NULL
;) {
600 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
602 if(bg_notify
->owner
== owner
) {
603 GSList
*rem_iter
= iter
;
604 iter
=g_slist_next(iter
);
605 notify_request_free(bg_notify
);
606 *slist
= g_slist_remove_link(*slist
, rem_iter
);
608 iter
=g_slist_next(iter
);
612 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
616 slist
= (GSList
**)(value
.v_pointer
);
618 for(iter
=*slist
;iter
!=NULL
;) {
620 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
622 if(bg_notify
->owner
== owner
) {
623 GSList
*rem_iter
= iter
;
624 iter
=g_slist_next(iter
);
625 notify_request_free(bg_notify
);
626 *slist
= g_slist_remove_link(*slist
, rem_iter
);
628 iter
=g_slist_next(iter
);
635 /* Background processing helper functions */
637 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
638 LttvTracesetContext
*tsc
,
639 LttvHooks
*hook_adder
)
641 LttvAttribute
*g_attribute
= lttv_global_attributes();
642 LttvAttribute
*module_attribute
;
643 LttvAttributeType type
;
644 LttvAttributeValue value
;
647 g_assert(module_attribute
=
648 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
651 g_assert(module_attribute
=
652 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
653 LTTV_IATTRIBUTE(module_attribute
),
656 /* Call the module's hook adder */
657 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
660 if(type
== LTTV_POINTER
) {
661 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
662 if(hook_adder
!= NULL
)
663 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
667 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
668 LttvTracesetContext
*tsc
,
669 LttvHooks
*hook_remover
)
671 LttvAttribute
*g_attribute
= lttv_global_attributes();
672 LttvAttribute
*module_attribute
;
673 LttvAttributeType type
;
674 LttvAttributeValue value
;
676 g_assert(module_attribute
=
677 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
680 g_assert(module_attribute
=
681 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
682 LTTV_IATTRIBUTE(module_attribute
),
685 /* Call the module's hook remover */
686 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
689 if(type
== LTTV_POINTER
) {
690 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
691 if(hook_remover
!= NULL
)
692 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
696 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
697 LttvTracesetContext
*tsc
)
699 LttvAttribute
*g_attribute
= lttv_global_attributes();
700 LttvAttribute
*module_attribute
;
701 LttvAttributeType type
;
702 LttvAttributeValue value
;
703 LttvHooks
*before_chunk_traceset
=NULL
;
704 LttvHooks
*before_chunk_trace
=NULL
;
705 LttvHooks
*before_chunk_tracefile
=NULL
;
706 LttvHooks
*event_hook
=NULL
;
707 LttvHooksById
*event_hook_by_id
=NULL
;
708 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
711 g_assert(module_attribute
=
712 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
715 g_assert(module_attribute
=
716 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
717 LTTV_IATTRIBUTE(module_attribute
),
720 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
721 LTTV_BEFORE_CHUNK_TRACESET
,
723 if(type
== LTTV_POINTER
) {
724 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
727 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
728 LTTV_BEFORE_CHUNK_TRACE
,
730 if(type
== LTTV_POINTER
) {
731 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
734 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
735 LTTV_BEFORE_CHUNK_TRACEFILE
,
737 if(type
== LTTV_POINTER
) {
738 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
741 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
744 if(type
== LTTV_POINTER
) {
745 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
748 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
749 LTTV_EVENT_HOOK_BY_ID
,
751 if(type
== LTTV_POINTER
) {
752 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
755 lttv_process_traceset_begin(tsc
,
756 before_chunk_traceset
,
758 before_chunk_tracefile
,
765 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
766 LttvTracesetContext
*tsc
)
768 LttvAttribute
*g_attribute
= lttv_global_attributes();
769 LttvAttribute
*module_attribute
;
770 LttvAttributeType type
;
771 LttvAttributeValue value
;
772 LttvHooks
*after_chunk_traceset
=NULL
;
773 LttvHooks
*after_chunk_trace
=NULL
;
774 LttvHooks
*after_chunk_tracefile
=NULL
;
775 LttvHooks
*event_hook
=NULL
;
776 LttvHooksById
*event_hook_by_id
=NULL
;
777 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
779 g_assert(module_attribute
=
780 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
783 g_assert(module_attribute
=
784 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
785 LTTV_IATTRIBUTE(module_attribute
),
788 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
789 LTTV_AFTER_CHUNK_TRACESET
,
791 if(type
== LTTV_POINTER
) {
792 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
795 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
796 LTTV_AFTER_CHUNK_TRACE
,
798 if(type
== LTTV_POINTER
) {
799 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
802 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
803 LTTV_AFTER_CHUNK_TRACEFILE
,
805 if(type
== LTTV_POINTER
) {
806 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
809 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
812 if(type
== LTTV_POINTER
) {
813 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
816 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
817 LTTV_EVENT_HOOK_BY_ID
,
819 if(type
== LTTV_POINTER
) {
820 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
823 lttv_process_traceset_end(tsc
,
824 after_chunk_traceset
,
826 after_chunk_tracefile
,
833 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
836 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
837 LttvAttributeValue value
;
840 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
843 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
846 /* the value is left unset. The only presence of the attribute is necessary.
850 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
853 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
856 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
859 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
863 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
866 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
867 LttvAttributeType type
;
868 LttvAttributeValue value
;
871 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
874 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
877 /* The only presence of the attribute is necessary. */
878 if(type
== LTTV_NONE
)
884 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
887 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
888 LttvAttributeValue value
;
891 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
894 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
897 /* the value is left unset. The only presence of the attribute is necessary.
901 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
904 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
907 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
910 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
914 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
917 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
918 LttvAttributeType type
;
919 LttvAttributeValue value
;
922 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
925 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
928 /* The only presence of the attribute is necessary. */
929 if(type
== LTTV_NONE
)
936 /* lttvwindowtraces_process_pending_requests
938 * This internal function gets called by g_idle, taking care of the pending
944 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
946 LttvTracesetContext
*tsc
;
947 LttvTracesetStats
*tss
;
949 //LttvTracesetContextPosition *sync_position;
950 LttvAttribute
*attribute
;
951 LttvAttribute
*g_attribute
= lttv_global_attributes();
952 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
953 LttvAttributeValue value
;
954 LttvAttributeType type
;
960 attribute
= lttv_trace_attribute(trace
);
962 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
965 g_assert(type
== LTTV_POINTER
);
966 list_out
= (GSList
**)(value
.v_pointer
);
968 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
969 LTTV_REQUESTS_CURRENT
,
971 g_assert(type
== LTTV_POINTER
);
972 list_in
= (GSList
**)(value
.v_pointer
);
974 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
977 g_assert(type
== LTTV_POINTER
);
978 notify_out
= (GSList
**)(value
.v_pointer
);
980 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
983 g_assert(type
== LTTV_POINTER
);
984 notify_in
= (GSList
**)(value
.v_pointer
);
986 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
987 LTTV_COMPUTATION_TRACESET
,
989 g_assert(type
== LTTV_POINTER
);
990 ts
= (LttvTraceset
*)*(value
.v_pointer
);
992 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
993 LTTV_COMPUTATION_TRACESET_CONTEXT
,
995 g_assert(type
== LTTV_POINTER
);
996 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
997 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
998 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
999 g_assert(LTTV_IS_TRACESET_STATS(tss
));
1001 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1002 LTTV_COMPUTATION_SYNC_POSITION
,
1004 g_assert(type
== LTTV_POINTER
);
1005 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1007 /* There is no events requests pending : we should never have been called! */
1008 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1009 /* 0.1 Lock traces */
1014 iter_trace
<lttv_traceset_number(tsc
->ts
);
1016 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
1018 if(lttvwindowtraces_lock(trace_v
) != 0)
1019 return TRUE
; /* Cannot get trace lock, try later */
1023 /* 0.2 Sync tracefiles */
1024 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1025 lttv_process_traceset_synchronize_tracefiles(tsc
);
1026 /* 1. Before processing */
1028 /* if list_in is empty */
1029 if(g_slist_length(*list_in
) == 0) {
1032 /* - Add all requests in list_out to list_in, empty list_out */
1033 GSList
*iter
= *list_out
;
1035 while(iter
!= NULL
) {
1036 gboolean remove
= FALSE
;
1037 gboolean free_data
= FALSE
;
1039 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1043 *list_in
= g_slist_append(*list_in
, bg_req
);
1048 GSList
*remove_iter
= iter
;
1050 iter
= g_slist_next(iter
);
1051 if(free_data
) g_free(remove_iter
->data
);
1052 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1053 } else { // not remove
1054 iter
= g_slist_next(iter
);
1060 GSList
*iter
= *list_in
;
1061 /* - for each request in list_in */
1062 while(iter
!= NULL
) {
1064 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1065 /* - set hooks'in_progress flag to TRUE */
1066 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1069 /* - call before request hook */
1070 /* Get before request hook */
1071 LttvAttribute
*module_attribute
;
1073 g_assert(module_attribute
=
1074 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1075 LTTV_IATTRIBUTE(g_attribute
),
1076 LTTV_COMPUTATION
)));
1078 g_assert(module_attribute
=
1079 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1080 LTTV_IATTRIBUTE(module_attribute
),
1081 bg_req
->module_name
)));
1083 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1084 LTTV_BEFORE_REQUEST
,
1086 g_assert(type
== LTTV_POINTER
);
1087 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1089 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1091 iter
= g_slist_next(iter
);
1095 /* - seek trace to start */
1097 LttTime start
= { 0, 0};
1098 lttv_process_traceset_seek_time(tsc
, start
);
1101 /* - Move all notifications from notify_out to notify_in. */
1103 GSList
*iter
= *notify_out
;
1104 g_assert(g_slist_length(*notify_in
) == 0);
1106 while(iter
!= NULL
) {
1107 gboolean remove
= FALSE
;
1108 gboolean free_data
= FALSE
;
1110 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1114 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1119 GSList
*remove_iter
= iter
;
1121 iter
= g_slist_next(iter
);
1123 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1124 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1125 } else { // not remove
1126 iter
= g_slist_next(iter
);
1131 GSList
*iter
= *list_in
;
1132 LttvHooks
*hook_adder
= lttv_hooks_new();
1133 /* - for each request in list_in */
1134 while(iter
!= NULL
) {
1136 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1137 /*- add hooks to context*/
1138 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1141 iter
= g_slist_next(iter
);
1143 lttv_hooks_call(hook_adder
,tsc
);
1144 lttv_hooks_destroy(hook_adder
);
1151 GSList
*iter
= *list_in
;
1152 /* - for each request in list_in */
1153 while(iter
!= NULL
) {
1155 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1156 /*- Call before chunk hooks for list_in*/
1157 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1159 iter
= g_slist_next(iter
);
1164 /* 2. call process traceset middle for a chunk */
1166 /*(assert list_in is not empty! : should not even be called in that case)*/
1167 LttTime end
= ltt_time_infinite
;
1168 g_assert(g_slist_length(*list_in
) != 0);
1170 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1173 /* 3. After the chunk */
1175 /* 3.1 call after_chunk hooks for list_in */
1177 GSList
*iter
= *list_in
;
1178 /* - for each request in list_in */
1179 while(iter
!= NULL
) {
1181 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1182 /* - Call after chunk hooks for list_in */
1183 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1185 iter
= g_slist_next(iter
);
1189 /* 3.2 for each notify_in */
1191 GSList
*iter
= *notify_in
;
1192 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1194 while(iter
!= NULL
) {
1195 gboolean remove
= FALSE
;
1196 gboolean free_data
= FALSE
;
1198 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1200 /* - if current time >= notify time, call notify and remove from
1202 * - if current position >= notify position, call notify and remove
1206 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1208 (notify_req
->notify_position
!= NULL
&&
1209 lttv_traceset_context_ctx_pos_compare(tsc
,
1210 notify_req
->notify_position
) >= 0)
1213 lttv_hooks_call(notify_req
->notify
, notify_req
);
1222 GSList
*remove_iter
= iter
;
1224 iter
= g_slist_next(iter
);
1226 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1227 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1228 } else { // not remove
1229 iter
= g_slist_next(iter
);
1235 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1236 /* 3.3 if end of trace reached */
1238 g_debug("Current time : %lu sec, %lu nsec",
1239 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1240 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1241 tsc
->time_span
.end_time
) > 0) {
1244 GSList
*iter
= *list_in
;
1245 LttvHooks
*hook_remover
= lttv_hooks_new();
1246 /* - for each request in list_in */
1247 while(iter
!= NULL
) {
1249 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1250 /* - remove hooks from context */
1251 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1254 iter
= g_slist_next(iter
);
1256 lttv_hooks_call(hook_remover
,tsc
);
1257 lttv_hooks_destroy(hook_remover
);
1260 /* - for each request in list_in */
1262 GSList
*iter
= *list_in
;
1264 while(iter
!= NULL
) {
1265 gboolean remove
= FALSE
;
1266 gboolean free_data
= FALSE
;
1268 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1270 /* - set hooks'in_progress flag to FALSE */
1271 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1273 /* - set hooks'ready flag to TRUE */
1274 lttvwindowtraces_set_ready(bg_req
->module_name
,
1276 /* - call after request hook */
1277 /* Get after request hook */
1278 LttvAttribute
*module_attribute
;
1280 g_assert(module_attribute
=
1281 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1282 LTTV_IATTRIBUTE(g_attribute
),
1283 LTTV_COMPUTATION
)));
1285 g_assert(module_attribute
=
1286 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1287 LTTV_IATTRIBUTE(module_attribute
),
1288 bg_req
->module_name
)));
1290 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1293 g_assert(type
== LTTV_POINTER
);
1294 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1296 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1298 if(bg_req
->dialog
!= NULL
)
1299 gtk_widget_destroy(bg_req
->dialog
);
1301 gtk_message_dialog_new(NULL
, 0, GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1302 "Background computation %s finished for trace %s",
1303 g_quark_to_string(bg_req
->module_name
),
1304 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1305 g_signal_connect_swapped (dialog
, "response",
1306 G_CALLBACK (gtk_widget_destroy
),
1308 gtk_widget_show(dialog
);
1310 /* - remove request */
1317 GSList
*remove_iter
= iter
;
1319 iter
= g_slist_next(iter
);
1320 if(free_data
) g_free(remove_iter
->data
);
1321 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1322 } else { // not remove
1323 iter
= g_slist_next(iter
);
1328 /* - for each notifications in notify_in */
1330 GSList
*iter
= *notify_in
;
1332 while(iter
!= NULL
) {
1333 gboolean remove
= FALSE
;
1334 gboolean free_data
= FALSE
;
1336 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1338 /* - call notify and remove from notify_in */
1339 lttv_hooks_call(notify_req
->notify
, notify_req
);
1346 GSList
*remove_iter
= iter
;
1348 iter
= g_slist_next(iter
);
1350 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1351 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1352 } else { // not remove
1353 iter
= g_slist_next(iter
);
1358 /* - reset the context */
1359 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1360 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1362 /* - if list_out is empty */
1363 if(g_slist_length(*list_out
) == 0) {
1364 /* - return FALSE (scheduler stopped) */
1365 g_debug("Background computation scheduler stopped");
1366 g_info("Background computation finished for trace %p", trace
);
1367 /* FIXME : remove status bar info, need context id and message id */
1374 /* 3.4 else, end of trace not reached */
1375 /* - return TRUE (scheduler still registered) */
1376 g_debug("Background computation left");
1381 /* 4. Unlock traces */
1383 lttv_process_traceset_get_sync_data(tsc
);
1384 //lttv_traceset_context_position_save(tsc, sync_position);
1388 iter_trace
<lttv_traceset_number(tsc
->ts
);
1390 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1392 lttvwindowtraces_unlock(trace_v
);
1401 * Register the background computation hooks for a specific module. It adds the
1402 * computation hooks to the global attrubutes, under "computation/module name".
1404 * @param module_name A GQuark : the name of the module which computes the
1407 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1408 LttvHooks
*before_chunk_traceset
,
1409 LttvHooks
*before_chunk_trace
,
1410 LttvHooks
*before_chunk_tracefile
,
1411 LttvHooks
*after_chunk_traceset
,
1412 LttvHooks
*after_chunk_trace
,
1413 LttvHooks
*after_chunk_tracefile
,
1414 LttvHooks
*before_request
,
1415 LttvHooks
*after_request
,
1416 LttvHooks
*event_hook
,
1417 LttvHooksById
*event_hook_by_id
,
1418 LttvHooks
*hook_adder
,
1419 LttvHooks
*hook_remover
)
1421 LttvAttribute
*g_attribute
= lttv_global_attributes();
1422 LttvAttribute
*attribute
;
1423 LttvAttributeValue value
;
1425 g_assert(attribute
=
1426 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1427 LTTV_COMPUTATION
)));
1429 g_assert(attribute
=
1430 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1433 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1434 LTTV_BEFORE_CHUNK_TRACESET
,
1437 *(value
.v_pointer
) = before_chunk_traceset
;
1439 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1440 LTTV_BEFORE_CHUNK_TRACE
,
1443 *(value
.v_pointer
) = before_chunk_trace
;
1445 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1446 LTTV_BEFORE_CHUNK_TRACEFILE
,
1449 *(value
.v_pointer
) = before_chunk_tracefile
;
1451 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1452 LTTV_AFTER_CHUNK_TRACESET
,
1455 *(value
.v_pointer
) = after_chunk_traceset
;
1457 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1458 LTTV_AFTER_CHUNK_TRACE
,
1461 *(value
.v_pointer
) = after_chunk_trace
;
1463 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1464 LTTV_AFTER_CHUNK_TRACEFILE
,
1467 *(value
.v_pointer
) = after_chunk_tracefile
;
1469 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1470 LTTV_BEFORE_REQUEST
,
1473 *(value
.v_pointer
) = before_request
;
1475 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1479 *(value
.v_pointer
) = after_request
;
1481 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1485 *(value
.v_pointer
) = event_hook
;
1487 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1488 LTTV_EVENT_HOOK_BY_ID
,
1491 *(value
.v_pointer
) = event_hook_by_id
;
1493 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1497 *(value
.v_pointer
) = hook_adder
;
1499 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1503 *(value
.v_pointer
) = hook_remover
;
1509 * It removes all the requests than can be currently processed by the
1510 * background computation algorithm for all the traces (list_in and list_out).
1512 * Leaves the flag to in_progress or none.. depending if current or queue
1514 * @param module_name A GQuark : the name of the module which computes the
1517 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1521 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1522 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1523 g_assert(trace_v
!= NULL
);
1525 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1526 LttvAttributeValue value
;
1527 GSList
**queue
, **current
;
1530 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1531 LTTV_REQUESTS_QUEUE
,
1534 queue
= (GSList
**)(value
.v_pointer
);
1537 while(iter
!= NULL
) {
1538 gboolean remove
= FALSE
;
1539 gboolean free_data
= FALSE
;
1541 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1543 if(bg_req
->module_name
== module_name
) {
1551 GSList
*remove_iter
= iter
;
1553 iter
= g_slist_next(iter
);
1554 if(free_data
) g_free(remove_iter
->data
);
1555 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1556 } else { // not remove
1557 iter
= g_slist_next(iter
);
1562 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1563 LTTV_REQUESTS_CURRENT
,
1566 current
= (GSList
**)(value
.v_pointer
);
1569 while(iter
!= NULL
) {
1570 gboolean remove
= FALSE
;
1571 gboolean free_data
= FALSE
;
1573 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1575 if(bg_req
->module_name
== module_name
) {
1583 GSList
*remove_iter
= iter
;
1585 iter
= g_slist_next(iter
);
1586 if(free_data
) g_free(remove_iter
->data
);
1587 *current
= g_slist_remove_link(*current
, remove_iter
);
1588 } else { // not remove
1589 iter
= g_slist_next(iter
);
1597 * Unregister the background computation hooks for a specific module.
1599 * It also removes all the requests than can be currently processed by the
1600 * background computation algorithm for all the traces (list_in and list_out).
1602 * @param module_name A GQuark : the name of the module which computes the
1606 void lttvwindowtraces_unregister_computation_hooks
1607 (LttvAttributeName module_name
)
1609 LttvAttribute
*g_attribute
= lttv_global_attributes();
1610 LttvAttribute
*attribute
;
1611 LttvAttributeValue value
;
1613 g_assert(attribute
=
1614 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1615 LTTV_COMPUTATION
)));
1616 g_assert(attribute
=
1617 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1621 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1622 LTTV_BEFORE_CHUNK_TRACESET
,
1625 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1626 if(before_chunk_traceset
!= NULL
)
1627 lttv_hooks_destroy(before_chunk_traceset
);
1629 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1630 LTTV_BEFORE_CHUNK_TRACE
,
1633 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1634 if(before_chunk_trace
!= NULL
)
1635 lttv_hooks_destroy(before_chunk_trace
);
1637 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1638 LTTV_BEFORE_CHUNK_TRACEFILE
,
1641 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1642 if(before_chunk_tracefile
!= NULL
)
1643 lttv_hooks_destroy(before_chunk_tracefile
);
1645 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1646 LTTV_AFTER_CHUNK_TRACESET
,
1649 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1650 if(after_chunk_traceset
!= NULL
)
1651 lttv_hooks_destroy(after_chunk_traceset
);
1653 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1654 LTTV_AFTER_CHUNK_TRACE
,
1657 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1658 if(after_chunk_trace
!= NULL
)
1659 lttv_hooks_destroy(after_chunk_trace
);
1661 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1662 LTTV_AFTER_CHUNK_TRACEFILE
,
1665 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1666 if(after_chunk_tracefile
!= NULL
)
1667 lttv_hooks_destroy(after_chunk_tracefile
);
1669 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1670 LTTV_BEFORE_REQUEST
,
1673 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1674 if(before_request
!= NULL
)
1675 lttv_hooks_destroy(before_request
);
1677 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1681 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1682 if(after_request
!= NULL
)
1683 lttv_hooks_destroy(after_request
);
1685 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1689 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1690 if(event_hook
!= NULL
)
1691 lttv_hooks_destroy(event_hook
);
1693 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1694 LTTV_EVENT_HOOK_BY_ID
,
1697 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1698 if(event_hook_by_id
!= NULL
)
1699 lttv_hooks_by_id_destroy(event_hook_by_id
);
1701 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1705 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1706 if(hook_adder
!= NULL
)
1707 lttv_hooks_destroy(hook_adder
);
1709 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1713 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1714 if(hook_remover
!= NULL
)
1715 lttv_hooks_destroy(hook_remover
);
1718 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1719 LTTV_EVENT_HOOK_BY_ID
);
1720 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1723 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1724 LTTV_AFTER_REQUEST
);
1725 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1726 LTTV_BEFORE_REQUEST
);
1728 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1729 LTTV_AFTER_CHUNK_TRACEFILE
);
1730 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1731 LTTV_AFTER_CHUNK_TRACE
);
1732 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1733 LTTV_AFTER_CHUNK_TRACESET
);
1735 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1736 LTTV_BEFORE_CHUNK_TRACEFILE
);
1737 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1738 LTTV_BEFORE_CHUNK_TRACE
);
1739 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1740 LTTV_BEFORE_CHUNK_TRACESET
);
1741 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1743 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1746 /* finally, remove module name */
1747 g_assert(attribute
=
1748 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1749 LTTV_COMPUTATION
)));
1750 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1756 * Lock a trace so no other instance can use it.
1758 * @param trace The trace to lock.
1759 * @return 0 on success, -1 if cannot get lock.
1761 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1763 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1764 LttvAttributeValue value
;
1765 LttvAttributeType type
;
1767 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1770 /* Verify the absence of the lock. */
1771 if(type
!= LTTV_NONE
) {
1772 g_critical("Cannot take trace lock");
1776 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1779 /* the value is left unset. The only presence of the attribute is necessary.
1788 * @param trace The trace to unlock.
1789 * @return 0 on success, -1 if cannot unlock (not locked ?).
1791 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1793 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1794 LttvAttributeType type
;
1795 LttvAttributeValue value
;
1797 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1800 /* Verify the presence of the lock. */
1801 if(type
== LTTV_NONE
) {
1802 g_critical("Cannot release trace lock");
1806 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1813 * Verify if a trace is locked.
1815 * @param trace The trace to verify.
1816 * @return TRUE if locked, FALSE is unlocked.
1818 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1820 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1821 LttvAttributeType type
;
1822 LttvAttributeValue value
;
1824 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1827 /* The only presence of the attribute is necessary. */
1828 if(type
== LTTV_NONE
)