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 */
50 typedef struct _BackgroundNotify
{
52 LttvTrace
*trace
; /* trace */
54 LttvTracesetContextPosition
*notify_position
;
55 LttvHooks
*notify
; /* Hook to call when the notify is
56 passed, or at the end of trace */
62 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
64 /* Get a trace by its path name.
66 * @param path path of the trace on the virtual file system.
67 * @return Pointer to trace if found
68 * NULL is returned if the trace is not present
71 LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
75 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
76 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
79 g_assert(trace_v
!= NULL
);
81 trace
= lttv_trace(trace_v
);
82 g_assert(trace
!= NULL
);
83 name
= g_quark_to_string(ltt_trace_name(trace
));
85 if(strcmp(name
, path
) == 0) {
94 /* Get a trace by its number identifier */
96 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
98 LttvAttribute
*g_attribute
= lttv_global_attributes();
99 LttvAttribute
*attribute
;
100 LttvAttributeType type
;
101 LttvAttributeName name
;
102 LttvAttributeValue value
;
105 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
108 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
110 if(type
== LTTV_POINTER
) {
111 return (LttvTrace
*)*(value
.v_pointer
);
117 /* Total number of traces */
119 guint
lttvwindowtraces_get_number()
121 LttvAttribute
*g_attribute
= lttv_global_attributes();
122 LttvAttribute
*attribute
;
123 LttvAttributeValue value
;
126 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
129 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
132 /* Add a trace to the global attributes */
134 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
136 LttvAttribute
*g_attribute
= lttv_global_attributes();
137 LttvAttribute
*attribute
;
138 LttvAttributeValue value
;
141 gchar attribute_path
[PATH_MAX
];
143 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
144 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
145 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
149 snprintf(attribute_path
, PATH_MAX
, "%llu:%llu", buf
.st_dev
, buf
.st_ino
) >= 0);
152 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
155 value
= lttv_attribute_add(attribute
,
156 g_quark_from_string(attribute_path
),
159 *(value
.v_pointer
) = (gpointer
)trace
;
161 /* create new traceset and tracesetcontext */
163 LttvTracesetStats
*tss
;
164 //LttvTracesetContextPosition *sync_position;
166 attribute
= lttv_trace_attribute(trace
);
167 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
168 LTTV_COMPUTATION_TRACESET
,
171 ts
= lttv_traceset_new();
172 *(value
.v_pointer
) = ts
;
174 lttv_traceset_add(ts
,trace
);
176 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
177 LTTV_COMPUTATION_TRACESET_CONTEXT
,
180 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
181 *(value
.v_pointer
) = tss
;
183 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
185 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
186 LTTV_COMPUTATION_SYNC_POSITION
,
190 sync_position
= lttv_traceset_context_position_new();
191 *(value
.v_pointer
) = sync_position
;
193 value
= lttv_attribute_add(attribute
,
197 value
= lttv_attribute_add(attribute
,
198 LTTV_REQUESTS_CURRENT
,
201 value
= lttv_attribute_add(attribute
,
205 value
= lttv_attribute_add(attribute
,
211 /* Remove a trace from the global attributes */
213 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
215 LttvAttribute
*g_attribute
= lttv_global_attributes();
216 LttvAttribute
*attribute
;
217 LttvAttributeValue value
;
221 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
224 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
225 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
227 g_assert(trace_v
!= NULL
);
229 /* Remove and background computation that could be in progress */
230 g_idle_remove_by_data(trace_v
);
232 if(trace_v
== trace
) {
234 LttvAttribute
*l_attribute
;
236 /* destroy traceset and tracesetcontext */
238 LttvTracesetStats
*tss
;
239 //LttvTracesetContextPosition *sync_position;
241 l_attribute
= lttv_trace_attribute(trace
);
244 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
245 LTTV_REQUESTS_QUEUE
);
247 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
248 LTTV_REQUESTS_CURRENT
);
250 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
253 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
254 LTTV_NOTIFY_CURRENT
);
256 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
257 LTTV_COMPUTATION_TRACESET
,
260 ts
= (LttvTraceset
*)*(value
.v_pointer
);
262 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
263 LTTV_COMPUTATION_SYNC_POSITION
,
266 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
267 lttv_traceset_context_position_destroy(sync_position
);
269 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
270 LTTV_COMPUTATION_SYNC_POSITION
);
273 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
274 LTTV_COMPUTATION_TRACESET_CONTEXT
,
277 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
279 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
281 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
282 LTTV_COMPUTATION_TRACESET_CONTEXT
);
283 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
284 LTTV_COMPUTATION_TRACESET
);
285 /* Destroy the traceset and the trace also */
286 lttv_traceset_destroy(ts
);
288 /* finally, remove the global attribute */
289 lttv_attribute_remove(attribute
, i
);
298 * Function to request data from a specific trace
300 * The memory allocated for the request will be managed by the API.
302 * @param trace the trace to compute
303 * @param module_name the name of the module which registered global computation
307 void lttvwindowtraces_background_request_queue
308 (LttvTrace
*trace
, gchar
*module_name
)
310 BackgroundRequest
*bg_req
;
311 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
312 LttvAttribute
*g_attribute
= lttv_global_attributes();
313 LttvAttribute
*module_attribute
;
314 LttvAttributeValue value
;
315 LttvAttributeType type
;
319 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
323 slist
= (GSList
**)(value
.v_pointer
);
325 /* Verify that the calculator is loaded */
326 g_assert(module_attribute
=
327 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
331 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
332 g_quark_from_string(module_name
),
334 if(type
== LTTV_NONE
) {
335 g_critical("Missing background calculator %s", module_name
);
339 bg_req
= g_new(BackgroundRequest
,1);
340 bg_req
->module_name
= g_quark_from_string(module_name
);
341 bg_req
->trace
= trace
;
343 *slist
= g_slist_append(*slist
, bg_req
);
345 /* Priority lower than live servicing */
346 g_idle_remove_by_data(trace
);
347 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
348 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
351 /* FIXME : show message in status bar, need context and message id */
352 g_info("Background computation started for trace %p", trace
);
356 * Remove a background request from a trace.
358 * This should ONLY be used by the modules which registered the global hooks
359 * (module_name). If this is called by the viewers, it may lead to incomplete
360 * and incoherent background processing information.
362 * Even if the module which deals with the hooks removes the background
363 * requests, it may cause a problem if the module gets loaded again in the
364 * session : the data will be partially calculated. The calculation function
365 * must deal with this case correctly.
367 * @param trace the trace to compute
368 * @param module_name the name of the module which registered global computation
372 void lttvwindowtraces_background_request_remove
373 (LttvTrace
*trace
, gchar
*module_name
)
375 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
376 LttvAttributeValue value
;
380 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
384 slist
= (GSList
**)(value
.v_pointer
);
386 for(iter
=*slist
;iter
!=NULL
;) {
387 BackgroundRequest
*bg_req
=
388 (BackgroundRequest
*)iter
->data
;
390 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
391 GSList
*rem_iter
= iter
;
392 iter
=g_slist_next(iter
);
394 *slist
= g_slist_delete_link(*slist
, rem_iter
);
396 iter
=g_slist_next(iter
);
403 * Register a callback to be called when requested data is passed in the next
404 * queued background processing.
406 * @param owner owner of the background notification
407 * @param trace the trace computed
408 * @param notify_time time when notification hooks must be called
409 * @param notify_position position when notification hooks must be called
410 * @param notify Hook to call when the notify position is passed
413 void lttvwindowtraces_background_notify_queue
417 const LttvTracesetContextPosition
*notify_position
,
418 const LttvHooks
*notify
)
420 BackgroundNotify
*bg_notify
;
421 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
422 LttvAttributeValue value
;
425 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
429 slist
= (GSList
**)(value
.v_pointer
);
432 bg_notify
= g_new(BackgroundNotify
,1);
434 bg_notify
->owner
= owner
;
435 bg_notify
->trace
= trace
;
436 bg_notify
->notify_time
= notify_time
;
437 if(notify_position
!= NULL
) {
438 bg_notify
->notify_position
= lttv_traceset_context_position_new();
439 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
442 bg_notify
->notify_position
= NULL
;
445 bg_notify
->notify
= lttv_hooks_new();
446 lttv_hooks_add_list(bg_notify
->notify
, notify
);
448 *slist
= g_slist_append(*slist
, bg_notify
);
452 * Register a callback to be called when requested data is passed in the current
453 * 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_current
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 bg_notify
= g_new(BackgroundNotify
,1);
482 bg_notify
->owner
= owner
;
483 bg_notify
->trace
= trace
;
484 bg_notify
->notify_time
= notify_time
;
485 if(notify_position
!= NULL
) {
486 bg_notify
->notify_position
= lttv_traceset_context_position_new();
487 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
490 bg_notify
->notify_position
= NULL
;
492 bg_notify
->notify
= lttv_hooks_new();
493 lttv_hooks_add_list(bg_notify
->notify
, notify
);
495 *slist
= g_slist_append(*slist
, bg_notify
);
499 static void notify_request_free(BackgroundNotify
*notify_req
)
501 if(notify_req
== NULL
) return;
503 if(notify_req
->notify_position
!= NULL
)
504 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
505 if(notify_req
->notify
!= NULL
)
506 lttv_hooks_destroy(notify_req
->notify
);
511 * Removes all the notifications requests from a specific viewer.
513 * @param owner owner of the background notification
516 void lttvwindowtraces_background_notify_remove(gpointer owner
)
520 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
521 LttvAttribute
*attribute
;
522 LttvAttributeValue value
;
523 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
527 g_assert(trace_v
!= NULL
);
529 attribute
= lttv_trace_attribute(trace_v
);
531 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
535 slist
= (GSList
**)(value
.v_pointer
);
537 for(iter
=*slist
;iter
!=NULL
;) {
539 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
541 if(bg_notify
->owner
== owner
) {
542 GSList
*rem_iter
= iter
;
543 iter
=g_slist_next(iter
);
544 notify_request_free(bg_notify
);
545 *slist
= g_slist_remove_link(*slist
, rem_iter
);
547 iter
=g_slist_next(iter
);
551 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
555 slist
= (GSList
**)(value
.v_pointer
);
557 for(iter
=*slist
;iter
!=NULL
;) {
559 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
561 if(bg_notify
->owner
== owner
) {
562 GSList
*rem_iter
= iter
;
563 iter
=g_slist_next(iter
);
564 notify_request_free(bg_notify
);
565 *slist
= g_slist_remove_link(*slist
, rem_iter
);
567 iter
=g_slist_next(iter
);
574 /* Background processing helper functions */
576 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
577 LttvTracesetContext
*tsc
,
578 LttvHooks
*hook_adder
)
580 LttvAttribute
*g_attribute
= lttv_global_attributes();
581 LttvAttribute
*module_attribute
;
582 LttvAttributeType type
;
583 LttvAttributeValue value
;
586 g_assert(module_attribute
=
587 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
590 g_assert(module_attribute
=
591 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
592 LTTV_IATTRIBUTE(module_attribute
),
595 /* Call the module's hook adder */
596 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
599 if(type
== LTTV_POINTER
) {
600 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
601 if(hook_adder
!= NULL
)
602 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
606 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
607 LttvTracesetContext
*tsc
,
608 LttvHooks
*hook_remover
)
610 LttvAttribute
*g_attribute
= lttv_global_attributes();
611 LttvAttribute
*module_attribute
;
612 LttvAttributeType type
;
613 LttvAttributeValue value
;
615 g_assert(module_attribute
=
616 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
619 g_assert(module_attribute
=
620 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
621 LTTV_IATTRIBUTE(module_attribute
),
624 /* Call the module's hook remover */
625 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
628 if(type
== LTTV_POINTER
) {
629 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
630 if(hook_remover
!= NULL
)
631 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
635 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
636 LttvTracesetContext
*tsc
)
638 LttvAttribute
*g_attribute
= lttv_global_attributes();
639 LttvAttribute
*module_attribute
;
640 LttvAttributeType type
;
641 LttvAttributeValue value
;
642 LttvHooks
*before_chunk_traceset
=NULL
;
643 LttvHooks
*before_chunk_trace
=NULL
;
644 LttvHooks
*before_chunk_tracefile
=NULL
;
645 LttvHooks
*event_hook
=NULL
;
646 LttvHooksById
*event_hook_by_id
=NULL
;
647 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
650 g_assert(module_attribute
=
651 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
654 g_assert(module_attribute
=
655 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
656 LTTV_IATTRIBUTE(module_attribute
),
659 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
660 LTTV_BEFORE_CHUNK_TRACESET
,
662 if(type
== LTTV_POINTER
) {
663 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
666 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
667 LTTV_BEFORE_CHUNK_TRACE
,
669 if(type
== LTTV_POINTER
) {
670 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
673 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
674 LTTV_BEFORE_CHUNK_TRACEFILE
,
676 if(type
== LTTV_POINTER
) {
677 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
680 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
683 if(type
== LTTV_POINTER
) {
684 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
687 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
688 LTTV_EVENT_HOOK_BY_ID
,
690 if(type
== LTTV_POINTER
) {
691 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
694 lttv_process_traceset_begin(tsc
,
695 before_chunk_traceset
,
697 before_chunk_tracefile
,
704 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
705 LttvTracesetContext
*tsc
)
707 LttvAttribute
*g_attribute
= lttv_global_attributes();
708 LttvAttribute
*module_attribute
;
709 LttvAttributeType type
;
710 LttvAttributeValue value
;
711 LttvHooks
*after_chunk_traceset
=NULL
;
712 LttvHooks
*after_chunk_trace
=NULL
;
713 LttvHooks
*after_chunk_tracefile
=NULL
;
714 LttvHooks
*event_hook
=NULL
;
715 LttvHooksById
*event_hook_by_id
=NULL
;
716 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
718 g_assert(module_attribute
=
719 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
722 g_assert(module_attribute
=
723 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
724 LTTV_IATTRIBUTE(module_attribute
),
727 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
728 LTTV_AFTER_CHUNK_TRACESET
,
730 if(type
== LTTV_POINTER
) {
731 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
734 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
735 LTTV_AFTER_CHUNK_TRACE
,
737 if(type
== LTTV_POINTER
) {
738 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
741 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
742 LTTV_AFTER_CHUNK_TRACEFILE
,
744 if(type
== LTTV_POINTER
) {
745 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
748 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
751 if(type
== LTTV_POINTER
) {
752 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
755 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
756 LTTV_EVENT_HOOK_BY_ID
,
758 if(type
== LTTV_POINTER
) {
759 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
762 lttv_process_traceset_end(tsc
,
763 after_chunk_traceset
,
765 after_chunk_tracefile
,
772 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
775 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
776 LttvAttributeValue value
;
779 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
782 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
785 /* the value is left unset. The only presence of the attribute is necessary.
789 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
792 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
795 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
798 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
802 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
805 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
806 LttvAttributeType type
;
807 LttvAttributeValue value
;
810 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
813 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
816 /* The only presence of the attribute is necessary. */
817 if(type
== LTTV_NONE
)
823 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
826 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
827 LttvAttributeValue value
;
830 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
833 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
836 /* the value is left unset. The only presence of the attribute is necessary.
840 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
843 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
846 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
849 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
853 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
856 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
857 LttvAttributeType type
;
858 LttvAttributeValue value
;
861 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
864 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
867 /* The only presence of the attribute is necessary. */
868 if(type
== LTTV_NONE
)
875 /* lttvwindowtraces_process_pending_requests
877 * This internal function gets called by g_idle, taking care of the pending
883 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
885 LttvTracesetContext
*tsc
;
886 LttvTracesetStats
*tss
;
888 //LttvTracesetContextPosition *sync_position;
889 LttvAttribute
*attribute
;
890 LttvAttribute
*g_attribute
= lttv_global_attributes();
891 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
892 LttvAttributeValue value
;
893 LttvAttributeType type
;
899 attribute
= lttv_trace_attribute(trace
);
901 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
904 g_assert(type
== LTTV_POINTER
);
905 list_out
= (GSList
**)(value
.v_pointer
);
907 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
908 LTTV_REQUESTS_CURRENT
,
910 g_assert(type
== LTTV_POINTER
);
911 list_in
= (GSList
**)(value
.v_pointer
);
913 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
916 g_assert(type
== LTTV_POINTER
);
917 notify_out
= (GSList
**)(value
.v_pointer
);
919 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
922 g_assert(type
== LTTV_POINTER
);
923 notify_in
= (GSList
**)(value
.v_pointer
);
925 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
926 LTTV_COMPUTATION_TRACESET
,
928 g_assert(type
== LTTV_POINTER
);
929 ts
= (LttvTraceset
*)*(value
.v_pointer
);
931 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
932 LTTV_COMPUTATION_TRACESET_CONTEXT
,
934 g_assert(type
== LTTV_POINTER
);
935 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
936 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
937 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
938 g_assert(LTTV_IS_TRACESET_STATS(tss
));
940 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
941 LTTV_COMPUTATION_SYNC_POSITION
,
943 g_assert(type
== LTTV_POINTER
);
944 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
946 /* There is no events requests pending : we should never have been called! */
947 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
948 /* 0.1 Lock traces */
953 iter_trace
<lttv_traceset_number(tsc
->ts
);
955 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
957 if(lttvwindowtraces_lock(trace_v
) != 0)
958 return TRUE
; /* Cannot get trace lock, try later */
962 /* 0.2 Sync tracefiles */
963 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
964 lttv_process_traceset_synchronize_tracefiles(tsc
);
965 /* 1. Before processing */
967 /* if list_in is empty */
968 if(g_slist_length(*list_in
) == 0) {
971 /* - Add all requests in list_out to list_in, empty list_out */
972 GSList
*iter
= *list_out
;
974 while(iter
!= NULL
) {
975 gboolean remove
= FALSE
;
976 gboolean free_data
= FALSE
;
978 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
982 *list_in
= g_slist_append(*list_in
, bg_req
);
987 GSList
*remove_iter
= iter
;
989 iter
= g_slist_next(iter
);
990 if(free_data
) g_free(remove_iter
->data
);
991 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
992 } else { // not remove
993 iter
= g_slist_next(iter
);
999 GSList
*iter
= *list_in
;
1000 /* - for each request in list_in */
1001 while(iter
!= NULL
) {
1003 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1004 /* - set hooks'in_progress flag to TRUE */
1005 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1008 /* - call before request hook */
1009 /* Get before request hook */
1010 LttvAttribute
*module_attribute
;
1012 g_assert(module_attribute
=
1013 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1014 LTTV_IATTRIBUTE(g_attribute
),
1015 LTTV_COMPUTATION
)));
1017 g_assert(module_attribute
=
1018 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1019 LTTV_IATTRIBUTE(module_attribute
),
1020 bg_req
->module_name
)));
1022 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1023 LTTV_BEFORE_REQUEST
,
1025 g_assert(type
== LTTV_POINTER
);
1026 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1028 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1030 iter
= g_slist_next(iter
);
1034 /* - seek trace to start */
1036 LttTime start
= { 0, 0};
1037 lttv_process_traceset_seek_time(tsc
, start
);
1040 /* - Move all notifications from notify_out to notify_in. */
1042 GSList
*iter
= *notify_out
;
1043 g_assert(g_slist_length(*notify_in
) == 0);
1045 while(iter
!= NULL
) {
1046 gboolean remove
= FALSE
;
1047 gboolean free_data
= FALSE
;
1049 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1053 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1058 GSList
*remove_iter
= iter
;
1060 iter
= g_slist_next(iter
);
1062 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1063 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1064 } else { // not remove
1065 iter
= g_slist_next(iter
);
1070 GSList
*iter
= *list_in
;
1071 LttvHooks
*hook_adder
= lttv_hooks_new();
1072 /* - for each request in list_in */
1073 while(iter
!= NULL
) {
1075 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1076 /*- add hooks to context*/
1077 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1080 iter
= g_slist_next(iter
);
1082 lttv_hooks_call(hook_adder
,tsc
);
1083 lttv_hooks_destroy(hook_adder
);
1090 GSList
*iter
= *list_in
;
1091 /* - for each request in list_in */
1092 while(iter
!= NULL
) {
1094 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1095 /*- Call before chunk hooks for list_in*/
1096 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1098 iter
= g_slist_next(iter
);
1103 /* 2. call process traceset middle for a chunk */
1105 /*(assert list_in is not empty! : should not even be called in that case)*/
1106 LttTime end
= ltt_time_infinite
;
1107 g_assert(g_slist_length(*list_in
) != 0);
1109 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1112 /* 3. After the chunk */
1114 /* 3.1 call after_chunk hooks for list_in */
1116 GSList
*iter
= *list_in
;
1117 /* - for each request in list_in */
1118 while(iter
!= NULL
) {
1120 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1121 /* - Call after chunk hooks for list_in */
1122 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1124 iter
= g_slist_next(iter
);
1128 /* 3.2 for each notify_in */
1130 GSList
*iter
= *notify_in
;
1131 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1133 while(iter
!= NULL
) {
1134 gboolean remove
= FALSE
;
1135 gboolean free_data
= FALSE
;
1137 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1139 /* - if current time >= notify time, call notify and remove from
1141 * - if current position >= notify position, call notify and remove
1145 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1147 (notify_req
->notify_position
!= NULL
&&
1148 lttv_traceset_context_ctx_pos_compare(tsc
,
1149 notify_req
->notify_position
) >= 0)
1152 lttv_hooks_call(notify_req
->notify
, notify_req
);
1161 GSList
*remove_iter
= iter
;
1163 iter
= g_slist_next(iter
);
1165 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1166 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1167 } else { // not remove
1168 iter
= g_slist_next(iter
);
1174 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1175 /* 3.3 if end of trace reached */
1177 g_debug("Current time : %lu sec, %lu nsec",
1178 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1179 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1180 tsc
->time_span
.end_time
) > 0) {
1183 GSList
*iter
= *list_in
;
1184 LttvHooks
*hook_remover
= lttv_hooks_new();
1185 /* - for each request in list_in */
1186 while(iter
!= NULL
) {
1188 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1189 /* - remove hooks from context */
1190 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1193 iter
= g_slist_next(iter
);
1195 lttv_hooks_call(hook_remover
,tsc
);
1196 lttv_hooks_destroy(hook_remover
);
1199 /* - for each request in list_in */
1201 GSList
*iter
= *list_in
;
1203 while(iter
!= NULL
) {
1204 gboolean remove
= FALSE
;
1205 gboolean free_data
= FALSE
;
1207 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1209 /* - set hooks'in_progress flag to FALSE */
1210 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1212 /* - set hooks'ready flag to TRUE */
1213 lttvwindowtraces_set_ready(bg_req
->module_name
,
1215 /* - call after request hook */
1216 /* Get after request hook */
1217 LttvAttribute
*module_attribute
;
1219 g_assert(module_attribute
=
1220 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1221 LTTV_IATTRIBUTE(g_attribute
),
1222 LTTV_COMPUTATION
)));
1224 g_assert(module_attribute
=
1225 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1226 LTTV_IATTRIBUTE(module_attribute
),
1227 bg_req
->module_name
)));
1229 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1232 g_assert(type
== LTTV_POINTER
);
1233 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1235 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1236 /* - remove request */
1243 GSList
*remove_iter
= iter
;
1245 iter
= g_slist_next(iter
);
1246 if(free_data
) g_free(remove_iter
->data
);
1247 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1248 } else { // not remove
1249 iter
= g_slist_next(iter
);
1254 /* - for each notifications in notify_in */
1256 GSList
*iter
= *notify_in
;
1258 while(iter
!= NULL
) {
1259 gboolean remove
= FALSE
;
1260 gboolean free_data
= FALSE
;
1262 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1264 /* - call notify and remove from notify_in */
1265 lttv_hooks_call(notify_req
->notify
, notify_req
);
1272 GSList
*remove_iter
= iter
;
1274 iter
= g_slist_next(iter
);
1276 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1277 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1278 } else { // not remove
1279 iter
= g_slist_next(iter
);
1284 /* - reset the context */
1285 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1286 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1288 /* - if list_out is empty */
1289 if(g_slist_length(*list_out
) == 0) {
1290 /* - return FALSE (scheduler stopped) */
1291 g_debug("Background computation scheduler stopped");
1292 g_info("Background computation finished for trace %p", trace
);
1293 /* FIXME : remove status bar info, need context id and message id */
1299 /* 3.4 else, end of trace not reached */
1300 /* - return TRUE (scheduler still registered) */
1301 g_debug("Background computation left");
1306 /* 4. Unlock traces */
1308 lttv_process_traceset_get_sync_data(tsc
);
1309 //lttv_traceset_context_position_save(tsc, sync_position);
1313 iter_trace
<lttv_traceset_number(tsc
->ts
);
1315 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1317 lttvwindowtraces_unlock(trace_v
);
1326 * Register the background computation hooks for a specific module. It adds the
1327 * computation hooks to the global attrubutes, under "computation/module name".
1329 * @param module_name A GQuark : the name of the module which computes the
1332 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1333 LttvHooks
*before_chunk_traceset
,
1334 LttvHooks
*before_chunk_trace
,
1335 LttvHooks
*before_chunk_tracefile
,
1336 LttvHooks
*after_chunk_traceset
,
1337 LttvHooks
*after_chunk_trace
,
1338 LttvHooks
*after_chunk_tracefile
,
1339 LttvHooks
*before_request
,
1340 LttvHooks
*after_request
,
1341 LttvHooks
*event_hook
,
1342 LttvHooksById
*event_hook_by_id
,
1343 LttvHooks
*hook_adder
,
1344 LttvHooks
*hook_remover
)
1346 LttvAttribute
*g_attribute
= lttv_global_attributes();
1347 LttvAttribute
*attribute
;
1348 LttvAttributeValue value
;
1350 g_assert(attribute
=
1351 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1352 LTTV_COMPUTATION
)));
1354 g_assert(attribute
=
1355 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1358 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1359 LTTV_BEFORE_CHUNK_TRACESET
,
1362 *(value
.v_pointer
) = before_chunk_traceset
;
1364 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1365 LTTV_BEFORE_CHUNK_TRACE
,
1368 *(value
.v_pointer
) = before_chunk_trace
;
1370 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1371 LTTV_BEFORE_CHUNK_TRACEFILE
,
1374 *(value
.v_pointer
) = before_chunk_tracefile
;
1376 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1377 LTTV_AFTER_CHUNK_TRACESET
,
1380 *(value
.v_pointer
) = after_chunk_traceset
;
1382 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1383 LTTV_AFTER_CHUNK_TRACE
,
1386 *(value
.v_pointer
) = after_chunk_trace
;
1388 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1389 LTTV_AFTER_CHUNK_TRACEFILE
,
1392 *(value
.v_pointer
) = after_chunk_tracefile
;
1394 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1395 LTTV_BEFORE_REQUEST
,
1398 *(value
.v_pointer
) = before_request
;
1400 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1404 *(value
.v_pointer
) = after_request
;
1406 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1410 *(value
.v_pointer
) = event_hook
;
1412 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1413 LTTV_EVENT_HOOK_BY_ID
,
1416 *(value
.v_pointer
) = event_hook_by_id
;
1418 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1422 *(value
.v_pointer
) = hook_adder
;
1424 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1428 *(value
.v_pointer
) = hook_remover
;
1434 * It removes all the requests than can be currently processed by the
1435 * background computation algorithm for all the traces (list_in and list_out).
1437 * Leaves the flag to in_progress or none.. depending if current or queue
1439 * @param module_name A GQuark : the name of the module which computes the
1442 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1446 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1447 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1448 g_assert(trace_v
!= NULL
);
1450 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1451 LttvAttributeValue value
;
1452 GSList
**queue
, **current
;
1455 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1456 LTTV_REQUESTS_QUEUE
,
1459 queue
= (GSList
**)(value
.v_pointer
);
1462 while(iter
!= NULL
) {
1463 gboolean remove
= FALSE
;
1464 gboolean free_data
= FALSE
;
1466 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1468 if(bg_req
->module_name
== module_name
) {
1476 GSList
*remove_iter
= iter
;
1478 iter
= g_slist_next(iter
);
1479 if(free_data
) g_free(remove_iter
->data
);
1480 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1481 } else { // not remove
1482 iter
= g_slist_next(iter
);
1487 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1488 LTTV_REQUESTS_CURRENT
,
1491 current
= (GSList
**)(value
.v_pointer
);
1494 while(iter
!= NULL
) {
1495 gboolean remove
= FALSE
;
1496 gboolean free_data
= FALSE
;
1498 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1500 if(bg_req
->module_name
== module_name
) {
1508 GSList
*remove_iter
= iter
;
1510 iter
= g_slist_next(iter
);
1511 if(free_data
) g_free(remove_iter
->data
);
1512 *current
= g_slist_remove_link(*current
, remove_iter
);
1513 } else { // not remove
1514 iter
= g_slist_next(iter
);
1522 * Unregister the background computation hooks for a specific module.
1524 * It also removes all the requests than can be currently processed by the
1525 * background computation algorithm for all the traces (list_in and list_out).
1527 * @param module_name A GQuark : the name of the module which computes the
1531 void lttvwindowtraces_unregister_computation_hooks
1532 (LttvAttributeName module_name
)
1534 LttvAttribute
*g_attribute
= lttv_global_attributes();
1535 LttvAttribute
*attribute
;
1536 LttvAttributeValue value
;
1538 g_assert(attribute
=
1539 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1540 LTTV_COMPUTATION
)));
1541 g_assert(attribute
=
1542 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1546 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1547 LTTV_BEFORE_CHUNK_TRACESET
,
1550 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1551 if(before_chunk_traceset
!= NULL
)
1552 lttv_hooks_destroy(before_chunk_traceset
);
1554 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1555 LTTV_BEFORE_CHUNK_TRACE
,
1558 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1559 if(before_chunk_trace
!= NULL
)
1560 lttv_hooks_destroy(before_chunk_trace
);
1562 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1563 LTTV_BEFORE_CHUNK_TRACEFILE
,
1566 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1567 if(before_chunk_tracefile
!= NULL
)
1568 lttv_hooks_destroy(before_chunk_tracefile
);
1570 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1571 LTTV_AFTER_CHUNK_TRACESET
,
1574 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1575 if(after_chunk_traceset
!= NULL
)
1576 lttv_hooks_destroy(after_chunk_traceset
);
1578 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1579 LTTV_AFTER_CHUNK_TRACE
,
1582 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1583 if(after_chunk_trace
!= NULL
)
1584 lttv_hooks_destroy(after_chunk_trace
);
1586 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1587 LTTV_AFTER_CHUNK_TRACEFILE
,
1590 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1591 if(after_chunk_tracefile
!= NULL
)
1592 lttv_hooks_destroy(after_chunk_tracefile
);
1594 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1595 LTTV_BEFORE_REQUEST
,
1598 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1599 if(before_request
!= NULL
)
1600 lttv_hooks_destroy(before_request
);
1602 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1606 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1607 if(after_request
!= NULL
)
1608 lttv_hooks_destroy(after_request
);
1610 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1614 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1615 if(event_hook
!= NULL
)
1616 lttv_hooks_destroy(event_hook
);
1618 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1619 LTTV_EVENT_HOOK_BY_ID
,
1622 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1623 if(event_hook_by_id
!= NULL
)
1624 lttv_hooks_by_id_destroy(event_hook_by_id
);
1626 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1630 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1631 if(hook_adder
!= NULL
)
1632 lttv_hooks_destroy(hook_adder
);
1634 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1638 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1639 if(hook_remover
!= NULL
)
1640 lttv_hooks_destroy(hook_remover
);
1643 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1644 LTTV_EVENT_HOOK_BY_ID
);
1645 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1648 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1649 LTTV_AFTER_REQUEST
);
1650 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1651 LTTV_BEFORE_REQUEST
);
1653 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1654 LTTV_AFTER_CHUNK_TRACEFILE
);
1655 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1656 LTTV_AFTER_CHUNK_TRACE
);
1657 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1658 LTTV_AFTER_CHUNK_TRACESET
);
1660 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1661 LTTV_BEFORE_CHUNK_TRACEFILE
);
1662 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1663 LTTV_BEFORE_CHUNK_TRACE
);
1664 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1665 LTTV_BEFORE_CHUNK_TRACESET
);
1666 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1668 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1671 /* finally, remove module name */
1672 g_assert(attribute
=
1673 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1674 LTTV_COMPUTATION
)));
1675 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1681 * Lock a trace so no other instance can use it.
1683 * @param trace The trace to lock.
1684 * @return 0 on success, -1 if cannot get lock.
1686 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1688 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1689 LttvAttributeValue value
;
1690 LttvAttributeType type
;
1692 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1695 /* Verify the absence of the lock. */
1696 if(type
!= LTTV_NONE
) {
1697 g_critical("Cannot take trace lock");
1701 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1704 /* the value is left unset. The only presence of the attribute is necessary.
1713 * @param trace The trace to unlock.
1714 * @return 0 on success, -1 if cannot unlock (not locked ?).
1716 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1718 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1719 LttvAttributeType type
;
1720 LttvAttributeValue value
;
1722 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1725 /* Verify the presence of the lock. */
1726 if(type
== LTTV_NONE
) {
1727 g_critical("Cannot release trace lock");
1731 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1738 * Verify if a trace is locked.
1740 * @param trace The trace to verify.
1741 * @return TRUE if locked, FALSE is unlocked.
1743 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1745 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1746 LttvAttributeType type
;
1747 LttvAttributeValue value
;
1749 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1752 /* The only presence of the attribute is necessary. */
1753 if(type
== LTTV_NONE
)