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
);
431 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
432 LTTV_COMPUTATION_TRACESET_CONTEXT
,
435 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
437 bg_notify
= g_new(BackgroundNotify
,1);
439 bg_notify
->owner
= owner
;
440 bg_notify
->trace
= trace
;
441 bg_notify
->notify_time
= notify_time
;
442 if(notify_position
!= NULL
) {
443 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
444 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
447 bg_notify
->notify_position
= NULL
;
450 bg_notify
->notify
= lttv_hooks_new();
451 lttv_hooks_add_list(bg_notify
->notify
, notify
);
453 *slist
= g_slist_append(*slist
, bg_notify
);
457 * Register a callback to be called when requested data is passed in the current
458 * background processing.
460 * @param owner owner of the background notification
461 * @param trace the trace computed
462 * @param notify_time time when notification hooks must be called
463 * @param notify_position position when notification hooks must be called
464 * @param notify Hook to call when the notify position is passed
467 void lttvwindowtraces_background_notify_current
471 const LttvTracesetContextPosition
*notify_position
,
472 const LttvHooks
*notify
)
474 BackgroundNotify
*bg_notify
;
475 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
476 LttvAttributeValue value
;
479 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
483 slist
= (GSList
**)(value
.v_pointer
);
485 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
486 LTTV_COMPUTATION_TRACESET_CONTEXT
,
489 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
492 bg_notify
= g_new(BackgroundNotify
,1);
494 bg_notify
->owner
= owner
;
495 bg_notify
->trace
= trace
;
496 bg_notify
->notify_time
= notify_time
;
497 if(notify_position
!= NULL
) {
498 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
499 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
502 bg_notify
->notify_position
= NULL
;
504 bg_notify
->notify
= lttv_hooks_new();
505 lttv_hooks_add_list(bg_notify
->notify
, notify
);
507 *slist
= g_slist_append(*slist
, bg_notify
);
511 static void notify_request_free(BackgroundNotify
*notify_req
)
513 if(notify_req
== NULL
) return;
515 if(notify_req
->notify_position
!= NULL
)
516 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
517 if(notify_req
->notify
!= NULL
)
518 lttv_hooks_destroy(notify_req
->notify
);
523 * Removes all the notifications requests from a specific viewer.
525 * @param owner owner of the background notification
528 void lttvwindowtraces_background_notify_remove(gpointer owner
)
532 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
533 LttvAttribute
*attribute
;
534 LttvAttributeValue value
;
535 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
539 g_assert(trace_v
!= NULL
);
541 attribute
= lttv_trace_attribute(trace_v
);
543 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
547 slist
= (GSList
**)(value
.v_pointer
);
549 for(iter
=*slist
;iter
!=NULL
;) {
551 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
553 if(bg_notify
->owner
== owner
) {
554 GSList
*rem_iter
= iter
;
555 iter
=g_slist_next(iter
);
556 notify_request_free(bg_notify
);
557 *slist
= g_slist_remove_link(*slist
, rem_iter
);
559 iter
=g_slist_next(iter
);
563 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
567 slist
= (GSList
**)(value
.v_pointer
);
569 for(iter
=*slist
;iter
!=NULL
;) {
571 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
573 if(bg_notify
->owner
== owner
) {
574 GSList
*rem_iter
= iter
;
575 iter
=g_slist_next(iter
);
576 notify_request_free(bg_notify
);
577 *slist
= g_slist_remove_link(*slist
, rem_iter
);
579 iter
=g_slist_next(iter
);
586 /* Background processing helper functions */
588 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
589 LttvTracesetContext
*tsc
,
590 LttvHooks
*hook_adder
)
592 LttvAttribute
*g_attribute
= lttv_global_attributes();
593 LttvAttribute
*module_attribute
;
594 LttvAttributeType type
;
595 LttvAttributeValue value
;
598 g_assert(module_attribute
=
599 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
602 g_assert(module_attribute
=
603 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
604 LTTV_IATTRIBUTE(module_attribute
),
607 /* Call the module's hook adder */
608 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
611 if(type
== LTTV_POINTER
) {
612 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
613 if(hook_adder
!= NULL
)
614 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
618 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
619 LttvTracesetContext
*tsc
,
620 LttvHooks
*hook_remover
)
622 LttvAttribute
*g_attribute
= lttv_global_attributes();
623 LttvAttribute
*module_attribute
;
624 LttvAttributeType type
;
625 LttvAttributeValue value
;
627 g_assert(module_attribute
=
628 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
631 g_assert(module_attribute
=
632 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
633 LTTV_IATTRIBUTE(module_attribute
),
636 /* Call the module's hook remover */
637 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
640 if(type
== LTTV_POINTER
) {
641 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
642 if(hook_remover
!= NULL
)
643 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
647 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
648 LttvTracesetContext
*tsc
)
650 LttvAttribute
*g_attribute
= lttv_global_attributes();
651 LttvAttribute
*module_attribute
;
652 LttvAttributeType type
;
653 LttvAttributeValue value
;
654 LttvHooks
*before_chunk_traceset
=NULL
;
655 LttvHooks
*before_chunk_trace
=NULL
;
656 LttvHooks
*before_chunk_tracefile
=NULL
;
657 LttvHooks
*event_hook
=NULL
;
658 LttvHooksById
*event_hook_by_id
=NULL
;
659 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
662 g_assert(module_attribute
=
663 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
666 g_assert(module_attribute
=
667 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
668 LTTV_IATTRIBUTE(module_attribute
),
671 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
672 LTTV_BEFORE_CHUNK_TRACESET
,
674 if(type
== LTTV_POINTER
) {
675 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
678 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
679 LTTV_BEFORE_CHUNK_TRACE
,
681 if(type
== LTTV_POINTER
) {
682 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
685 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
686 LTTV_BEFORE_CHUNK_TRACEFILE
,
688 if(type
== LTTV_POINTER
) {
689 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
692 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
695 if(type
== LTTV_POINTER
) {
696 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
699 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
700 LTTV_EVENT_HOOK_BY_ID
,
702 if(type
== LTTV_POINTER
) {
703 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
706 lttv_process_traceset_begin(tsc
,
707 before_chunk_traceset
,
709 before_chunk_tracefile
,
716 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
717 LttvTracesetContext
*tsc
)
719 LttvAttribute
*g_attribute
= lttv_global_attributes();
720 LttvAttribute
*module_attribute
;
721 LttvAttributeType type
;
722 LttvAttributeValue value
;
723 LttvHooks
*after_chunk_traceset
=NULL
;
724 LttvHooks
*after_chunk_trace
=NULL
;
725 LttvHooks
*after_chunk_tracefile
=NULL
;
726 LttvHooks
*event_hook
=NULL
;
727 LttvHooksById
*event_hook_by_id
=NULL
;
728 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
730 g_assert(module_attribute
=
731 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
734 g_assert(module_attribute
=
735 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
736 LTTV_IATTRIBUTE(module_attribute
),
739 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
740 LTTV_AFTER_CHUNK_TRACESET
,
742 if(type
== LTTV_POINTER
) {
743 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
746 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
747 LTTV_AFTER_CHUNK_TRACE
,
749 if(type
== LTTV_POINTER
) {
750 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
753 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
754 LTTV_AFTER_CHUNK_TRACEFILE
,
756 if(type
== LTTV_POINTER
) {
757 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
760 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
763 if(type
== LTTV_POINTER
) {
764 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
767 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
768 LTTV_EVENT_HOOK_BY_ID
,
770 if(type
== LTTV_POINTER
) {
771 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
774 lttv_process_traceset_end(tsc
,
775 after_chunk_traceset
,
777 after_chunk_tracefile
,
784 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
787 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
788 LttvAttributeValue value
;
791 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
794 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
797 /* the value is left unset. The only presence of the attribute is necessary.
801 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
804 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
807 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
810 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
814 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
817 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
818 LttvAttributeType type
;
819 LttvAttributeValue value
;
822 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
825 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
828 /* The only presence of the attribute is necessary. */
829 if(type
== LTTV_NONE
)
835 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
838 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
839 LttvAttributeValue value
;
842 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
845 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
848 /* the value is left unset. The only presence of the attribute is necessary.
852 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
855 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
858 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
861 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
865 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
868 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
869 LttvAttributeType type
;
870 LttvAttributeValue value
;
873 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
876 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
879 /* The only presence of the attribute is necessary. */
880 if(type
== LTTV_NONE
)
887 /* lttvwindowtraces_process_pending_requests
889 * This internal function gets called by g_idle, taking care of the pending
895 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
897 LttvTracesetContext
*tsc
;
898 LttvTracesetStats
*tss
;
900 //LttvTracesetContextPosition *sync_position;
901 LttvAttribute
*attribute
;
902 LttvAttribute
*g_attribute
= lttv_global_attributes();
903 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
904 LttvAttributeValue value
;
905 LttvAttributeType type
;
911 attribute
= lttv_trace_attribute(trace
);
913 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
916 g_assert(type
== LTTV_POINTER
);
917 list_out
= (GSList
**)(value
.v_pointer
);
919 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
920 LTTV_REQUESTS_CURRENT
,
922 g_assert(type
== LTTV_POINTER
);
923 list_in
= (GSList
**)(value
.v_pointer
);
925 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
928 g_assert(type
== LTTV_POINTER
);
929 notify_out
= (GSList
**)(value
.v_pointer
);
931 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
934 g_assert(type
== LTTV_POINTER
);
935 notify_in
= (GSList
**)(value
.v_pointer
);
937 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
938 LTTV_COMPUTATION_TRACESET
,
940 g_assert(type
== LTTV_POINTER
);
941 ts
= (LttvTraceset
*)*(value
.v_pointer
);
943 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
944 LTTV_COMPUTATION_TRACESET_CONTEXT
,
946 g_assert(type
== LTTV_POINTER
);
947 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
948 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
949 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
950 g_assert(LTTV_IS_TRACESET_STATS(tss
));
952 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
953 LTTV_COMPUTATION_SYNC_POSITION
,
955 g_assert(type
== LTTV_POINTER
);
956 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
958 /* There is no events requests pending : we should never have been called! */
959 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
960 /* 0.1 Lock traces */
965 iter_trace
<lttv_traceset_number(tsc
->ts
);
967 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
969 if(lttvwindowtraces_lock(trace_v
) != 0)
970 return TRUE
; /* Cannot get trace lock, try later */
974 /* 0.2 Sync tracefiles */
975 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
976 lttv_process_traceset_synchronize_tracefiles(tsc
);
977 /* 1. Before processing */
979 /* if list_in is empty */
980 if(g_slist_length(*list_in
) == 0) {
983 /* - Add all requests in list_out to list_in, empty list_out */
984 GSList
*iter
= *list_out
;
986 while(iter
!= NULL
) {
987 gboolean remove
= FALSE
;
988 gboolean free_data
= FALSE
;
990 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
994 *list_in
= g_slist_append(*list_in
, bg_req
);
999 GSList
*remove_iter
= iter
;
1001 iter
= g_slist_next(iter
);
1002 if(free_data
) g_free(remove_iter
->data
);
1003 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1004 } else { // not remove
1005 iter
= g_slist_next(iter
);
1011 GSList
*iter
= *list_in
;
1012 /* - for each request in list_in */
1013 while(iter
!= NULL
) {
1015 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1016 /* - set hooks'in_progress flag to TRUE */
1017 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1020 /* - call before request hook */
1021 /* Get before request hook */
1022 LttvAttribute
*module_attribute
;
1024 g_assert(module_attribute
=
1025 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1026 LTTV_IATTRIBUTE(g_attribute
),
1027 LTTV_COMPUTATION
)));
1029 g_assert(module_attribute
=
1030 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1031 LTTV_IATTRIBUTE(module_attribute
),
1032 bg_req
->module_name
)));
1034 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1035 LTTV_BEFORE_REQUEST
,
1037 g_assert(type
== LTTV_POINTER
);
1038 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1040 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1042 iter
= g_slist_next(iter
);
1046 /* - seek trace to start */
1048 LttTime start
= { 0, 0};
1049 lttv_process_traceset_seek_time(tsc
, start
);
1052 /* - Move all notifications from notify_out to notify_in. */
1054 GSList
*iter
= *notify_out
;
1055 g_assert(g_slist_length(*notify_in
) == 0);
1057 while(iter
!= NULL
) {
1058 gboolean remove
= FALSE
;
1059 gboolean free_data
= FALSE
;
1061 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1065 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1070 GSList
*remove_iter
= iter
;
1072 iter
= g_slist_next(iter
);
1074 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1075 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1076 } else { // not remove
1077 iter
= g_slist_next(iter
);
1082 GSList
*iter
= *list_in
;
1083 LttvHooks
*hook_adder
= lttv_hooks_new();
1084 /* - for each request in list_in */
1085 while(iter
!= NULL
) {
1087 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1088 /*- add hooks to context*/
1089 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1092 iter
= g_slist_next(iter
);
1094 lttv_hooks_call(hook_adder
,tsc
);
1095 lttv_hooks_destroy(hook_adder
);
1102 GSList
*iter
= *list_in
;
1103 /* - for each request in list_in */
1104 while(iter
!= NULL
) {
1106 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1107 /*- Call before chunk hooks for list_in*/
1108 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1110 iter
= g_slist_next(iter
);
1115 /* 2. call process traceset middle for a chunk */
1117 /*(assert list_in is not empty! : should not even be called in that case)*/
1118 LttTime end
= ltt_time_infinite
;
1119 g_assert(g_slist_length(*list_in
) != 0);
1121 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1124 /* 3. After the chunk */
1126 /* 3.1 call after_chunk hooks for list_in */
1128 GSList
*iter
= *list_in
;
1129 /* - for each request in list_in */
1130 while(iter
!= NULL
) {
1132 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1133 /* - Call after chunk hooks for list_in */
1134 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1136 iter
= g_slist_next(iter
);
1140 /* 3.2 for each notify_in */
1142 GSList
*iter
= *notify_in
;
1143 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1145 while(iter
!= NULL
) {
1146 gboolean remove
= FALSE
;
1147 gboolean free_data
= FALSE
;
1149 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1151 /* - if current time >= notify time, call notify and remove from
1153 * - if current position >= notify position, call notify and remove
1157 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1159 (notify_req
->notify_position
!= NULL
&&
1160 lttv_traceset_context_ctx_pos_compare(tsc
,
1161 notify_req
->notify_position
) >= 0)
1164 lttv_hooks_call(notify_req
->notify
, notify_req
);
1173 GSList
*remove_iter
= iter
;
1175 iter
= g_slist_next(iter
);
1177 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1178 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1179 } else { // not remove
1180 iter
= g_slist_next(iter
);
1186 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1187 /* 3.3 if end of trace reached */
1189 g_debug("Current time : %lu sec, %lu nsec",
1190 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1191 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1192 tsc
->time_span
.end_time
) > 0) {
1195 GSList
*iter
= *list_in
;
1196 LttvHooks
*hook_remover
= lttv_hooks_new();
1197 /* - for each request in list_in */
1198 while(iter
!= NULL
) {
1200 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1201 /* - remove hooks from context */
1202 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1205 iter
= g_slist_next(iter
);
1207 lttv_hooks_call(hook_remover
,tsc
);
1208 lttv_hooks_destroy(hook_remover
);
1211 /* - for each request in list_in */
1213 GSList
*iter
= *list_in
;
1215 while(iter
!= NULL
) {
1216 gboolean remove
= FALSE
;
1217 gboolean free_data
= FALSE
;
1219 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1221 /* - set hooks'in_progress flag to FALSE */
1222 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1224 /* - set hooks'ready flag to TRUE */
1225 lttvwindowtraces_set_ready(bg_req
->module_name
,
1227 /* - call after request hook */
1228 /* Get after request hook */
1229 LttvAttribute
*module_attribute
;
1231 g_assert(module_attribute
=
1232 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1233 LTTV_IATTRIBUTE(g_attribute
),
1234 LTTV_COMPUTATION
)));
1236 g_assert(module_attribute
=
1237 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1238 LTTV_IATTRIBUTE(module_attribute
),
1239 bg_req
->module_name
)));
1241 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1244 g_assert(type
== LTTV_POINTER
);
1245 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1247 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1248 /* - remove request */
1255 GSList
*remove_iter
= iter
;
1257 iter
= g_slist_next(iter
);
1258 if(free_data
) g_free(remove_iter
->data
);
1259 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1260 } else { // not remove
1261 iter
= g_slist_next(iter
);
1266 /* - for each notifications in notify_in */
1268 GSList
*iter
= *notify_in
;
1270 while(iter
!= NULL
) {
1271 gboolean remove
= FALSE
;
1272 gboolean free_data
= FALSE
;
1274 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1276 /* - call notify and remove from notify_in */
1277 lttv_hooks_call(notify_req
->notify
, notify_req
);
1284 GSList
*remove_iter
= iter
;
1286 iter
= g_slist_next(iter
);
1288 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1289 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1290 } else { // not remove
1291 iter
= g_slist_next(iter
);
1296 /* - reset the context */
1297 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1298 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1300 /* - if list_out is empty */
1301 if(g_slist_length(*list_out
) == 0) {
1302 /* - return FALSE (scheduler stopped) */
1303 g_debug("Background computation scheduler stopped");
1304 g_info("Background computation finished for trace %p", trace
);
1305 /* FIXME : remove status bar info, need context id and message id */
1311 /* 3.4 else, end of trace not reached */
1312 /* - return TRUE (scheduler still registered) */
1313 g_debug("Background computation left");
1318 /* 4. Unlock traces */
1320 lttv_process_traceset_get_sync_data(tsc
);
1321 //lttv_traceset_context_position_save(tsc, sync_position);
1325 iter_trace
<lttv_traceset_number(tsc
->ts
);
1327 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1329 lttvwindowtraces_unlock(trace_v
);
1338 * Register the background computation hooks for a specific module. It adds the
1339 * computation hooks to the global attrubutes, under "computation/module name".
1341 * @param module_name A GQuark : the name of the module which computes the
1344 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1345 LttvHooks
*before_chunk_traceset
,
1346 LttvHooks
*before_chunk_trace
,
1347 LttvHooks
*before_chunk_tracefile
,
1348 LttvHooks
*after_chunk_traceset
,
1349 LttvHooks
*after_chunk_trace
,
1350 LttvHooks
*after_chunk_tracefile
,
1351 LttvHooks
*before_request
,
1352 LttvHooks
*after_request
,
1353 LttvHooks
*event_hook
,
1354 LttvHooksById
*event_hook_by_id
,
1355 LttvHooks
*hook_adder
,
1356 LttvHooks
*hook_remover
)
1358 LttvAttribute
*g_attribute
= lttv_global_attributes();
1359 LttvAttribute
*attribute
;
1360 LttvAttributeValue value
;
1362 g_assert(attribute
=
1363 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1364 LTTV_COMPUTATION
)));
1366 g_assert(attribute
=
1367 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1370 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1371 LTTV_BEFORE_CHUNK_TRACESET
,
1374 *(value
.v_pointer
) = before_chunk_traceset
;
1376 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1377 LTTV_BEFORE_CHUNK_TRACE
,
1380 *(value
.v_pointer
) = before_chunk_trace
;
1382 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1383 LTTV_BEFORE_CHUNK_TRACEFILE
,
1386 *(value
.v_pointer
) = before_chunk_tracefile
;
1388 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1389 LTTV_AFTER_CHUNK_TRACESET
,
1392 *(value
.v_pointer
) = after_chunk_traceset
;
1394 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1395 LTTV_AFTER_CHUNK_TRACE
,
1398 *(value
.v_pointer
) = after_chunk_trace
;
1400 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1401 LTTV_AFTER_CHUNK_TRACEFILE
,
1404 *(value
.v_pointer
) = after_chunk_tracefile
;
1406 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1407 LTTV_BEFORE_REQUEST
,
1410 *(value
.v_pointer
) = before_request
;
1412 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1416 *(value
.v_pointer
) = after_request
;
1418 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1422 *(value
.v_pointer
) = event_hook
;
1424 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1425 LTTV_EVENT_HOOK_BY_ID
,
1428 *(value
.v_pointer
) = event_hook_by_id
;
1430 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1434 *(value
.v_pointer
) = hook_adder
;
1436 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1440 *(value
.v_pointer
) = hook_remover
;
1446 * It removes all the requests than can be currently processed by the
1447 * background computation algorithm for all the traces (list_in and list_out).
1449 * Leaves the flag to in_progress or none.. depending if current or queue
1451 * @param module_name A GQuark : the name of the module which computes the
1454 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1458 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1459 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1460 g_assert(trace_v
!= NULL
);
1462 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1463 LttvAttributeValue value
;
1464 GSList
**queue
, **current
;
1467 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1468 LTTV_REQUESTS_QUEUE
,
1471 queue
= (GSList
**)(value
.v_pointer
);
1474 while(iter
!= NULL
) {
1475 gboolean remove
= FALSE
;
1476 gboolean free_data
= FALSE
;
1478 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1480 if(bg_req
->module_name
== module_name
) {
1488 GSList
*remove_iter
= iter
;
1490 iter
= g_slist_next(iter
);
1491 if(free_data
) g_free(remove_iter
->data
);
1492 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1493 } else { // not remove
1494 iter
= g_slist_next(iter
);
1499 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1500 LTTV_REQUESTS_CURRENT
,
1503 current
= (GSList
**)(value
.v_pointer
);
1506 while(iter
!= NULL
) {
1507 gboolean remove
= FALSE
;
1508 gboolean free_data
= FALSE
;
1510 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1512 if(bg_req
->module_name
== module_name
) {
1520 GSList
*remove_iter
= iter
;
1522 iter
= g_slist_next(iter
);
1523 if(free_data
) g_free(remove_iter
->data
);
1524 *current
= g_slist_remove_link(*current
, remove_iter
);
1525 } else { // not remove
1526 iter
= g_slist_next(iter
);
1534 * Unregister the background computation hooks for a specific module.
1536 * It also removes all the requests than can be currently processed by the
1537 * background computation algorithm for all the traces (list_in and list_out).
1539 * @param module_name A GQuark : the name of the module which computes the
1543 void lttvwindowtraces_unregister_computation_hooks
1544 (LttvAttributeName module_name
)
1546 LttvAttribute
*g_attribute
= lttv_global_attributes();
1547 LttvAttribute
*attribute
;
1548 LttvAttributeValue value
;
1550 g_assert(attribute
=
1551 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1552 LTTV_COMPUTATION
)));
1553 g_assert(attribute
=
1554 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1558 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1559 LTTV_BEFORE_CHUNK_TRACESET
,
1562 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1563 if(before_chunk_traceset
!= NULL
)
1564 lttv_hooks_destroy(before_chunk_traceset
);
1566 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1567 LTTV_BEFORE_CHUNK_TRACE
,
1570 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1571 if(before_chunk_trace
!= NULL
)
1572 lttv_hooks_destroy(before_chunk_trace
);
1574 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1575 LTTV_BEFORE_CHUNK_TRACEFILE
,
1578 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1579 if(before_chunk_tracefile
!= NULL
)
1580 lttv_hooks_destroy(before_chunk_tracefile
);
1582 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1583 LTTV_AFTER_CHUNK_TRACESET
,
1586 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1587 if(after_chunk_traceset
!= NULL
)
1588 lttv_hooks_destroy(after_chunk_traceset
);
1590 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1591 LTTV_AFTER_CHUNK_TRACE
,
1594 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1595 if(after_chunk_trace
!= NULL
)
1596 lttv_hooks_destroy(after_chunk_trace
);
1598 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1599 LTTV_AFTER_CHUNK_TRACEFILE
,
1602 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1603 if(after_chunk_tracefile
!= NULL
)
1604 lttv_hooks_destroy(after_chunk_tracefile
);
1606 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1607 LTTV_BEFORE_REQUEST
,
1610 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1611 if(before_request
!= NULL
)
1612 lttv_hooks_destroy(before_request
);
1614 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1618 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1619 if(after_request
!= NULL
)
1620 lttv_hooks_destroy(after_request
);
1622 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1626 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1627 if(event_hook
!= NULL
)
1628 lttv_hooks_destroy(event_hook
);
1630 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1631 LTTV_EVENT_HOOK_BY_ID
,
1634 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1635 if(event_hook_by_id
!= NULL
)
1636 lttv_hooks_by_id_destroy(event_hook_by_id
);
1638 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1642 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1643 if(hook_adder
!= NULL
)
1644 lttv_hooks_destroy(hook_adder
);
1646 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1650 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1651 if(hook_remover
!= NULL
)
1652 lttv_hooks_destroy(hook_remover
);
1655 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1656 LTTV_EVENT_HOOK_BY_ID
);
1657 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1660 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1661 LTTV_AFTER_REQUEST
);
1662 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1663 LTTV_BEFORE_REQUEST
);
1665 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1666 LTTV_AFTER_CHUNK_TRACEFILE
);
1667 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1668 LTTV_AFTER_CHUNK_TRACE
);
1669 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1670 LTTV_AFTER_CHUNK_TRACESET
);
1672 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1673 LTTV_BEFORE_CHUNK_TRACEFILE
);
1674 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1675 LTTV_BEFORE_CHUNK_TRACE
);
1676 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1677 LTTV_BEFORE_CHUNK_TRACESET
);
1678 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1680 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1683 /* finally, remove module name */
1684 g_assert(attribute
=
1685 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1686 LTTV_COMPUTATION
)));
1687 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1693 * Lock a trace so no other instance can use it.
1695 * @param trace The trace to lock.
1696 * @return 0 on success, -1 if cannot get lock.
1698 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1700 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1701 LttvAttributeValue value
;
1702 LttvAttributeType type
;
1704 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1707 /* Verify the absence of the lock. */
1708 if(type
!= LTTV_NONE
) {
1709 g_critical("Cannot take trace lock");
1713 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1716 /* the value is left unset. The only presence of the attribute is necessary.
1725 * @param trace The trace to unlock.
1726 * @return 0 on success, -1 if cannot unlock (not locked ?).
1728 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1730 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1731 LttvAttributeType type
;
1732 LttvAttributeValue value
;
1734 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1737 /* Verify the presence of the lock. */
1738 if(type
== LTTV_NONE
) {
1739 g_critical("Cannot release trace lock");
1743 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1750 * Verify if a trace is locked.
1752 * @param trace The trace to verify.
1753 * @return TRUE if locked, FALSE is unlocked.
1755 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1757 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1758 LttvAttributeType type
;
1759 LttvAttributeValue value
;
1761 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1764 /* The only presence of the attribute is necessary. */
1765 if(type
== LTTV_NONE
)