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 */
23 #include <sys/types.h>
28 #include <ltt/trace.h>
30 #include <lttv/lttv.h>
31 #include <lttv/traceset.h>
32 #include <lttv/attribute.h>
33 #include <lttv/tracecontext.h>
34 #include <lttvwindow/lttvwindowtraces.h>
35 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
38 typedef struct _BackgroundRequest
{
39 LttvAttributeName module_name
; /* Hook path in global attributes,
40 where all standard hooks under computation/.
42 LttvTrace
*trace
; /* trace concerned */
45 typedef struct _BackgroundNotify
{
47 LttvTrace
*trace
; /* trace */
49 LttvTracesetContextPosition
*notify_position
;
50 LttvHooks
*notify
; /* Hook to call when the notify is
51 passed, or at the end of trace */
57 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
59 /* Get a trace by its path name.
61 * @param path path of the trace on the virtual file system.
62 * @return Pointer to trace if found
63 * NULL is returned if the trace is not present
66 LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
68 LttvAttribute
*attribute
= lttv_global_attributes();
71 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
72 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
75 g_assert(trace_v
!= NULL
);
77 trace
= lttv_trace(trace_v
);
78 g_assert(trace
!= NULL
);
79 name
= ltt_trace_name(trace
);
81 if(strcmp(name
, path
) == 0) {
90 /* Get a trace by its number identifier */
92 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
94 LttvAttribute
*g_attribute
= lttv_global_attributes();
95 LttvAttribute
*attribute
;
96 LttvAttributeType type
;
97 LttvAttributeName name
;
98 LttvAttributeValue value
;
101 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
104 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
106 if(type
== LTTV_POINTER
) {
107 return (LttvTrace
*)*(value
.v_pointer
);
113 /* Total number of traces */
115 guint
lttvwindowtraces_get_number()
117 LttvAttribute
*g_attribute
= lttv_global_attributes();
118 LttvAttribute
*attribute
;
119 LttvAttributeValue value
;
122 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
125 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
128 /* Add a trace to the global attributes */
130 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
132 LttvAttribute
*g_attribute
= lttv_global_attributes();
133 LttvAttribute
*attribute
;
134 LttvAttributeValue value
;
137 gchar attribute_path
[PATH_MAX
];
139 if(stat(ltt_trace_name(lttv_trace(trace
)), &buf
)) {
140 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
141 ltt_trace_name(lttv_trace(trace
)));
145 snprintf(attribute_path
, PATH_MAX
, "%lu:%lu", buf
.st_dev
, buf
.st_ino
) >= 0);
148 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
151 value
= lttv_attribute_add(attribute
,
152 g_quark_from_string(attribute_path
),
155 *(value
.v_pointer
) = (gpointer
)trace
;
157 /* create new traceset and tracesetcontext */
159 LttvTracesetStats
*tss
;
161 attribute
= lttv_trace_attribute(trace
);
162 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
163 LTTV_COMPUTATION_TRACESET
,
166 ts
= lttv_traceset_new();
167 *(value
.v_pointer
) = ts
;
169 lttv_traceset_add(ts
,trace
);
171 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
172 LTTV_COMPUTATION_TRACESET_CONTEXT
,
175 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
176 *(value
.v_pointer
) = tss
;
178 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
180 value
= lttv_attribute_add(attribute
,
184 value
= lttv_attribute_add(attribute
,
185 LTTV_REQUESTS_CURRENT
,
188 value
= lttv_attribute_add(attribute
,
192 value
= lttv_attribute_add(attribute
,
198 /* Remove a trace from the global attributes */
200 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
202 LttvAttribute
*g_attribute
= lttv_global_attributes();
203 LttvAttribute
*attribute
;
204 LttvAttributeValue value
;
208 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
211 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
212 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
214 g_assert(trace_v
!= NULL
);
216 /* Remove and background computation that could be in progress */
217 g_idle_remove_by_data(trace_v
);
219 if(trace_v
== trace
) {
221 LttvAttribute
*l_attribute
;
223 /* create new traceset and tracesetcontext */
225 LttvTracesetStats
*tss
;
227 l_attribute
= lttv_trace_attribute(trace
);
230 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
231 LTTV_REQUESTS_QUEUE
);
233 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
234 LTTV_REQUESTS_CURRENT
);
236 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
239 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
240 LTTV_NOTIFY_CURRENT
);
242 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
243 LTTV_COMPUTATION_TRACESET
,
246 ts
= (LttvTraceset
*)*(value
.v_pointer
);
248 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
249 LTTV_COMPUTATION_TRACESET_CONTEXT
,
252 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
254 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
256 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
257 LTTV_COMPUTATION_TRACESET_CONTEXT
);
258 lttv_traceset_destroy(ts
);
259 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
260 LTTV_COMPUTATION_TRACESET
);
262 /* finally, remove the global attribute */
263 lttv_attribute_remove(attribute
, i
);
272 * Function to request data from a specific trace
274 * The memory allocated for the request will be managed by the API.
276 * @param trace the trace to compute
277 * @param module_name the name of the module which registered global computation
281 void lttvwindowtraces_background_request_queue
282 (LttvTrace
*trace
, gchar
*module_name
)
284 BackgroundRequest
*bg_req
;
285 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
286 LttvAttribute
*g_attribute
= lttv_global_attributes();
287 LttvAttribute
*module_attribute
;
288 LttvAttributeValue value
;
289 LttvAttributeType type
;
293 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
297 slist
= (GSList
**)(value
.v_pointer
);
299 /* Verify that the calculator is loaded */
300 g_assert(module_attribute
=
301 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
305 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
306 g_quark_from_string(module_name
),
308 if(type
== LTTV_NONE
) {
309 g_critical("Missing background calculator %s", module_name
);
313 bg_req
= g_new(BackgroundRequest
,1);
314 bg_req
->module_name
= g_quark_from_string(module_name
);
315 bg_req
->trace
= trace
;
317 *slist
= g_slist_append(*slist
, bg_req
);
319 /* Priority lower than live servicing */
320 g_idle_remove_by_data(trace
);
321 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
322 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
325 /* FIXME : show message in status bar, need context and message id */
326 g_info("Background computation started for trace %p", trace
);
330 * Remove a background request from a trace.
332 * This should ONLY be used by the modules which registered the global hooks
333 * (module_name). If this is called by the viewers, it may lead to incomplete
334 * and incoherent background processing information.
336 * Even if the module which deals with the hooks removes the background
337 * requests, it may cause a problem if the module gets loaded again in the
338 * session : the data will be partially calculated. The calculation function
339 * must deal with this case correctly.
341 * @param trace the trace to compute
342 * @param module_name the name of the module which registered global computation
346 void lttvwindowtraces_background_request_remove
347 (LttvTrace
*trace
, gchar
*module_name
)
349 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
350 LttvAttributeValue value
;
354 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
358 slist
= (GSList
**)(value
.v_pointer
);
360 for(iter
=*slist
;iter
!=NULL
;) {
361 BackgroundRequest
*bg_req
=
362 (BackgroundRequest
*)iter
->data
;
364 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
365 GSList
*rem_iter
= iter
;
366 iter
=g_slist_next(iter
);
368 *slist
= g_slist_delete_link(*slist
, rem_iter
);
370 iter
=g_slist_next(iter
);
377 * Register a callback to be called when requested data is passed in the next
378 * queued background processing.
380 * @param owner owner of the background notification
381 * @param trace the trace computed
382 * @param notify_time time when notification hooks must be called
383 * @param notify_position position when notification hooks must be called
384 * @param notify Hook to call when the notify position is passed
387 void lttvwindowtraces_background_notify_queue
391 const LttvTracesetContextPosition
*notify_position
,
392 const LttvHooks
*notify
)
394 BackgroundNotify
*bg_notify
;
395 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
396 LttvAttributeValue value
;
399 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
403 slist
= (GSList
**)(value
.v_pointer
);
406 bg_notify
= g_new(BackgroundNotify
,1);
408 bg_notify
->owner
= owner
;
409 bg_notify
->trace
= trace
;
410 bg_notify
->notify_time
= notify_time
;
411 if(notify_position
!= NULL
) {
412 bg_notify
->notify_position
= lttv_traceset_context_position_new();
413 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
416 bg_notify
->notify_position
= NULL
;
419 bg_notify
->notify
= lttv_hooks_new();
420 lttv_hooks_add_list(bg_notify
->notify
, notify
);
422 *slist
= g_slist_append(*slist
, bg_notify
);
426 * Register a callback to be called when requested data is passed in the current
427 * background processing.
429 * @param owner owner of the background notification
430 * @param trace the trace computed
431 * @param notify_time time when notification hooks must be called
432 * @param notify_position position when notification hooks must be called
433 * @param notify Hook to call when the notify position is passed
436 void lttvwindowtraces_background_notify_current
440 const LttvTracesetContextPosition
*notify_position
,
441 const LttvHooks
*notify
)
443 BackgroundNotify
*bg_notify
;
444 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
445 LttvAttributeValue value
;
448 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
452 slist
= (GSList
**)(value
.v_pointer
);
454 bg_notify
= g_new(BackgroundNotify
,1);
456 bg_notify
->owner
= owner
;
457 bg_notify
->trace
= trace
;
458 bg_notify
->notify_time
= notify_time
;
459 if(notify_position
!= NULL
) {
460 bg_notify
->notify_position
= lttv_traceset_context_position_new();
461 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
464 bg_notify
->notify_position
= NULL
;
466 bg_notify
->notify
= lttv_hooks_new();
467 lttv_hooks_add_list(bg_notify
->notify
, notify
);
469 *slist
= g_slist_append(*slist
, bg_notify
);
473 static void notify_request_free(BackgroundNotify
*notify_req
)
475 if(notify_req
== NULL
) return;
477 if(notify_req
->notify_position
!= NULL
)
478 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
479 if(notify_req
->notify
!= NULL
)
480 lttv_hooks_destroy(notify_req
->notify
);
485 * Removes all the notifications requests from a specific viewer.
487 * @param owner owner of the background notification
490 void lttvwindowtraces_background_notify_remove(gpointer owner
)
494 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
495 LttvAttribute
*attribute
;
496 LttvAttributeValue value
;
497 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
501 g_assert(trace_v
!= NULL
);
503 attribute
= lttv_trace_attribute(trace_v
);
505 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
509 slist
= (GSList
**)(value
.v_pointer
);
511 for(iter
=*slist
;iter
!=NULL
;) {
513 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
515 if(bg_notify
->owner
== owner
) {
516 GSList
*rem_iter
= iter
;
517 iter
=g_slist_next(iter
);
518 notify_request_free(bg_notify
);
519 *slist
= g_slist_remove_link(*slist
, rem_iter
);
521 iter
=g_slist_next(iter
);
525 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
529 slist
= (GSList
**)(value
.v_pointer
);
531 for(iter
=*slist
;iter
!=NULL
;) {
533 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
535 if(bg_notify
->owner
== owner
) {
536 GSList
*rem_iter
= iter
;
537 iter
=g_slist_next(iter
);
538 notify_request_free(bg_notify
);
539 *slist
= g_slist_remove_link(*slist
, rem_iter
);
541 iter
=g_slist_next(iter
);
548 /* Background processing helper functions */
550 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
551 LttvTracesetContext
*tsc
)
553 LttvAttribute
*g_attribute
= lttv_global_attributes();
554 LttvAttribute
*module_attribute
;
555 LttvAttributeType type
;
556 LttvAttributeValue value
;
557 LttvHooks
*before_chunk_traceset
=NULL
;
558 LttvHooks
*before_chunk_trace
=NULL
;
559 LttvHooks
*before_chunk_tracefile
=NULL
;
560 LttvHooks
*event_hook
=NULL
;
561 LttvHooksById
*event_hook_by_id
=NULL
;
562 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
565 g_assert(module_attribute
=
566 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
569 g_assert(module_attribute
=
570 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
571 LTTV_IATTRIBUTE(module_attribute
),
574 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
575 LTTV_BEFORE_CHUNK_TRACESET
,
577 if(type
== LTTV_POINTER
) {
578 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
581 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
582 LTTV_BEFORE_CHUNK_TRACE
,
584 if(type
== LTTV_POINTER
) {
585 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
588 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
589 LTTV_BEFORE_CHUNK_TRACEFILE
,
591 if(type
== LTTV_POINTER
) {
592 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
595 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
598 if(type
== LTTV_POINTER
) {
599 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
602 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
603 LTTV_EVENT_HOOK_BY_ID
,
605 if(type
== LTTV_POINTER
) {
606 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
609 /* Call the module's hook adder */
610 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
613 if(type
== LTTV_POINTER
) {
614 lttv_hooks_call((LttvHooks
*)*(value
.v_pointer
), (gpointer
)tss
);
619 lttv_process_traceset_begin(tsc
,
620 before_chunk_traceset
,
622 before_chunk_tracefile
,
628 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
629 LttvTracesetContext
*tsc
)
631 LttvAttribute
*g_attribute
= lttv_global_attributes();
632 LttvAttribute
*module_attribute
;
633 LttvAttributeType type
;
634 LttvAttributeValue value
;
635 LttvHooks
*after_chunk_traceset
=NULL
;
636 LttvHooks
*after_chunk_trace
=NULL
;
637 LttvHooks
*after_chunk_tracefile
=NULL
;
638 LttvHooks
*event_hook
=NULL
;
639 LttvHooksById
*event_hook_by_id
=NULL
;
640 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
642 g_assert(module_attribute
=
643 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
646 g_assert(module_attribute
=
647 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
648 LTTV_IATTRIBUTE(module_attribute
),
651 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
652 LTTV_AFTER_CHUNK_TRACESET
,
654 if(type
== LTTV_POINTER
) {
655 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
658 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
659 LTTV_AFTER_CHUNK_TRACE
,
661 if(type
== LTTV_POINTER
) {
662 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
665 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
666 LTTV_AFTER_CHUNK_TRACEFILE
,
668 if(type
== LTTV_POINTER
) {
669 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
672 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
675 if(type
== LTTV_POINTER
) {
676 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
679 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
680 LTTV_EVENT_HOOK_BY_ID
,
682 if(type
== LTTV_POINTER
) {
683 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
686 lttv_process_traceset_end(tsc
,
687 after_chunk_traceset
,
689 after_chunk_tracefile
,
693 /* Call the module's hook remover */
694 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
697 if(type
== LTTV_POINTER
) {
698 lttv_hooks_call((LttvHooks
*)*(value
.v_pointer
), (gpointer
)tss
);
703 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
706 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
707 LttvAttributeValue value
;
710 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
713 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
716 /* the value is left unset. The only presence of the attribute is necessary.
720 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
723 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
726 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
729 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
733 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
736 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
737 LttvAttributeType type
;
738 LttvAttributeValue value
;
741 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
744 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
747 /* The only presence of the attribute is necessary. */
748 if(type
== LTTV_NONE
)
754 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
757 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
758 LttvAttributeValue value
;
761 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
764 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
767 /* the value is left unset. The only presence of the attribute is necessary.
771 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
774 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
777 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
780 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
784 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
787 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
788 LttvAttributeType type
;
789 LttvAttributeValue value
;
792 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
795 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
798 /* The only presence of the attribute is necessary. */
799 if(type
== LTTV_NONE
)
806 /* lttvwindowtraces_process_pending_requests
808 * This internal function gets called by g_idle, taking care of the pending
814 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
816 LttvTracesetContext
*tsc
;
817 LttvTracesetStats
*tss
;
819 LttvAttribute
*attribute
;
820 LttvAttribute
*g_attribute
= lttv_global_attributes();
821 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
822 LttvAttributeValue value
;
823 LttvAttributeType type
;
825 LttvHooks
*before_request
, *after_request
;
830 attribute
= lttv_trace_attribute(trace
);
832 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
835 g_assert(type
== LTTV_POINTER
);
836 list_out
= (GSList
**)(value
.v_pointer
);
838 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
839 LTTV_REQUESTS_CURRENT
,
841 g_assert(type
== LTTV_POINTER
);
842 list_in
= (GSList
**)(value
.v_pointer
);
844 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
847 g_assert(type
== LTTV_POINTER
);
848 notify_out
= (GSList
**)(value
.v_pointer
);
850 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
853 g_assert(type
== LTTV_POINTER
);
854 notify_in
= (GSList
**)(value
.v_pointer
);
856 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
857 LTTV_COMPUTATION_TRACESET
,
859 g_assert(type
== LTTV_POINTER
);
860 ts
= (LttvTraceset
*)*(value
.v_pointer
);
862 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
863 LTTV_COMPUTATION_TRACESET_CONTEXT
,
865 g_assert(type
== LTTV_POINTER
);
866 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
867 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
868 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
869 g_assert(LTTV_IS_TRACESET_STATS(tss
));
871 /* There is no events requests pending : we should never have been called! */
872 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
874 /* 0.1 Lock traces */
879 iter_trace
<lttv_traceset_number(tsc
->ts
);
881 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
883 if(lttvwindowtraces_lock(trace_v
) != 0)
884 return TRUE
; /* Cannot get trace lock, try later */
888 /* 0.2 Sync tracefiles */
889 lttv_process_traceset_synchronize_tracefiles(tsc
);
891 /* 1. Before processing */
893 /* if list_in is empty */
894 if(g_slist_length(*list_in
) == 0) {
897 /* - Add all requests in list_out to list_in, empty list_out */
898 GSList
*iter
= *list_out
;
900 while(iter
!= NULL
) {
901 gboolean remove
= FALSE
;
902 gboolean free_data
= FALSE
;
904 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
908 *list_in
= g_slist_append(*list_in
, bg_req
);
913 GSList
*remove_iter
= iter
;
915 iter
= g_slist_next(iter
);
916 if(free_data
) g_free(remove_iter
->data
);
917 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
918 } else { // not remove
919 iter
= g_slist_next(iter
);
925 GSList
*iter
= *list_in
;
926 /* - for each request in list_in */
927 while(iter
!= NULL
) {
929 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
930 /* - set hooks'in_progress flag to TRUE */
931 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
934 /* - call before request hook */
935 /* Get before request hook */
936 LttvAttribute
*module_attribute
;
938 g_assert(module_attribute
=
939 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
940 LTTV_IATTRIBUTE(g_attribute
),
943 g_assert(module_attribute
=
944 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
945 LTTV_IATTRIBUTE(module_attribute
),
946 bg_req
->module_name
)));
948 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
951 g_assert(type
== LTTV_POINTER
);
952 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
955 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
957 iter
= g_slist_next(iter
);
961 /* - seek trace to start */
963 LttTime start
= { 0, 0};
964 lttv_process_traceset_seek_time(tsc
, start
);
967 /* - Move all notifications from notify_out to notify_in. */
969 GSList
*iter
= *notify_out
;
970 g_assert(g_slist_length(*notify_in
) == 0);
972 while(iter
!= NULL
) {
973 gboolean remove
= FALSE
;
974 gboolean free_data
= FALSE
;
976 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
980 *notify_in
= g_slist_append(*notify_in
, notify_req
);
985 GSList
*remove_iter
= iter
;
987 iter
= g_slist_next(iter
);
989 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
990 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
991 } else { // not remove
992 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 /*- Call before chunk hooks for list_in*/
1005 /*- add hooks to context*/
1006 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1008 iter
= g_slist_next(iter
);
1013 /* 2. call process traceset middle for a chunk */
1015 /*(assert list_in is not empty! : should not even be called in that case)*/
1016 LttTime end
= { G_MAXUINT
, G_MAXUINT
};
1017 g_assert(g_slist_length(*list_in
) != 0);
1019 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1022 /* 3. After the chunk */
1024 /* 3.1 call after_chunk hooks for list_in */
1026 GSList
*iter
= *list_in
;
1027 /* - for each request in list_in */
1028 while(iter
!= NULL
) {
1030 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1031 /* - Call after chunk hooks for list_in */
1032 /* - remove hooks from context */
1033 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1035 iter
= g_slist_next(iter
);
1039 /* 3.2 for each notify_in */
1041 GSList
*iter
= *notify_in
;
1042 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1044 while(iter
!= NULL
) {
1045 gboolean remove
= FALSE
;
1046 gboolean free_data
= FALSE
;
1048 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1050 /* - if current time >= notify time, call notify and remove from
1052 * - if current position >= notify position, call notify and remove
1056 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1058 (notify_req
->notify_position
!= NULL
&&
1059 lttv_traceset_context_ctx_pos_compare(tsc
,
1060 notify_req
->notify_position
) >= 0)
1063 lttv_hooks_call(notify_req
->notify
, notify_req
);
1072 GSList
*remove_iter
= iter
;
1074 iter
= g_slist_next(iter
);
1076 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1077 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1078 } else { // not remove
1079 iter
= g_slist_next(iter
);
1085 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1086 /* 3.3 if end of trace reached */
1088 g_debug("Current time : %lu sec, %lu nsec",
1089 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1090 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1091 tsc
->time_span
.end_time
) > 0) {
1093 /* - for each request in list_in */
1095 GSList
*iter
= *list_in
;
1097 while(iter
!= NULL
) {
1098 gboolean remove
= FALSE
;
1099 gboolean free_data
= FALSE
;
1101 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1103 /* - set hooks'in_progress flag to FALSE */
1104 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1106 /* - set hooks'ready flag to TRUE */
1107 lttvwindowtraces_set_ready(bg_req
->module_name
,
1109 /* - call after request hook */
1110 /* Get after request hook */
1111 LttvAttribute
*module_attribute
;
1113 g_assert(module_attribute
=
1114 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1115 LTTV_IATTRIBUTE(g_attribute
),
1116 LTTV_COMPUTATION
)));
1118 g_assert(module_attribute
=
1119 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1120 LTTV_IATTRIBUTE(module_attribute
),
1121 bg_req
->module_name
)));
1123 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1126 g_assert(type
== LTTV_POINTER
);
1127 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1129 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1130 /* - remove request */
1137 GSList
*remove_iter
= iter
;
1139 iter
= g_slist_next(iter
);
1140 if(free_data
) g_free(remove_iter
->data
);
1141 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1142 } else { // not remove
1143 iter
= g_slist_next(iter
);
1148 /* - for each notifications in notify_in */
1150 GSList
*iter
= *notify_in
;
1152 while(iter
!= NULL
) {
1153 gboolean remove
= FALSE
;
1154 gboolean free_data
= FALSE
;
1156 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1158 /* - call notify and remove from notify_in */
1159 lttv_hooks_call(notify_req
->notify
, notify_req
);
1166 GSList
*remove_iter
= iter
;
1168 iter
= g_slist_next(iter
);
1170 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1171 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1172 } else { // not remove
1173 iter
= g_slist_next(iter
);
1177 /* - if list_out is empty */
1178 if(g_slist_length(*list_out
) == 0) {
1179 /* - return FALSE (scheduler stopped) */
1180 g_debug("Background computation scheduler stopped");
1181 g_info("Background computation finished for trace %p", trace
);
1182 /* FIXME : remove status bar info, need context id and message id */
1188 /* 3.4 else, end of trace not reached */
1189 /* - return TRUE (scheduler still registered) */
1190 g_debug("Background computation left");
1195 /* 4. Unlock traces */
1197 //lttv_process_traceset_get_sync_data(tsc);
1201 iter_trace
<lttv_traceset_number(tsc
->ts
);
1203 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1205 lttvwindowtraces_unlock(trace_v
);
1214 * Register the background computation hooks for a specific module. It adds the
1215 * computation hooks to the global attrubutes, under "computation/module name".
1217 * @param module_name A GQuark : the name of the module which computes the
1220 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1221 LttvHooks
*before_chunk_traceset
,
1222 LttvHooks
*before_chunk_trace
,
1223 LttvHooks
*before_chunk_tracefile
,
1224 LttvHooks
*after_chunk_traceset
,
1225 LttvHooks
*after_chunk_trace
,
1226 LttvHooks
*after_chunk_tracefile
,
1227 LttvHooks
*before_request
,
1228 LttvHooks
*after_request
,
1229 LttvHooks
*event_hook
,
1230 LttvHooksById
*event_hook_by_id
,
1231 LttvHooks
*hook_adder
,
1232 LttvHooks
*hook_remover
)
1234 LttvAttribute
*g_attribute
= lttv_global_attributes();
1235 LttvAttribute
*attribute
;
1236 LttvAttributeValue value
;
1238 g_assert(attribute
=
1239 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1240 LTTV_COMPUTATION
)));
1242 g_assert(attribute
=
1243 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1246 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1247 LTTV_BEFORE_CHUNK_TRACESET
,
1250 *(value
.v_pointer
) = before_chunk_traceset
;
1252 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1253 LTTV_BEFORE_CHUNK_TRACE
,
1256 *(value
.v_pointer
) = before_chunk_trace
;
1258 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1259 LTTV_BEFORE_CHUNK_TRACEFILE
,
1262 *(value
.v_pointer
) = before_chunk_tracefile
;
1264 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1265 LTTV_AFTER_CHUNK_TRACESET
,
1268 *(value
.v_pointer
) = after_chunk_traceset
;
1270 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1271 LTTV_AFTER_CHUNK_TRACE
,
1274 *(value
.v_pointer
) = after_chunk_trace
;
1276 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1277 LTTV_AFTER_CHUNK_TRACEFILE
,
1280 *(value
.v_pointer
) = after_chunk_tracefile
;
1282 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1283 LTTV_BEFORE_REQUEST
,
1286 *(value
.v_pointer
) = before_request
;
1288 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1292 *(value
.v_pointer
) = after_request
;
1294 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1298 *(value
.v_pointer
) = event_hook
;
1300 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1301 LTTV_EVENT_HOOK_BY_ID
,
1304 *(value
.v_pointer
) = event_hook_by_id
;
1306 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1310 *(value
.v_pointer
) = hook_adder
;
1312 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1316 *(value
.v_pointer
) = hook_remover
;
1322 * It removes all the requests than can be currently processed by the
1323 * background computation algorithm for all the traces (list_in and list_out).
1325 * Leaves the flag to in_progress or none.. depending if current or queue
1327 * @param module_name A GQuark : the name of the module which computes the
1330 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1334 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1335 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1336 g_assert(trace_v
!= NULL
);
1338 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1339 LttvAttributeValue value
;
1340 GSList
**queue
, **current
;
1343 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1344 LTTV_REQUESTS_QUEUE
,
1347 queue
= (GSList
**)(value
.v_pointer
);
1350 while(iter
!= NULL
) {
1351 gboolean remove
= FALSE
;
1352 gboolean free_data
= FALSE
;
1354 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1356 if(bg_req
->module_name
== module_name
) {
1364 GSList
*remove_iter
= iter
;
1366 iter
= g_slist_next(iter
);
1367 if(free_data
) g_free(remove_iter
->data
);
1368 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1369 } else { // not remove
1370 iter
= g_slist_next(iter
);
1375 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1376 LTTV_REQUESTS_CURRENT
,
1379 current
= (GSList
**)(value
.v_pointer
);
1382 while(iter
!= NULL
) {
1383 gboolean remove
= FALSE
;
1384 gboolean free_data
= FALSE
;
1386 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1388 if(bg_req
->module_name
== module_name
) {
1396 GSList
*remove_iter
= iter
;
1398 iter
= g_slist_next(iter
);
1399 if(free_data
) g_free(remove_iter
->data
);
1400 *current
= g_slist_remove_link(*current
, remove_iter
);
1401 } else { // not remove
1402 iter
= g_slist_next(iter
);
1410 * Unregister the background computation hooks for a specific module.
1412 * It also removes all the requests than can be currently processed by the
1413 * background computation algorithm for all the traces (list_in and list_out).
1415 * @param module_name A GQuark : the name of the module which computes the
1419 void lttvwindowtraces_unregister_computation_hooks
1420 (LttvAttributeName module_name
)
1422 LttvAttribute
*g_attribute
= lttv_global_attributes();
1423 LttvAttribute
*attribute
;
1424 LttvAttributeValue value
;
1426 g_assert(attribute
=
1427 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1428 LTTV_COMPUTATION
)));
1429 g_assert(attribute
=
1430 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1434 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1435 LTTV_BEFORE_CHUNK_TRACESET
,
1438 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1439 if(before_chunk_traceset
!= NULL
)
1440 lttv_hooks_destroy(before_chunk_traceset
);
1442 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1443 LTTV_BEFORE_CHUNK_TRACE
,
1446 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1447 if(before_chunk_trace
!= NULL
)
1448 lttv_hooks_destroy(before_chunk_trace
);
1450 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1451 LTTV_BEFORE_CHUNK_TRACEFILE
,
1454 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1455 if(before_chunk_tracefile
!= NULL
)
1456 lttv_hooks_destroy(before_chunk_tracefile
);
1458 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1459 LTTV_AFTER_CHUNK_TRACESET
,
1462 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1463 if(after_chunk_traceset
!= NULL
)
1464 lttv_hooks_destroy(after_chunk_traceset
);
1466 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1467 LTTV_AFTER_CHUNK_TRACE
,
1470 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1471 if(after_chunk_trace
!= NULL
)
1472 lttv_hooks_destroy(after_chunk_trace
);
1474 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1475 LTTV_AFTER_CHUNK_TRACEFILE
,
1478 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1479 if(after_chunk_tracefile
!= NULL
)
1480 lttv_hooks_destroy(after_chunk_tracefile
);
1482 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1483 LTTV_BEFORE_REQUEST
,
1486 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1487 if(before_request
!= NULL
)
1488 lttv_hooks_destroy(before_request
);
1490 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1494 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1495 if(after_request
!= NULL
)
1496 lttv_hooks_destroy(after_request
);
1498 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1502 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1503 if(event_hook
!= NULL
)
1504 lttv_hooks_destroy(event_hook
);
1506 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1507 LTTV_EVENT_HOOK_BY_ID
,
1510 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1511 if(event_hook_by_id
!= NULL
)
1512 lttv_hooks_by_id_destroy(event_hook_by_id
);
1514 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1518 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1519 if(hook_adder
!= NULL
)
1520 lttv_hooks_destroy(hook_adder
);
1522 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1526 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1527 if(hook_remover
!= NULL
)
1528 lttv_hooks_destroy(hook_remover
);
1531 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1532 LTTV_EVENT_HOOK_BY_ID
);
1533 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1536 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1537 LTTV_AFTER_REQUEST
);
1538 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1539 LTTV_BEFORE_REQUEST
);
1541 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1542 LTTV_AFTER_CHUNK_TRACEFILE
);
1543 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1544 LTTV_AFTER_CHUNK_TRACE
);
1545 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1546 LTTV_AFTER_CHUNK_TRACESET
);
1548 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1549 LTTV_BEFORE_CHUNK_TRACEFILE
);
1550 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1551 LTTV_BEFORE_CHUNK_TRACE
);
1552 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1553 LTTV_BEFORE_CHUNK_TRACESET
);
1554 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1556 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1559 /* finally, remove module name */
1560 g_assert(attribute
=
1561 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1562 LTTV_COMPUTATION
)));
1563 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1569 * Lock a trace so no other instance can use it.
1571 * @param trace The trace to lock.
1572 * @return 0 on success, -1 if cannot get lock.
1574 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1576 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1577 LttvAttributeValue value
;
1578 LttvAttributeType type
;
1580 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1583 /* Verify the absence of the lock. */
1584 if(type
!= LTTV_NONE
) {
1585 g_critical("Cannot take trace lock");
1589 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1592 /* the value is left unset. The only presence of the attribute is necessary.
1601 * @param trace The trace to unlock.
1602 * @return 0 on success, -1 if cannot unlock (not locked ?).
1604 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1606 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1607 LttvAttributeType type
;
1608 LttvAttributeValue value
;
1610 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1613 /* Verify the presence of the lock. */
1614 if(type
== LTTV_NONE
) {
1615 g_critical("Cannot release trace lock");
1619 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1626 * Verify if a trace is locked.
1628 * @param trace The trace to verify.
1629 * @return TRUE if locked, FALSE is unlocked.
1631 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1633 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1634 LttvAttributeType type
;
1635 LttvAttributeValue value
;
1637 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1640 /* The only presence of the attribute is necessary. */
1641 if(type
== LTTV_NONE
)