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 */
56 /* Get a trace by its path name.
58 * @param path path of the trace on the virtual file system.
59 * @return Pointer to trace if found
60 * NULL is returned if the trace is not present
63 LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
65 LttvAttribute
*attribute
= lttv_global_attributes();
68 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
69 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
73 g_assert(trace_v
!= NULL
);
75 trace
= lttv_trace(trace_v
);
76 g_assert(trace
!= NULL
);
77 name
= ltt_trace_name(trace
);
79 if(strcmp(name
, path
) == 0) {
88 /* Get a trace by its number identifier */
90 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
92 LttvAttribute
*g_attribute
= lttv_global_attributes();
93 LttvAttribute
*attribute
;
94 LttvAttributeType type
;
95 LttvAttributeName name
;
96 LttvAttributeValue value
;
99 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
102 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
104 if(type
== LTTV_POINTER
) {
105 return (LttvTrace
*)*(value
.v_pointer
);
111 /* Total number of traces */
113 guint
lttvwindowtraces_get_number()
115 LttvAttribute
*g_attribute
= lttv_global_attributes();
116 LttvAttribute
*attribute
;
117 LttvAttributeValue value
;
120 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
123 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
126 /* Add a trace to the global attributes */
128 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
130 LttvAttribute
*g_attribute
= lttv_global_attributes();
131 LttvAttribute
*attribute
;
132 LttvAttributeValue value
;
135 gchar attribute_path
[PATH_MAX
];
137 if(stat(ltt_trace_name(lttv_trace(trace
)), &buf
)) {
138 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
139 ltt_trace_name(lttv_trace(trace
)));
143 snprintf(attribute_path
, PATH_MAX
, "%lu:%lu", buf
.st_dev
, buf
.st_ino
) >= 0);
146 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
149 value
= lttv_attribute_add(attribute
,
150 g_quark_from_string(attribute_path
),
153 *(value
.v_pointer
) = (gpointer
)trace
;
155 /* create new traceset and tracesetcontext */
157 LttvTracesetContext
*tsc
;
159 attribute
= lttv_trace_attribute(trace
);
160 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
161 LTTV_COMPUTATION_TRACESET
,
164 ts
= lttv_traceset_new();
165 *(value
.v_pointer
) = ts
;
167 lttv_traceset_add(ts
,trace
);
169 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
170 LTTV_COMPUTATION_TRACESET_CONTEXT
,
173 tsc
= g_object_new(LTTV_TRACESET_CONTEXT_TYPE
, NULL
);
174 *(value
.v_pointer
) = tsc
;
176 lttv_context_init(tsc
, ts
);
178 value
= lttv_attribute_add(attribute
,
182 value
= lttv_attribute_add(attribute
,
183 LTTV_REQUESTS_CURRENT
,
186 value
= lttv_attribute_add(attribute
,
190 value
= lttv_attribute_add(attribute
,
196 /* Remove a trace from the global attributes */
198 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
200 LttvAttribute
*g_attribute
= lttv_global_attributes();
201 LttvAttribute
*attribute
;
202 LttvAttributeValue value
;
206 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
209 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
210 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
212 g_assert(trace_v
!= NULL
);
214 if(trace_v
== trace
) {
216 LttvAttribute
*l_attribute
;
218 /* create new traceset and tracesetcontext */
220 LttvTracesetContext
*tsc
;
222 l_attribute
= lttv_trace_attribute(trace
);
225 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
226 LTTV_REQUESTS_QUEUE
);
228 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
229 LTTV_REQUESTS_CURRENT
);
231 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
234 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
235 LTTV_NOTIFY_CURRENT
);
237 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
238 LTTV_COMPUTATION_TRACESET
,
241 ts
= (LttvTraceset
*)*(value
.v_pointer
);
243 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
244 LTTV_COMPUTATION_TRACESET_CONTEXT
,
247 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
249 lttv_context_fini(tsc
);
251 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
252 LTTV_COMPUTATION_TRACESET_CONTEXT
);
253 lttv_traceset_destroy(ts
);
254 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
255 LTTV_COMPUTATION_TRACESET
);
257 /* finally, remove the global attribute */
258 lttv_attribute_remove(attribute
, i
);
267 * Function to request data from a specific trace
269 * The memory allocated for the request will be managed by the API.
271 * @param trace the trace to compute
272 * @param module_name the name of the module which registered global computation
276 void lttvwindowtraces_background_request_queue
277 (LttvTrace
*trace
, gchar
*module_name
)
279 BackgroundRequest
*bg_req
;
280 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
281 LttvAttributeValue value
;
285 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
289 slist
= (GSList
**)(value
.v_pointer
);
291 bg_req
= g_new(BackgroundRequest
,1);
292 bg_req
->module_name
= g_quark_from_string(module_name
);
293 bg_req
->trace
= trace
;
295 *slist
= g_slist_append(*slist
, bg_req
);
299 * Remove a background request from a trace.
301 * This should ONLY be used by the modules which registered the global hooks
302 * (module_name). If this is called by the viewers, it may lead to incomplete
303 * and incoherent background processing information.
305 * Even if the module which deals with the hooks removes the background
306 * requests, it may cause a problem if the module gets loaded again in the
307 * session : the data will be partially calculated. The calculation function
308 * must deal with this case correctly.
310 * @param trace the trace to compute
311 * @param module_name the name of the module which registered global computation
315 void lttvwindowtraces_background_request_remove
316 (LttvTrace
*trace
, gchar
*module_name
)
318 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
319 LttvAttributeValue value
;
323 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
327 slist
= (GSList
**)(value
.v_pointer
);
329 for(iter
=*slist
;iter
!=NULL
;) {
330 BackgroundRequest
*bg_req
=
331 (BackgroundRequest
*)iter
->data
;
333 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
334 GSList
*rem_iter
= iter
;
335 iter
=g_slist_next(iter
);
337 *slist
= g_slist_delete_link(*slist
, rem_iter
);
339 iter
=g_slist_next(iter
);
346 * Register a callback to be called when requested data is passed in the next
347 * queued background processing.
349 * @param owner owner of the background notification
350 * @param trace the trace computed
351 * @param notify_time time when notification hooks must be called
352 * @param notify_position position when notification hooks must be called
353 * @param notify Hook to call when the notify position is passed
356 void lttvwindowtraces_background_notify_queue
360 const LttvTracesetContextPosition
*notify_position
,
361 const LttvHooks
*notify
)
363 BackgroundNotify
*bg_notify
;
364 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
365 LttvAttributeValue value
;
368 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
372 slist
= (GSList
**)(value
.v_pointer
);
375 bg_notify
= g_new(BackgroundNotify
,1);
377 bg_notify
->owner
= owner
;
378 bg_notify
->trace
= trace
;
379 bg_notify
->notify_time
= notify_time
;
380 bg_notify
->notify_position
= ltt_traceset_context_position_new();
381 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
383 bg_notify
->notify
= lttv_hooks_new();
384 lttv_hooks_add_list(bg_notify
->notify
, notify
);
386 *slist
= g_slist_append(*slist
, bg_notify
);
390 * Register a callback to be called when requested data is passed in the current
391 * background processing.
393 * @param owner owner of the background notification
394 * @param trace the trace computed
395 * @param notify_time time when notification hooks must be called
396 * @param notify_position position when notification hooks must be called
397 * @param notify Hook to call when the notify position is passed
400 void lttvwindowtraces_background_notify_current
404 const LttvTracesetContextPosition
*notify_position
,
405 const LttvHooks
*notify
)
407 BackgroundNotify
*bg_notify
;
408 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
409 LttvAttributeValue value
;
412 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
416 slist
= (GSList
**)(value
.v_pointer
);
418 bg_notify
= g_new(BackgroundNotify
,1);
420 bg_notify
->owner
= owner
;
421 bg_notify
->trace
= trace
;
422 bg_notify
->notify_time
= notify_time
;
423 bg_notify
->notify_position
= ltt_traceset_context_position_new();
424 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
426 bg_notify
->notify
= lttv_hooks_new();
427 lttv_hooks_add_list(bg_notify
->notify
, notify
);
429 *slist
= g_slist_append(*slist
, bg_notify
);
433 * Removes all the notifications requests from a specific viewer.
435 * @param owner owner of the background notification
438 void lttvwindowtraces_background_notify_remove(gpointer owner
)
442 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
443 LttvAttribute
*attribute
;
444 LttvAttributeValue value
;
445 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
449 g_assert(trace_v
!= NULL
);
451 LttvAttribute
*t_a
= lttv_trace_attribute(trace_v
);
453 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
457 slist
= (GSList
**)(value
.v_pointer
);
459 for(iter
=*slist
;iter
!=NULL
;) {
461 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
463 if(bg_notify
->owner
== owner
) {
464 GSList
*rem_iter
= iter
;
465 iter
=g_slist_next(iter
);
466 lttv_traceset_context_position_destroy(
467 bg_notify
->notify_position
);
468 lttv_hooks_destroy(bg_notify
->notify
);
470 g_slist_remove_link(*slist
, rem_iter
);
472 iter
=g_slist_next(iter
);
476 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
480 slist
= (GSList
**)(value
.v_pointer
);
482 for(iter
=*slist
;iter
!=NULL
;) {
484 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
486 if(bg_notify
->owner
== owner
) {
487 GSList
*rem_iter
= iter
;
488 iter
=g_slist_next(iter
);
489 lttv_traceset_context_position_destroy(
490 bg_notify
->notify_position
);
491 lttv_hooks_destroy(bg_notify
->notify
);
493 g_slist_remove_link(*slist
, rem_iter
);
495 iter
=g_slist_next(iter
);
502 /* Background processing helper functions */
504 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
505 LttvTracesetContext
*tsc
)
507 LttvAttribute
*g_attribute
= lttv_global_attributes();
508 LttvAttribute
*module_attribute
;
509 LttvAttributeType type
;
510 LttvAttributeValue value
;
511 LttvHooks
*before_chunk_traceset
=NULL
;
512 LttvHooks
*before_chunk_trace
=NULL
;
513 LttvHooks
*before_chunk_tracefile
=NULL
;
514 LttvHooks
*event_hook
=NULL
;
515 LttvHooksById
*event_hook_by_id
=NULL
;
518 g_assert(module_attribute
=
519 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
522 g_assert(module_attribute
=
523 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
524 LTTV_IATTRIBUTE(module_attribute
),
527 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
528 LTTV_BEFORE_CHUNK_TRACESET
,
530 if(type
== LTTV_POINTER
) {
531 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
534 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
535 LTTV_BEFORE_CHUNK_TRACE
,
537 if(type
== LTTV_POINTER
) {
538 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
541 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
542 LTTV_BEFORE_CHUNK_TRACEFILE
,
544 if(type
== LTTV_POINTER
) {
545 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
548 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
551 if(type
== LTTV_POINTER
) {
552 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
555 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
556 LTTV_EVENT_HOOK_BY_ID
,
558 if(type
== LTTV_POINTER
) {
559 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
563 lttv_process_traceset_begin(tsc
,
564 before_chunk_traceset
,
566 before_chunk_tracefile
,
572 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
573 LttvTracesetContext
*tsc
)
575 LttvAttribute
*g_attribute
= lttv_global_attributes();
576 LttvAttribute
*module_attribute
;
577 LttvAttributeType type
;
578 LttvAttributeValue value
;
579 LttvHooks
*after_chunk_traceset
=NULL
;
580 LttvHooks
*after_chunk_trace
=NULL
;
581 LttvHooks
*after_chunk_tracefile
=NULL
;
582 LttvHooks
*event_hook
=NULL
;
583 LttvHooksById
*event_hook_by_id
=NULL
;
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 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
596 LTTV_AFTER_CHUNK_TRACESET
,
598 if(type
== LTTV_POINTER
) {
599 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
602 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
603 LTTV_AFTER_CHUNK_TRACE
,
605 if(type
== LTTV_POINTER
) {
606 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
609 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
610 LTTV_AFTER_CHUNK_TRACEFILE
,
612 if(type
== LTTV_POINTER
) {
613 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
616 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
619 if(type
== LTTV_POINTER
) {
620 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
623 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
624 LTTV_EVENT_HOOK_BY_ID
,
626 if(type
== LTTV_POINTER
) {
627 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
631 lttv_process_traceset_end(tsc
,
632 after_chunk_traceset
,
634 after_chunk_tracefile
,
640 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
643 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
644 LttvAttributeValue value
;
647 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
650 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
653 /* the value is left unset. The only presence of the attribute is necessary.
657 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
660 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
663 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
666 lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute
),
670 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
673 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
674 LttvAttributeType type
;
675 LttvAttributeValue value
;
678 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
681 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
684 /* The only presence of the attribute is necessary. */
685 if(type
== LTTV_NONE
)
691 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
694 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
695 LttvAttributeValue value
;
698 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
701 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
704 /* the value is left unset. The only presence of the attribute is necessary.
708 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
711 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
714 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
717 lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute
),
721 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
724 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
725 LttvAttributeType type
;
726 LttvAttributeValue value
;
729 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
732 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
735 /* The only presence of the attribute is necessary. */
736 if(type
== LTTV_NONE
)
744 /* lttvwindowtraces_process_pending_requests
746 * This internal function gets called by g_idle, taking care of the pending
752 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
754 LttvTracesetContext
*tsc
;
756 LttvAttribute
*attribute
;
757 GSList
*list_out
, *list_in
, *notify_in
, *notify_out
;
758 LttvAttributeValue value
;
759 LttvAttributeType type
;
764 attribute
= lttv_trace_attribute(trace
);
766 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
769 g_assert(type
== LTTV_POINTER
);
770 list_out
= (GSList
*)*(value
.v_pointer
);
772 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
773 LTTV_REQUESTS_CURRENT
,
775 g_assert(type
== LTTV_POINTER
);
776 list_in
= (GSList
*)*(value
.v_pointer
);
778 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
781 g_assert(type
== LTTV_POINTER
);
782 notify_out
= (GSList
*)*(value
.v_pointer
);
784 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
787 g_assert(type
== LTTV_POINTER
);
788 notify_in
= (GSList
*)*(value
.v_pointer
);
790 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
791 LTTV_COMPUTATION_TRACESET
,
793 g_assert(type
== LTTV_POINTER
);
794 ts
= (LttvTraceset
*)*(value
.v_pointer
);
796 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
797 LTTV_COMPUTATION_TRACESET_CONTEXT
,
799 g_assert(type
== LTTV_POINTER
);
800 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
801 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
803 /* There is no events requests pending : we should never have been called! */
804 g_assert(g_slist_length(list_out
) != 0 || g_slist_length(list_in
) != 0);
808 /* 1. Before processing */
810 /* if list_in is empty */
811 if(g_slist_length(list_in
) == 0) {
814 /* - Add all requests in list_out to list_in, empty list_out */
815 GSList
*iter
= list_out
;
817 while(iter
!= NULL
) {
818 gboolean remove
= FALSE
;
819 gboolean free_data
= FALSE
;
821 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
825 list_in
= g_slist_append(list_in
, bg_req
);
830 GSList
*remove_iter
= iter
;
832 iter
= g_slist_next(iter
);
833 if(free_data
) g_free(remove_iter
->data
);
834 list_out
= g_slist_remove_link(list_out
, remove_iter
);
835 } else { // not remove
836 iter
= g_slist_next(iter
);
842 GSList
*iter
= list_in
;
843 /* - for each request in list_in */
844 while(iter
!= NULL
) {
846 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
847 /*- add hooks to context*/
848 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
851 iter
= g_slist_next(iter
);
855 /* - seek trace to start */
857 LttTime start
= { 0, 0};
858 lttv_process_traceset_seek_time(tsc
, start
);
861 /* - Move all notifications from notify_out to notify_in. */
863 GSList
*iter
= notify_out
;
864 g_assert(g_slist_length(notify_in
) == 0);
866 while(iter
!= NULL
) {
867 gboolean remove
= FALSE
;
868 gboolean free_data
= FALSE
;
870 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
874 notify_in
= g_slist_append(notify_in
, notify_req
);
879 GSList
*remove_iter
= iter
;
881 iter
= g_slist_next(iter
);
882 if(free_data
) g_free(remove_iter
->data
);
883 notify_out
= g_slist_remove_link(notify_out
, remove_iter
);
884 } else { // not remove
885 iter
= g_slist_next(iter
);
892 GSList
*iter
= list_in
;
893 /* - for each request in list_in */
894 while(iter
!= NULL
) {
896 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
897 /*- Call before chunk hooks for list_in*/
898 /*- add hooks to context*/
899 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
901 iter
= g_slist_next(iter
);
906 /* 2. call process traceset middle for a chunk */
908 /*(assert list_in is not empty! : should not even be called in that case)*/
909 LttTime end
= { G_MAXUINT
, G_MAXUINT
};
910 g_assert(g_slist_length(list_in
) != 0);
912 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
915 /* 3. After the chunk */
917 /* 3.1 call after_chunk hooks for list_in */
919 GSList
*iter
= list_in
;
920 /* - for each request in list_in */
921 while(iter
!= NULL
) {
923 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
924 /* - Call after chunk hooks for list_in */
925 /* - remove hooks from context */
926 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
928 iter
= g_slist_next(iter
);
932 /* 3.2 for each notify_in */
934 GSList
*iter
= notify_in
;
935 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
937 while(iter
!= NULL
) {
938 gboolean remove
= FALSE
;
939 gboolean free_data
= FALSE
;
941 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
943 /* - if current time >= notify time, call notify and remove from
945 * - if current position >= notify position, call notify and remove
949 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) >= 0)
951 (lttv_traceset_context_ctx_pos_compare(tsc
,
952 notify_req
->notify_position
) >= 0)
955 lttv_hooks_call(notify_req
->notify
, notify_req
);
964 GSList
*remove_iter
= iter
;
966 iter
= g_slist_next(iter
);
967 if(free_data
) g_free(remove_iter
->data
);
968 notify_in
= g_slist_remove_link(notify_in
, remove_iter
);
969 } else { // not remove
970 iter
= g_slist_next(iter
);
976 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
977 /* 3.3 if end of trace reached */
978 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
979 tsc
->time_span
.end_time
) > 0) {
981 /* - for each request in list_in */
983 GSList
*iter
= list_in
;
985 while(iter
!= NULL
) {
986 gboolean remove
= FALSE
;
987 gboolean free_data
= FALSE
;
989 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
991 /* - set hooks'in_progress flag to FALSE */
992 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
994 /* - set hooks'ready flag to TRUE */
995 lttvwindowtraces_set_ready(bg_req
->module_name
,
997 /* - remove request */
1004 GSList
*remove_iter
= iter
;
1006 iter
= g_slist_next(iter
);
1007 if(free_data
) g_free(remove_iter
->data
);
1008 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1009 } else { // not remove
1010 iter
= g_slist_next(iter
);
1015 /* - for each notifications in notify_in */
1017 GSList
*iter
= notify_in
;
1019 while(iter
!= NULL
) {
1020 gboolean remove
= FALSE
;
1021 gboolean free_data
= FALSE
;
1023 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1025 /* - call notify and remove from notify_in */
1026 lttv_hooks_call(notify_req
->notify
, notify_req
);
1033 GSList
*remove_iter
= iter
;
1035 iter
= g_slist_next(iter
);
1036 if(free_data
) g_free(remove_iter
->data
);
1037 notify_in
= g_slist_remove_link(notify_in
, remove_iter
);
1038 } else { // not remove
1039 iter
= g_slist_next(iter
);
1044 /* - return FALSE (scheduler stopped) */
1047 /* 3.4 else, end of trace not reached */
1048 /* - return TRUE (scheduler still registered) */
1058 * Register the background computation hooks for a specific module. It adds the
1059 * computation hooks to the global attrubutes, under "computation/module name"
1061 * @param module_name A GQuark : the name of the module which computes the
1064 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1065 LttvHooks
*before_chunk_traceset
,
1066 LttvHooks
*before_chunk_trace
,
1067 LttvHooks
*before_chunk_tracefile
,
1068 LttvHooks
*after_chunk_traceset
,
1069 LttvHooks
*after_chunk_trace
,
1070 LttvHooks
*after_chunk_tracefile
,
1071 LttvHooks
*before_request
,
1072 LttvHooks
*after_request
,
1073 LttvHooks
*event_hook
,
1074 LttvHooksById
*event_hook_by_id
)
1076 LttvAttribute
*g_attribute
= lttv_global_attributes();
1077 LttvAttribute
*attribute
;
1078 LttvAttributeValue value
;
1080 g_assert(attribute
=
1081 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1082 LTTV_COMPUTATION
)));
1084 g_assert(attribute
=
1085 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1088 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1089 LTTV_BEFORE_CHUNK_TRACESET
,
1092 *(value
.v_pointer
) = before_chunk_traceset
;
1094 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1095 LTTV_BEFORE_CHUNK_TRACE
,
1098 *(value
.v_pointer
) = before_chunk_trace
;
1100 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1101 LTTV_BEFORE_CHUNK_TRACEFILE
,
1104 *(value
.v_pointer
) = before_chunk_tracefile
;
1106 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1107 LTTV_AFTER_CHUNK_TRACESET
,
1110 *(value
.v_pointer
) = after_chunk_traceset
;
1112 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1113 LTTV_AFTER_CHUNK_TRACE
,
1116 *(value
.v_pointer
) = after_chunk_trace
;
1118 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1119 LTTV_AFTER_CHUNK_TRACEFILE
,
1122 *(value
.v_pointer
) = after_chunk_tracefile
;
1124 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1125 LTTV_BEFORE_REQUEST
,
1128 *(value
.v_pointer
) = before_request
;
1130 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1134 *(value
.v_pointer
) = after_request
;
1136 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1140 *(value
.v_pointer
) = event_hook
;
1142 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1143 LTTV_EVENT_HOOK_BY_ID
,
1146 *(value
.v_pointer
) = event_hook_by_id
;
1152 * It removes all the requests than can be currently processed by the
1153 * background computation algorithm for all the traces (list_in and list_out).
1155 * Leaves the flag to in_progress or none.. depending if current or queue
1157 * @param module_name A GQuark : the name of the module which computes the
1160 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1164 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1165 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1166 g_assert(trace_v
!= NULL
);
1168 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1169 LttvAttributeValue value
;
1170 GSList
*queue
, *current
;
1173 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1174 LTTV_REQUESTS_QUEUE
,
1177 queue
= (GSList
*)*(value
.v_pointer
);
1180 while(iter
!= NULL
) {
1181 gboolean remove
= FALSE
;
1182 gboolean free_data
= FALSE
;
1184 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1186 if(bg_req
->module_name
== module_name
) {
1194 GSList
*remove_iter
= iter
;
1196 iter
= g_slist_next(iter
);
1197 if(free_data
) g_free(remove_iter
->data
);
1198 queue
= g_slist_remove_link(queue
, remove_iter
);
1199 } else { // not remove
1200 iter
= g_slist_next(iter
);
1205 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1206 LTTV_REQUESTS_CURRENT
,
1209 current
= (GSList
*)*(value
.v_pointer
);
1212 while(iter
!= NULL
) {
1213 gboolean remove
= FALSE
;
1214 gboolean free_data
= FALSE
;
1216 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1218 if(bg_req
->module_name
== module_name
) {
1226 GSList
*remove_iter
= iter
;
1228 iter
= g_slist_next(iter
);
1229 if(free_data
) g_free(remove_iter
->data
);
1230 current
= g_slist_remove_link(current
, remove_iter
);
1231 } else { // not remove
1232 iter
= g_slist_next(iter
);
1240 * Unregister the background computation hooks for a specific module.
1242 * It also removes all the requests than can be currently processed by the
1243 * background computation algorithm for all the traces (list_in and list_out).
1245 * @param module_name A GQuark : the name of the module which computes the
1249 void lttvwindowtraces_unregister_computation_hooks
1250 (LttvAttributeName module_name
)
1252 LttvAttribute
*g_attribute
= lttv_global_attributes();
1253 LttvAttribute
*attribute
;
1255 g_assert(attribute
=
1256 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1257 LTTV_COMPUTATION
)));
1258 g_assert(attribute
=
1259 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1263 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1264 LTTV_EVENT_HOOK_BY_ID
);
1265 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1268 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1269 LTTV_AFTER_REQUEST
);
1270 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1271 LTTV_BEFORE_REQUEST
);
1273 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1274 LTTV_AFTER_CHUNK_TRACEFILE
);
1275 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1276 LTTV_AFTER_CHUNK_TRACE
);
1277 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1278 LTTV_AFTER_CHUNK_TRACESET
);
1280 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1281 LTTV_BEFORE_CHUNK_TRACEFILE
);
1282 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1283 LTTV_BEFORE_CHUNK_TRACE
);
1284 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1285 LTTV_BEFORE_CHUNK_TRACESET
);
1286 /* finally, remove module name */
1287 g_assert(attribute
=
1288 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1289 LTTV_COMPUTATION
)));
1290 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),