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
);
72 g_assert(trace_v
!= NULL
);
74 trace
= lttv_trace(trace_v
);
75 g_assert(trace
!= NULL
);
76 name
= ltt_trace_name(trace
);
78 if(strcmp(name
, path
) == 0) {
87 /* Get a trace by its number identifier */
89 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
91 LttvAttribute
*g_attribute
= lttv_global_attributes();
92 LttvAttribute
*attribute
;
93 LttvAttributeType type
;
94 LttvAttributeName name
;
95 LttvAttributeValue value
;
98 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
101 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
103 if(type
== LTTV_POINTER
) {
104 return (LttvTrace
*)*(value
.v_pointer
);
110 /* Total number of traces */
112 guint
lttvwindowtraces_get_number()
114 LttvAttribute
*g_attribute
= lttv_global_attributes();
115 LttvAttribute
*attribute
;
116 LttvAttributeValue value
;
119 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
122 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
125 /* Add a trace to the global attributes */
127 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
129 LttvAttribute
*g_attribute
= lttv_global_attributes();
130 LttvAttribute
*attribute
;
131 LttvAttributeValue value
;
134 gchar attribute_path
[PATH_MAX
];
136 if(stat(ltt_trace_name(lttv_trace(trace
)), &buf
)) {
137 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
138 ltt_trace_name(lttv_trace(trace
)));
142 snprintf(attribute_path
, PATH_MAX
, "%lu:%lu", buf
.st_dev
, buf
.st_ino
) >= 0);
145 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
148 value
= lttv_attribute_add(attribute
,
149 g_quark_from_string(attribute_path
),
152 *(value
.v_pointer
) = (gpointer
)trace
;
154 /* create new traceset and tracesetcontext */
156 LttvTracesetContext
*tsc
;
158 attribute
= lttv_trace_attribute(trace
);
159 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
160 LTTV_COMPUTATION_TRACESET
,
163 ts
= lttv_traceset_new();
164 *(value
.v_pointer
) = ts
;
166 lttv_traceset_add(ts
,trace
);
168 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
169 LTTV_COMPUTATION_TRACESET_CONTEXT
,
172 tsc
= g_object_new(LTTV_TRACESET_CONTEXT_TYPE
, NULL
);
173 *(value
.v_pointer
) = tsc
;
175 lttv_context_init(tsc
, ts
);
177 value
= lttv_attribute_add(attribute
,
181 value
= lttv_attribute_add(attribute
,
182 LTTV_REQUESTS_CURRENT
,
185 value
= lttv_attribute_add(attribute
,
189 value
= lttv_attribute_add(attribute
,
195 /* Remove a trace from the global attributes */
197 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
199 LttvAttribute
*g_attribute
= lttv_global_attributes();
200 LttvAttribute
*attribute
;
201 LttvAttributeValue value
;
205 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
208 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
209 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
211 g_assert(trace_v
!= NULL
);
213 if(trace_v
== trace
) {
215 LttvAttribute
*l_attribute
;
217 /* create new traceset and tracesetcontext */
219 LttvTracesetContext
*tsc
;
221 l_attribute
= lttv_trace_attribute(trace
);
224 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
225 LTTV_REQUESTS_QUEUE
);
227 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
228 LTTV_REQUESTS_CURRENT
);
230 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
233 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
234 LTTV_NOTIFY_CURRENT
);
236 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
237 LTTV_COMPUTATION_TRACESET
,
240 ts
= (LttvTraceset
*)*(value
.v_pointer
);
242 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
243 LTTV_COMPUTATION_TRACESET_CONTEXT
,
246 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
248 lttv_context_fini(tsc
);
250 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
251 LTTV_COMPUTATION_TRACESET_CONTEXT
);
252 lttv_traceset_destroy(ts
);
253 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
254 LTTV_COMPUTATION_TRACESET
);
256 /* finally, remove the global attribute */
257 lttv_attribute_remove(attribute
, i
);
266 * Function to request data from a specific trace
268 * The memory allocated for the request will be managed by the API.
270 * @param trace the trace to compute
271 * @param module_name the name of the module which registered global computation
275 void lttvwindowtraces_background_request_queue
276 (LttvTrace
*trace
, gchar
*module_name
)
278 BackgroundRequest
*bg_req
;
279 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
280 LttvAttributeValue value
;
284 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
288 slist
= (GSList
**)(value
.v_pointer
);
290 bg_req
= g_new(BackgroundRequest
,1);
291 bg_req
->module_name
= g_quark_from_string(module_name
);
292 bg_req
->trace
= trace
;
294 *slist
= g_slist_append(*slist
, bg_req
);
298 * Remove a background request from a trace.
300 * This should ONLY be used by the modules which registered the global hooks
301 * (module_name). If this is called by the viewers, it may lead to incomplete
302 * and incoherent background processing information.
304 * Even if the module which deals with the hooks removes the background
305 * requests, it may cause a problem if the module gets loaded again in the
306 * session : the data will be partially calculated. The calculation function
307 * must deal with this case correctly.
309 * @param trace the trace to compute
310 * @param module_name the name of the module which registered global computation
314 void lttvwindowtraces_background_request_remove
315 (LttvTrace
*trace
, gchar
*module_name
)
317 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
318 LttvAttributeValue value
;
322 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
326 slist
= (GSList
**)(value
.v_pointer
);
328 for(iter
=*slist
;iter
!=NULL
;) {
329 BackgroundRequest
*bg_req
=
330 (BackgroundRequest
*)iter
->data
;
332 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
333 GSList
*rem_iter
= iter
;
334 iter
=g_slist_next(iter
);
336 *slist
= g_slist_delete_link(*slist
, rem_iter
);
338 iter
=g_slist_next(iter
);
345 * Register a callback to be called when requested data is passed in the next
346 * queued background processing.
348 * @param owner owner of the background notification
349 * @param trace the trace computed
350 * @param notify_time time when notification hooks must be called
351 * @param notify_position position when notification hooks must be called
352 * @param notify Hook to call when the notify position is passed
355 void lttvwindowtraces_background_notify_queue
359 const LttvTracesetContextPosition
*notify_position
,
360 const LttvHooks
*notify
)
362 BackgroundNotify
*bg_notify
;
363 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
364 LttvAttributeValue value
;
367 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
371 slist
= (GSList
**)(value
.v_pointer
);
374 bg_notify
= g_new(BackgroundNotify
,1);
376 bg_notify
->owner
= owner
;
377 bg_notify
->trace
= trace
;
378 bg_notify
->notify_time
= notify_time
;
379 bg_notify
->notify_position
= ltt_traceset_context_position_new();
380 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
382 bg_notify
->notify
= lttv_hooks_new();
383 lttv_hooks_add_list(bg_notify
->notify
, notify
);
385 *slist
= g_slist_append(*slist
, bg_notify
);
389 * Register a callback to be called when requested data is passed in the current
390 * background processing.
392 * @param owner owner of the background notification
393 * @param trace the trace computed
394 * @param notify_time time when notification hooks must be called
395 * @param notify_position position when notification hooks must be called
396 * @param notify Hook to call when the notify position is passed
399 void lttvwindowtraces_background_notify_current
403 const LttvTracesetContextPosition
*notify_position
,
404 const LttvHooks
*notify
)
406 BackgroundNotify
*bg_notify
;
407 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
408 LttvAttributeValue value
;
411 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
415 slist
= (GSList
**)(value
.v_pointer
);
417 bg_notify
= g_new(BackgroundNotify
,1);
419 bg_notify
->owner
= owner
;
420 bg_notify
->trace
= trace
;
421 bg_notify
->notify_time
= notify_time
;
422 bg_notify
->notify_position
= ltt_traceset_context_position_new();
423 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
425 bg_notify
->notify
= lttv_hooks_new();
426 lttv_hooks_add_list(bg_notify
->notify
, notify
);
428 *slist
= g_slist_append(*slist
, bg_notify
);
432 * Removes all the notifications requests from a specific viewer.
434 * @param owner owner of the background notification
437 void lttvwindowtraces_background_notify_remove(gpointer owner
)
441 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
442 LttvAttribute
*attribute
;
443 LttvAttributeValue value
;
444 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
448 g_assert(trace_v
!= NULL
);
450 LttvAttribute
*t_a
= lttv_trace_attribute(trace_v
);
452 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
456 slist
= (GSList
**)(value
.v_pointer
);
458 for(iter
=*slist
;iter
!=NULL
;) {
460 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
462 if(bg_notify
->owner
== owner
) {
463 GSList
*rem_iter
= iter
;
464 iter
=g_slist_next(iter
);
465 lttv_traceset_context_position_destroy(
466 bg_notify
->notify_position
);
467 lttv_hooks_destroy(bg_notify
->notify
);
469 g_slist_remove_link(*slist
, rem_iter
);
471 iter
=g_slist_next(iter
);
475 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
479 slist
= (GSList
**)(value
.v_pointer
);
481 for(iter
=*slist
;iter
!=NULL
;) {
483 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
485 if(bg_notify
->owner
== owner
) {
486 GSList
*rem_iter
= iter
;
487 iter
=g_slist_next(iter
);
488 lttv_traceset_context_position_destroy(
489 bg_notify
->notify_position
);
490 lttv_hooks_destroy(bg_notify
->notify
);
492 g_slist_remove_link(*slist
, rem_iter
);
494 iter
=g_slist_next(iter
);
501 /* Background processing helper functions */
503 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
504 LttvTracesetContext
*tsc
)
506 LttvAttribute
*g_attribute
= lttv_global_attributes();
507 LttvAttribute
*module_attribute
;
508 LttvAttributeType type
;
509 LttvAttributeValue value
;
510 LttvHooks
*before_chunk_traceset
=NULL
;
511 LttvHooks
*before_chunk_trace
=NULL
;
512 LttvHooks
*before_chunk_tracefile
=NULL
;
513 LttvHooks
*event_hook
=NULL
;
514 LttvHooksById
*event_hook_by_id
=NULL
;
517 g_assert(module_attribute
=
518 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
521 g_assert(module_attribute
=
522 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
523 LTTV_IATTRIBUTE(module_attribute
),
526 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
527 LTTV_BEFORE_CHUNK_TRACESET
,
529 if(type
== LTTV_POINTER
) {
530 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
533 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
534 LTTV_BEFORE_CHUNK_TRACE
,
536 if(type
== LTTV_POINTER
) {
537 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
540 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
541 LTTV_BEFORE_CHUNK_TRACEFILE
,
543 if(type
== LTTV_POINTER
) {
544 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
547 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
550 if(type
== LTTV_POINTER
) {
551 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
554 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
555 LTTV_EVENT_HOOK_BY_ID
,
557 if(type
== LTTV_POINTER
) {
558 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
562 lttv_process_traceset_begin(tsc
,
563 before_chunk_traceset
,
565 before_chunk_tracefile
,
571 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
572 LttvTracesetContext
*tsc
)
574 LttvAttribute
*g_attribute
= lttv_global_attributes();
575 LttvAttribute
*module_attribute
;
576 LttvAttributeType type
;
577 LttvAttributeValue value
;
578 LttvHooks
*after_chunk_traceset
=NULL
;
579 LttvHooks
*after_chunk_trace
=NULL
;
580 LttvHooks
*after_chunk_tracefile
=NULL
;
581 LttvHooks
*event_hook
=NULL
;
582 LttvHooksById
*event_hook_by_id
=NULL
;
585 g_assert(module_attribute
=
586 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
589 g_assert(module_attribute
=
590 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
591 LTTV_IATTRIBUTE(module_attribute
),
594 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
595 LTTV_AFTER_CHUNK_TRACESET
,
597 if(type
== LTTV_POINTER
) {
598 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
601 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
602 LTTV_AFTER_CHUNK_TRACE
,
604 if(type
== LTTV_POINTER
) {
605 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
608 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
609 LTTV_AFTER_CHUNK_TRACEFILE
,
611 if(type
== LTTV_POINTER
) {
612 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
615 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
618 if(type
== LTTV_POINTER
) {
619 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
622 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
623 LTTV_EVENT_HOOK_BY_ID
,
625 if(type
== LTTV_POINTER
) {
626 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
630 lttv_process_traceset_end(tsc
,
631 after_chunk_traceset
,
633 after_chunk_tracefile
,
639 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
642 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
643 LttvAttributeValue value
;
646 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
649 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
652 /* the value is left unset. The only presence of the attribute is necessary.
656 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
659 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
662 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
665 lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute
),
669 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
672 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
673 LttvAttributeType type
;
674 LttvAttributeValue value
;
677 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
680 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
683 /* The only presence of the attribute is necessary. */
684 if(type
== LTTV_NONE
)
690 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
693 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
694 LttvAttributeValue value
;
697 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
700 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
703 /* the value is left unset. The only presence of the attribute is necessary.
707 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
710 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
713 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
716 lttv_iattribute_remove(LTTV_IATTRIBUTE(attribute
),
720 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
723 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
724 LttvAttributeType type
;
725 LttvAttributeValue value
;
728 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
731 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
734 /* The only presence of the attribute is necessary. */
735 if(type
== LTTV_NONE
)
743 /* lttvwindowtraces_process_pending_requests
745 * This internal function gets called by g_idle, taking care of the pending
751 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
753 LttvTracesetContext
*tsc
;
755 LttvAttribute
*attribute
;
756 GSList
*list_out
, *list_in
, *notify_in
, *notify_out
;
757 LttvAttributeValue value
;
758 LttvAttributeType type
;
763 attribute
= lttv_trace_attribute(trace
);
765 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
768 g_assert(type
== LTTV_POINTER
);
769 list_out
= (GSList
*)*(value
.v_pointer
);
771 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
772 LTTV_REQUESTS_CURRENT
,
774 g_assert(type
== LTTV_POINTER
);
775 list_in
= (GSList
*)*(value
.v_pointer
);
777 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
780 g_assert(type
== LTTV_POINTER
);
781 notify_out
= (GSList
*)*(value
.v_pointer
);
783 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
786 g_assert(type
== LTTV_POINTER
);
787 notify_in
= (GSList
*)*(value
.v_pointer
);
789 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
790 LTTV_COMPUTATION_TRACESET
,
792 g_assert(type
== LTTV_POINTER
);
793 ts
= (LttvTraceset
*)*(value
.v_pointer
);
795 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
796 LTTV_COMPUTATION_TRACESET_CONTEXT
,
798 g_assert(type
== LTTV_POINTER
);
799 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
800 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
802 /* There is no events requests pending : we should never have been called! */
803 g_assert(g_slist_length(list_out
) != 0 || g_slist_length(list_in
) != 0);
807 /* 1. Before processing */
809 /* if list_in is empty */
810 if(g_slist_length(list_in
) == 0) {
813 /* - Add all requests in list_out to list_in, empty list_out */
814 GSList
*iter
= list_out
;
816 while(iter
!= NULL
) {
817 gboolean remove
= FALSE
;
818 gboolean free_data
= FALSE
;
820 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
824 list_in
= g_slist_append(list_in
, bg_req
);
829 GSList
*remove_iter
= iter
;
831 iter
= g_slist_next(iter
);
832 if(free_data
) g_free(remove_iter
->data
);
833 list_out
= g_slist_remove_link(list_out
, remove_iter
);
834 } else { // not remove
835 iter
= g_slist_next(iter
);
841 GSList
*iter
= list_in
;
842 /* - for each request in list_in */
843 while(iter
!= NULL
) {
845 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
846 /*- add hooks to context*/
847 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
850 iter
= g_slist_next(iter
);
854 /* - seek trace to start */
856 LttTime start
= { 0, 0};
857 lttv_process_traceset_seek_time(tsc
, start
);
860 /* - Move all notifications from notify_out to notify_in. */
862 GSList
*iter
= notify_out
;
863 g_assert(g_slist_length(notify_in
) == 0);
865 while(iter
!= NULL
) {
866 gboolean remove
= FALSE
;
867 gboolean free_data
= FALSE
;
869 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
873 notify_in
= g_slist_append(notify_in
, notify_req
);
878 GSList
*remove_iter
= iter
;
880 iter
= g_slist_next(iter
);
881 if(free_data
) g_free(remove_iter
->data
);
882 notify_out
= g_slist_remove_link(notify_out
, remove_iter
);
883 } else { // not remove
884 iter
= g_slist_next(iter
);
891 GSList
*iter
= list_in
;
892 /* - for each request in list_in */
893 while(iter
!= NULL
) {
895 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
896 /*- Call before chunk hooks for list_in*/
897 /*- add hooks to context*/
898 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
900 iter
= g_slist_next(iter
);
905 /* 2. call process traceset middle for a chunk */
907 /*(assert list_in is not empty! : should not even be called in that case)*/
908 LttTime end
= { G_MAXUINT
, G_MAXUINT
};
909 g_assert(g_slist_length(list_in
) != 0);
911 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
914 /* 3. After the chunk */
916 /* 3.1 call after_chunk hooks for list_in */
918 GSList
*iter
= list_in
;
919 /* - for each request in list_in */
920 while(iter
!= NULL
) {
922 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
923 /* - Call after chunk hooks for list_in */
924 /* - remove hooks from context */
925 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
927 iter
= g_slist_next(iter
);
931 /* 3.2 for each notify_in */
933 GSList
*iter
= notify_in
;
934 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
936 while(iter
!= NULL
) {
937 gboolean remove
= FALSE
;
938 gboolean free_data
= FALSE
;
940 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
942 /* - if current time >= notify time, call notify and remove from
944 * - if current position >= notify position, call notify and remove
948 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) >= 0)
950 (lttv_traceset_context_ctx_pos_compare(tsc
,
951 notify_req
->notify_position
) >= 0)
954 lttv_hooks_call(notify_req
->notify
, notify_req
);
963 GSList
*remove_iter
= iter
;
965 iter
= g_slist_next(iter
);
966 if(free_data
) g_free(remove_iter
->data
);
967 notify_in
= g_slist_remove_link(notify_in
, remove_iter
);
968 } else { // not remove
969 iter
= g_slist_next(iter
);
975 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
976 /* 3.3 if end of trace reached */
977 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
978 tsc
->time_span
.end_time
) > 0) {
980 /* - for each request in list_in */
982 GSList
*iter
= list_in
;
984 while(iter
!= NULL
) {
985 gboolean remove
= FALSE
;
986 gboolean free_data
= FALSE
;
988 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
990 /* - set hooks'in_progress flag to FALSE */
991 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
993 /* - set hooks'ready flag to TRUE */
994 lttvwindowtraces_set_ready(bg_req
->module_name
,
996 /* - remove request */
1003 GSList
*remove_iter
= iter
;
1005 iter
= g_slist_next(iter
);
1006 if(free_data
) g_free(remove_iter
->data
);
1007 list_in
= g_slist_remove_link(list_in
, remove_iter
);
1008 } else { // not remove
1009 iter
= g_slist_next(iter
);
1014 /* - for each notifications in notify_in */
1016 GSList
*iter
= notify_in
;
1018 while(iter
!= NULL
) {
1019 gboolean remove
= FALSE
;
1020 gboolean free_data
= FALSE
;
1022 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1024 /* - call notify and remove from notify_in */
1025 lttv_hooks_call(notify_req
->notify
, notify_req
);
1032 GSList
*remove_iter
= iter
;
1034 iter
= g_slist_next(iter
);
1035 if(free_data
) g_free(remove_iter
->data
);
1036 notify_in
= g_slist_remove_link(notify_in
, remove_iter
);
1037 } else { // not remove
1038 iter
= g_slist_next(iter
);
1043 /* - return FALSE (scheduler stopped) */
1046 /* 3.4 else, end of trace not reached */
1047 /* - return TRUE (scheduler still registered) */
1057 * Register the background computation hooks for a specific module. It adds the
1058 * computation hooks to the global attrubutes, under "computation/module name"
1060 * @param module_name A GQuark : the name of the module which computes the
1063 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1064 LttvHooks
*before_chunk_traceset
,
1065 LttvHooks
*before_chunk_trace
,
1066 LttvHooks
*before_chunk_tracefile
,
1067 LttvHooks
*after_chunk_traceset
,
1068 LttvHooks
*after_chunk_trace
,
1069 LttvHooks
*after_chunk_tracefile
,
1070 LttvHooks
*before_request
,
1071 LttvHooks
*after_request
,
1072 LttvHooks
*event_hook
,
1073 LttvHooksById
*event_hook_by_id
)
1075 LttvAttribute
*g_attribute
= lttv_global_attributes();
1076 LttvAttribute
*attribute
;
1077 LttvAttributeValue value
;
1079 g_assert(attribute
=
1080 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1081 LTTV_COMPUTATION
)));
1083 g_assert(attribute
=
1084 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1087 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1088 LTTV_BEFORE_CHUNK_TRACESET
,
1091 *(value
.v_pointer
) = before_chunk_traceset
;
1093 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1094 LTTV_BEFORE_CHUNK_TRACE
,
1097 *(value
.v_pointer
) = before_chunk_trace
;
1099 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1100 LTTV_BEFORE_CHUNK_TRACEFILE
,
1103 *(value
.v_pointer
) = before_chunk_tracefile
;
1105 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1106 LTTV_AFTER_CHUNK_TRACESET
,
1109 *(value
.v_pointer
) = after_chunk_traceset
;
1111 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1112 LTTV_AFTER_CHUNK_TRACE
,
1115 *(value
.v_pointer
) = after_chunk_trace
;
1117 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1118 LTTV_AFTER_CHUNK_TRACEFILE
,
1121 *(value
.v_pointer
) = after_chunk_tracefile
;
1123 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1124 LTTV_BEFORE_REQUEST
,
1127 *(value
.v_pointer
) = before_request
;
1129 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1133 *(value
.v_pointer
) = after_request
;
1135 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1139 *(value
.v_pointer
) = event_hook
;
1141 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1142 LTTV_EVENT_HOOK_BY_ID
,
1145 *(value
.v_pointer
) = event_hook_by_id
;
1151 * It removes all the requests than can be currently processed by the
1152 * background computation algorithm for all the traces (list_in and list_out).
1154 * Leaves the flag to in_progress or none.. depending if current or queue
1156 * @param module_name A GQuark : the name of the module which computes the
1159 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1163 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1164 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1165 g_assert(trace_v
!= NULL
);
1167 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1168 LttvAttributeValue value
;
1169 GSList
*queue
, *current
;
1172 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1173 LTTV_REQUESTS_QUEUE
,
1176 queue
= (GSList
*)*(value
.v_pointer
);
1179 while(iter
!= NULL
) {
1180 gboolean remove
= FALSE
;
1181 gboolean free_data
= FALSE
;
1183 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1185 if(bg_req
->module_name
== module_name
) {
1193 GSList
*remove_iter
= iter
;
1195 iter
= g_slist_next(iter
);
1196 if(free_data
) g_free(remove_iter
->data
);
1197 queue
= g_slist_remove_link(queue
, remove_iter
);
1198 } else { // not remove
1199 iter
= g_slist_next(iter
);
1204 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1205 LTTV_REQUESTS_CURRENT
,
1208 current
= (GSList
*)*(value
.v_pointer
);
1211 while(iter
!= NULL
) {
1212 gboolean remove
= FALSE
;
1213 gboolean free_data
= FALSE
;
1215 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1217 if(bg_req
->module_name
== module_name
) {
1225 GSList
*remove_iter
= iter
;
1227 iter
= g_slist_next(iter
);
1228 if(free_data
) g_free(remove_iter
->data
);
1229 current
= g_slist_remove_link(current
, remove_iter
);
1230 } else { // not remove
1231 iter
= g_slist_next(iter
);
1239 * Unregister the background computation hooks for a specific module.
1241 * It also removes all the requests than can be currently processed by the
1242 * background computation algorithm for all the traces (list_in and list_out).
1244 * @param module_name A GQuark : the name of the module which computes the
1248 void lttvwindowtraces_unregister_computation_hooks
1249 (LttvAttributeName module_name
)
1251 LttvAttribute
*g_attribute
= lttv_global_attributes();
1252 LttvAttribute
*attribute
;
1254 g_assert(attribute
=
1255 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1256 LTTV_COMPUTATION
)));
1257 g_assert(attribute
=
1258 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1262 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1263 LTTV_EVENT_HOOK_BY_ID
);
1264 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1267 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1268 LTTV_AFTER_REQUEST
);
1269 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1270 LTTV_BEFORE_REQUEST
);
1272 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1273 LTTV_AFTER_CHUNK_TRACEFILE
);
1274 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1275 LTTV_AFTER_CHUNK_TRACE
);
1276 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1277 LTTV_AFTER_CHUNK_TRACESET
);
1279 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1280 LTTV_BEFORE_CHUNK_TRACEFILE
);
1281 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1282 LTTV_BEFORE_CHUNK_TRACE
);
1283 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1284 LTTV_BEFORE_CHUNK_TRACESET
);
1285 /* finally, remove module name */
1286 g_assert(attribute
=
1287 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1288 LTTV_COMPUTATION
)));
1289 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),