1 /* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 /* This file is the API used to launch any background computation on a trace */
21 /* Here is the implementation of the API */
27 #include <sys/types.h>
33 #include <ltt/trace.h>
35 #include <lttv/lttv.h>
36 #include <lttv/traceset.h>
37 #include <lttv/attribute.h>
38 #include <lttv/tracecontext.h>
39 #include <lttvwindow/lttvwindowtraces.h>
40 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
41 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
43 extern GSList
* g_main_window_list
;
45 typedef struct _BackgroundRequest
{
46 LttvAttributeName module_name
; /* Hook path in global attributes,
47 where all standard hooks under computation/.
49 LttvTrace
*trace
; /* trace concerned */
50 GtkWidget
*dialog
; /* Dialog linked with the request, may be NULL */
51 GtkWidget
*parent_window
; /* Parent window the dialog must be transient for */
54 typedef struct _BackgroundNotify
{
56 LttvTrace
*trace
; /* trace */
58 LttvTracesetContextPosition
*notify_position
;
59 LttvHooks
*notify
; /* Hook to call when the notify is
60 passed, or at the end of trace */
66 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
);
68 /* Get a trace by its path name.
70 * @param path path of the trace on the virtual file system.
71 * @return Pointer to trace if found
72 * NULL is returned if the trace is not present
75 __EXPORT LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
79 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
80 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
83 g_assert(trace_v
!= NULL
);
85 trace
= lttv_trace(trace_v
);
86 g_assert(trace
!= NULL
);
87 name
= g_quark_to_string(ltt_trace_name(trace
));
89 if(strcmp(name
, path
) == 0) {
98 /* Get a trace by its number identifier */
100 __EXPORT LttvTrace
*lttvwindowtraces_get_trace(guint num
)
102 LttvAttribute
*g_attribute
= lttv_global_attributes();
103 LttvAttribute
*attribute
;
104 LttvAttributeType type
;
105 LttvAttributeName name
;
106 LttvAttributeValue value
;
110 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
113 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
,
116 if(type
== LTTV_POINTER
) {
117 return (LttvTrace
*)*(value
.v_pointer
);
123 /* Total number of traces */
125 __EXPORT guint
lttvwindowtraces_get_number()
127 LttvAttribute
*g_attribute
= lttv_global_attributes();
128 LttvAttribute
*attribute
;
129 LttvAttributeValue value
;
132 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
135 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
138 /* Add a trace to the global attributes */
140 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
142 LttvAttribute
*g_attribute
= lttv_global_attributes();
143 LttvAttribute
*attribute
;
144 LttvAttributeValue value
;
147 gchar attribute_path
[PATH_MAX
];
149 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace
))), &buf
)) {
150 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
151 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
155 snprintf(attribute_path
, PATH_MAX
, "%llu:%llu", buf
.st_dev
, buf
.st_ino
) >= 0);
158 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
161 value
= lttv_attribute_add(attribute
,
162 g_quark_from_string(attribute_path
),
165 *(value
.v_pointer
) = (gpointer
)trace
;
167 /* create new traceset and tracesetcontext */
169 LttvTracesetStats
*tss
;
170 //LttvTracesetContextPosition *sync_position;
172 attribute
= lttv_trace_attribute(trace
);
173 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
174 LTTV_COMPUTATION_TRACESET
,
177 ts
= lttv_traceset_new();
178 *(value
.v_pointer
) = ts
;
180 lttv_traceset_add(ts
,trace
);
182 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
183 LTTV_COMPUTATION_TRACESET_CONTEXT
,
186 tss
= g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
);
187 *(value
.v_pointer
) = tss
;
189 lttv_context_init(LTTV_TRACESET_CONTEXT(tss
), ts
);
191 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
192 LTTV_COMPUTATION_SYNC_POSITION
,
196 sync_position
= lttv_traceset_context_position_new();
197 *(value
.v_pointer
) = sync_position
;
199 value
= lttv_attribute_add(attribute
,
203 value
= lttv_attribute_add(attribute
,
204 LTTV_REQUESTS_CURRENT
,
207 value
= lttv_attribute_add(attribute
,
211 value
= lttv_attribute_add(attribute
,
216 /* Remove a trace from the global attributes */
218 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
220 LttvAttribute
*g_attribute
= lttv_global_attributes();
221 LttvAttribute
*attribute
;
222 LttvAttributeValue value
;
226 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
229 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
230 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
232 g_assert(trace_v
!= NULL
);
234 /* Remove and background computation that could be in progress */
235 g_idle_remove_by_data(trace_v
);
237 if(trace_v
== trace
) {
239 LttvAttribute
*l_attribute
;
241 /* destroy traceset and tracesetcontext */
243 LttvTracesetStats
*tss
;
244 //LttvTracesetContextPosition *sync_position;
246 l_attribute
= lttv_trace_attribute(trace
);
249 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
250 LTTV_REQUESTS_QUEUE
);
252 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
253 LTTV_REQUESTS_CURRENT
);
255 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
258 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
259 LTTV_NOTIFY_CURRENT
);
261 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
262 LTTV_COMPUTATION_TRACESET
,
265 ts
= (LttvTraceset
*)*(value
.v_pointer
);
267 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
268 LTTV_COMPUTATION_SYNC_POSITION
,
271 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
272 lttv_traceset_context_position_destroy(sync_position
);
274 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
275 LTTV_COMPUTATION_SYNC_POSITION
);
278 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
279 LTTV_COMPUTATION_TRACESET_CONTEXT
,
282 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
284 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
286 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
287 LTTV_COMPUTATION_TRACESET_CONTEXT
);
288 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
289 LTTV_COMPUTATION_TRACESET
);
290 /* Destroy the traceset and the trace also */
291 lttv_traceset_destroy(ts
);
293 /* finally, remove the global attribute */
294 lttv_attribute_remove(attribute
, i
);
301 static void destroy_dialog(BackgroundRequest
*bg_req
)
303 gtk_widget_destroy(bg_req
->dialog
);
304 bg_req
->dialog
= NULL
;
309 * Function to request data from a specific trace
311 * The memory allocated for the request will be managed by the API.
313 * @param widget the current Window
314 * @param trace the trace to compute
315 * @param module_name the name of the module which registered global computation
319 __EXPORT
void lttvwindowtraces_background_request_queue
320 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
322 BackgroundRequest
*bg_req
;
323 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
324 LttvAttribute
*g_attribute
= lttv_global_attributes();
325 LttvAttribute
*module_attribute
;
326 LttvAttributeValue value
;
327 LttvAttributeType type
;
331 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
335 slist
= (GSList
**)(value
.v_pointer
);
337 /* Verify that the calculator is loaded */
338 g_assert(module_attribute
=
339 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
343 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
344 g_quark_from_string(module_name
),
346 if(type
== LTTV_NONE
) {
347 g_critical("Missing background calculator %s", module_name
);
351 bg_req
= g_new(BackgroundRequest
,1);
352 bg_req
->module_name
= g_quark_from_string(module_name
);
353 bg_req
->trace
= trace
;
355 *slist
= g_slist_append(*slist
, bg_req
);
357 /* Priority lower than live servicing */
358 g_idle_remove_by_data(trace
);
359 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
360 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
363 /* FIXME : show message in status bar, need context and message id */
364 g_info("Background computation for %s started for trace %p", module_name
,
367 gtk_message_dialog_new(
369 GTK_DIALOG_DESTROY_WITH_PARENT
,
370 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
371 "Background computation for %s started for trace %s",
373 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
374 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
375 g_signal_connect_swapped (dialog
, "response",
376 G_CALLBACK (destroy_dialog
),
378 bg_req
->dialog
= dialog
;
379 /* the parent window might vanish : only use this pointer for a
380 * comparison with existing windows */
381 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
382 gtk_widget_show(dialog
);
386 * Remove a background request from a trace.
388 * This should ONLY be used by the modules which registered the global hooks
389 * (module_name). If this is called by the viewers, it may lead to incomplete
390 * and incoherent background processing information.
392 * Even if the module which deals with the hooks removes the background
393 * requests, it may cause a problem if the module gets loaded again in the
394 * session : the data will be partially calculated. The calculation function
395 * must deal with this case correctly.
397 * @param trace the trace to compute
398 * @param module_name the name of the module which registered global computation
402 void lttvwindowtraces_background_request_remove
403 (LttvTrace
*trace
, gchar
*module_name
)
405 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
406 LttvAttributeValue value
;
410 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
414 slist
= (GSList
**)(value
.v_pointer
);
416 for(iter
=*slist
;iter
!=NULL
;) {
417 BackgroundRequest
*bg_req
=
418 (BackgroundRequest
*)iter
->data
;
420 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
421 GSList
*rem_iter
= iter
;
422 iter
=g_slist_next(iter
);
424 *slist
= g_slist_delete_link(*slist
, rem_iter
);
426 iter
=g_slist_next(iter
);
432 * Find a background request in a trace
436 __EXPORT gboolean lttvwindowtraces_background_request_find
437 (LttvTrace
*trace
, gchar
*module_name
)
439 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
440 LttvAttributeValue value
;
444 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
448 slist
= (GSList
**)(value
.v_pointer
);
450 for(iter
=*slist
;iter
!=NULL
;) {
451 BackgroundRequest
*bg_req
=
452 (BackgroundRequest
*)iter
->data
;
454 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
457 iter
=g_slist_next(iter
);
464 * Register a callback to be called when requested data is passed in the next
465 * queued background processing.
467 * @param owner owner of the background notification
468 * @param trace the trace computed
469 * @param notify_time time when notification hooks must be called
470 * @param notify_position position when notification hooks must be called
471 * @param notify Hook to call when the notify position is passed
474 __EXPORT
void lttvwindowtraces_background_notify_queue
478 const LttvTracesetContextPosition
*notify_position
,
479 const LttvHooks
*notify
)
481 BackgroundNotify
*bg_notify
;
482 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
483 LttvAttributeValue value
;
486 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
490 slist
= (GSList
**)(value
.v_pointer
);
492 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
493 LTTV_COMPUTATION_TRACESET_CONTEXT
,
496 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
498 bg_notify
= g_new(BackgroundNotify
,1);
500 bg_notify
->owner
= owner
;
501 bg_notify
->trace
= trace
;
502 bg_notify
->notify_time
= notify_time
;
503 if(notify_position
!= NULL
) {
504 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
505 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
508 bg_notify
->notify_position
= NULL
;
511 bg_notify
->notify
= lttv_hooks_new();
512 lttv_hooks_add_list(bg_notify
->notify
, notify
);
514 *slist
= g_slist_append(*slist
, bg_notify
);
518 * Register a callback to be called when requested data is passed in the current
519 * background processing.
521 * @param owner owner of the background notification
522 * @param trace the trace computed
523 * @param notify_time time when notification hooks must be called
524 * @param notify_position position when notification hooks must be called
525 * @param notify Hook to call when the notify position is passed
528 __EXPORT
void lttvwindowtraces_background_notify_current
532 const LttvTracesetContextPosition
*notify_position
,
533 const LttvHooks
*notify
)
535 BackgroundNotify
*bg_notify
;
536 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
537 LttvAttributeValue value
;
540 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
544 slist
= (GSList
**)(value
.v_pointer
);
546 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
547 LTTV_COMPUTATION_TRACESET_CONTEXT
,
550 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
553 bg_notify
= g_new(BackgroundNotify
,1);
555 bg_notify
->owner
= owner
;
556 bg_notify
->trace
= trace
;
557 bg_notify
->notify_time
= notify_time
;
558 if(notify_position
!= NULL
) {
559 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
560 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
563 bg_notify
->notify_position
= NULL
;
565 bg_notify
->notify
= lttv_hooks_new();
566 lttv_hooks_add_list(bg_notify
->notify
, notify
);
568 *slist
= g_slist_append(*slist
, bg_notify
);
572 static void notify_request_free(BackgroundNotify
*notify_req
)
574 if(notify_req
== NULL
) return;
576 if(notify_req
->notify_position
!= NULL
)
577 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
578 if(notify_req
->notify
!= NULL
)
579 lttv_hooks_destroy(notify_req
->notify
);
584 * Removes all the notifications requests from a specific viewer.
586 * @param owner owner of the background notification
589 __EXPORT
void lttvwindowtraces_background_notify_remove(gpointer owner
)
593 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
594 LttvAttribute
*attribute
;
595 LttvAttributeValue value
;
596 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
600 g_assert(trace_v
!= NULL
);
602 attribute
= lttv_trace_attribute(trace_v
);
604 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
608 slist
= (GSList
**)(value
.v_pointer
);
610 for(iter
=*slist
;iter
!=NULL
;) {
612 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
614 if(bg_notify
->owner
== owner
) {
615 GSList
*rem_iter
= iter
;
616 iter
=g_slist_next(iter
);
617 notify_request_free(bg_notify
);
618 *slist
= g_slist_remove_link(*slist
, rem_iter
);
620 iter
=g_slist_next(iter
);
624 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
628 slist
= (GSList
**)(value
.v_pointer
);
630 for(iter
=*slist
;iter
!=NULL
;) {
632 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
634 if(bg_notify
->owner
== owner
) {
635 GSList
*rem_iter
= iter
;
636 iter
=g_slist_next(iter
);
637 notify_request_free(bg_notify
);
638 *slist
= g_slist_remove_link(*slist
, rem_iter
);
640 iter
=g_slist_next(iter
);
647 /* Background processing helper functions */
649 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
650 LttvTracesetContext
*tsc
,
651 LttvHooks
*hook_adder
)
653 LttvAttribute
*g_attribute
= lttv_global_attributes();
654 LttvAttribute
*module_attribute
;
655 LttvAttributeType type
;
656 LttvAttributeValue value
;
659 g_assert(module_attribute
=
660 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
663 g_assert(module_attribute
=
664 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
665 LTTV_IATTRIBUTE(module_attribute
),
668 /* Call the module's hook adder */
669 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
672 if(type
== LTTV_POINTER
) {
673 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
674 if(hook_adder
!= NULL
)
675 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
679 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
680 LttvTracesetContext
*tsc
,
681 LttvHooks
*hook_remover
)
683 LttvAttribute
*g_attribute
= lttv_global_attributes();
684 LttvAttribute
*module_attribute
;
685 LttvAttributeType type
;
686 LttvAttributeValue value
;
688 g_assert(module_attribute
=
689 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
692 g_assert(module_attribute
=
693 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
694 LTTV_IATTRIBUTE(module_attribute
),
697 /* Call the module's hook remover */
698 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
701 if(type
== LTTV_POINTER
) {
702 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
703 if(hook_remover
!= NULL
)
704 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
708 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
709 LttvTracesetContext
*tsc
)
711 LttvAttribute
*g_attribute
= lttv_global_attributes();
712 LttvAttribute
*module_attribute
;
713 LttvAttributeType type
;
714 LttvAttributeValue value
;
715 LttvHooks
*before_chunk_traceset
=NULL
;
716 LttvHooks
*before_chunk_trace
=NULL
;
717 LttvHooks
*before_chunk_tracefile
=NULL
;
718 LttvHooks
*event_hook
=NULL
;
719 LttvHooksById
*event_hook_by_id
=NULL
;
720 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
723 g_assert(module_attribute
=
724 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
727 g_assert(module_attribute
=
728 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
729 LTTV_IATTRIBUTE(module_attribute
),
732 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
733 LTTV_BEFORE_CHUNK_TRACESET
,
735 if(type
== LTTV_POINTER
) {
736 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
739 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
740 LTTV_BEFORE_CHUNK_TRACE
,
742 if(type
== LTTV_POINTER
) {
743 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
746 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
747 LTTV_BEFORE_CHUNK_TRACEFILE
,
749 if(type
== LTTV_POINTER
) {
750 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
753 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
756 if(type
== LTTV_POINTER
) {
757 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
760 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
761 LTTV_EVENT_HOOK_BY_ID
,
763 if(type
== LTTV_POINTER
) {
764 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
767 lttv_process_traceset_begin(tsc
,
768 before_chunk_traceset
,
770 before_chunk_tracefile
,
777 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
778 LttvTracesetContext
*tsc
)
780 LttvAttribute
*g_attribute
= lttv_global_attributes();
781 LttvAttribute
*module_attribute
;
782 LttvAttributeType type
;
783 LttvAttributeValue value
;
784 LttvHooks
*after_chunk_traceset
=NULL
;
785 LttvHooks
*after_chunk_trace
=NULL
;
786 LttvHooks
*after_chunk_tracefile
=NULL
;
787 LttvHooks
*event_hook
=NULL
;
788 LttvHooksById
*event_hook_by_id
=NULL
;
789 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
791 g_assert(module_attribute
=
792 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
795 g_assert(module_attribute
=
796 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
797 LTTV_IATTRIBUTE(module_attribute
),
800 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
801 LTTV_AFTER_CHUNK_TRACESET
,
803 if(type
== LTTV_POINTER
) {
804 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
807 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
808 LTTV_AFTER_CHUNK_TRACE
,
810 if(type
== LTTV_POINTER
) {
811 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
814 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
815 LTTV_AFTER_CHUNK_TRACEFILE
,
817 if(type
== LTTV_POINTER
) {
818 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
821 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
824 if(type
== LTTV_POINTER
) {
825 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
828 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
829 LTTV_EVENT_HOOK_BY_ID
,
831 if(type
== LTTV_POINTER
) {
832 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
835 lttv_process_traceset_end(tsc
,
836 after_chunk_traceset
,
838 after_chunk_tracefile
,
845 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
848 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
849 LttvAttributeValue value
;
852 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
855 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
858 /* the value is left unset. The only presence of the attribute is necessary.
862 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
865 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
868 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
871 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
875 __EXPORT gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
878 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
879 LttvAttributeType type
;
880 LttvAttributeValue value
;
883 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
886 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
889 /* The only presence of the attribute is necessary. */
890 if(type
== LTTV_NONE
)
896 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
899 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
900 LttvAttributeValue value
;
903 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
906 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
909 /* the value is left unset. The only presence of the attribute is necessary.
913 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
916 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
919 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
922 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
926 __EXPORT gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
929 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
930 LttvAttributeType type
;
931 LttvAttributeValue value
;
934 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
937 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
940 /* The only presence of the attribute is necessary. */
941 if(type
== LTTV_NONE
)
947 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
949 if(a
->mwindow
== b
) return 0;
954 /* lttvwindowtraces_process_pending_requests
956 * This internal function gets called by g_idle, taking care of the pending
962 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
964 LttvTracesetContext
*tsc
;
965 LttvTracesetStats
*tss
;
967 //LttvTracesetContextPosition *sync_position;
968 LttvAttribute
*attribute
;
969 LttvAttribute
*g_attribute
= lttv_global_attributes();
970 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
971 LttvAttributeValue value
;
972 LttvAttributeType type
;
978 if(lttvwindow_preempt_count
> 0) return TRUE
;
980 attribute
= lttv_trace_attribute(trace
);
982 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
985 g_assert(type
== LTTV_POINTER
);
986 list_out
= (GSList
**)(value
.v_pointer
);
988 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
989 LTTV_REQUESTS_CURRENT
,
991 g_assert(type
== LTTV_POINTER
);
992 list_in
= (GSList
**)(value
.v_pointer
);
994 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
997 g_assert(type
== LTTV_POINTER
);
998 notify_out
= (GSList
**)(value
.v_pointer
);
1000 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1001 LTTV_NOTIFY_CURRENT
,
1003 g_assert(type
== LTTV_POINTER
);
1004 notify_in
= (GSList
**)(value
.v_pointer
);
1006 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1007 LTTV_COMPUTATION_TRACESET
,
1009 g_assert(type
== LTTV_POINTER
);
1010 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1012 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1013 LTTV_COMPUTATION_TRACESET_CONTEXT
,
1015 g_assert(type
== LTTV_POINTER
);
1016 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
1017 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
1018 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
1019 g_assert(LTTV_IS_TRACESET_STATS(tss
));
1021 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1022 LTTV_COMPUTATION_SYNC_POSITION
,
1024 g_assert(type
== LTTV_POINTER
);
1025 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1027 /* There is no events requests pending : we should never have been called! */
1028 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1029 /* 0.1 Lock traces */
1034 iter_trace
<lttv_traceset_number(tsc
->ts
);
1036 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
1038 if(lttvwindowtraces_lock(trace_v
) != 0)
1039 return TRUE
; /* Cannot get trace lock, try later */
1043 /* 0.2 Sync tracefiles */
1044 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1045 lttv_process_traceset_synchronize_tracefiles(tsc
);
1046 /* 1. Before processing */
1048 /* if list_in is empty */
1049 if(g_slist_length(*list_in
) == 0) {
1052 /* - Add all requests in list_out to list_in, empty list_out */
1053 GSList
*iter
= *list_out
;
1055 while(iter
!= NULL
) {
1056 gboolean remove
= FALSE
;
1057 gboolean free_data
= FALSE
;
1059 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1063 *list_in
= g_slist_append(*list_in
, bg_req
);
1068 GSList
*remove_iter
= iter
;
1070 iter
= g_slist_next(iter
);
1071 if(free_data
) g_free(remove_iter
->data
);
1072 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1073 } else { // not remove
1074 iter
= g_slist_next(iter
);
1080 GSList
*iter
= *list_in
;
1081 /* - for each request in list_in */
1082 while(iter
!= NULL
) {
1084 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1085 /* - set hooks'in_progress flag to TRUE */
1086 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1089 /* - call before request hook */
1090 /* Get before request hook */
1091 LttvAttribute
*module_attribute
;
1093 g_assert(module_attribute
=
1094 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1095 LTTV_IATTRIBUTE(g_attribute
),
1096 LTTV_COMPUTATION
)));
1098 g_assert(module_attribute
=
1099 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1100 LTTV_IATTRIBUTE(module_attribute
),
1101 bg_req
->module_name
)));
1103 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1104 LTTV_BEFORE_REQUEST
,
1106 g_assert(type
== LTTV_POINTER
);
1107 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1109 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1111 iter
= g_slist_next(iter
);
1115 /* - seek trace to start */
1117 LttTime start
= { 0, 0};
1118 lttv_process_traceset_seek_time(tsc
, start
);
1121 /* - Move all notifications from notify_out to notify_in. */
1123 GSList
*iter
= *notify_out
;
1124 g_assert(g_slist_length(*notify_in
) == 0);
1126 while(iter
!= NULL
) {
1127 gboolean remove
= FALSE
;
1128 gboolean free_data
= FALSE
;
1130 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1134 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1139 GSList
*remove_iter
= iter
;
1141 iter
= g_slist_next(iter
);
1143 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1144 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1145 } else { // not remove
1146 iter
= g_slist_next(iter
);
1151 GSList
*iter
= *list_in
;
1152 LttvHooks
*hook_adder
= lttv_hooks_new();
1153 /* - for each request in list_in */
1154 while(iter
!= NULL
) {
1156 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1157 /*- add hooks to context*/
1158 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1161 iter
= g_slist_next(iter
);
1163 lttv_hooks_call(hook_adder
,tsc
);
1164 lttv_hooks_destroy(hook_adder
);
1171 GSList
*iter
= *list_in
;
1172 /* - for each request in list_in */
1173 while(iter
!= NULL
) {
1175 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1176 /*- Call before chunk hooks for list_in*/
1177 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1179 iter
= g_slist_next(iter
);
1184 /* 2. call process traceset middle for a chunk */
1186 /*(assert list_in is not empty! : should not even be called in that case)*/
1187 LttTime end
= ltt_time_infinite
;
1188 g_assert(g_slist_length(*list_in
) != 0);
1190 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1193 /* 3. After the chunk */
1195 /* 3.1 call after_chunk hooks for list_in */
1197 GSList
*iter
= *list_in
;
1198 /* - for each request in list_in */
1199 while(iter
!= NULL
) {
1201 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1202 /* - Call after chunk hooks for list_in */
1203 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1205 iter
= g_slist_next(iter
);
1209 /* 3.2 for each notify_in */
1211 GSList
*iter
= *notify_in
;
1212 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1214 while(iter
!= NULL
) {
1215 gboolean remove
= FALSE
;
1216 gboolean free_data
= FALSE
;
1218 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1220 /* - if current time >= notify time, call notify and remove from
1222 * - if current position >= notify position, call notify and remove
1226 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1228 (notify_req
->notify_position
!= NULL
&&
1229 lttv_traceset_context_ctx_pos_compare(tsc
,
1230 notify_req
->notify_position
) >= 0)
1233 lttv_hooks_call(notify_req
->notify
, notify_req
);
1242 GSList
*remove_iter
= iter
;
1244 iter
= g_slist_next(iter
);
1246 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1247 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1248 } else { // not remove
1249 iter
= g_slist_next(iter
);
1255 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1256 /* 3.3 if end of trace reached */
1258 g_debug("Current time : %lu sec, %lu nsec",
1259 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1260 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1261 tsc
->time_span
.end_time
) > 0) {
1264 GSList
*iter
= *list_in
;
1265 LttvHooks
*hook_remover
= lttv_hooks_new();
1266 /* - for each request in list_in */
1267 while(iter
!= NULL
) {
1269 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1270 /* - remove hooks from context */
1271 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1274 iter
= g_slist_next(iter
);
1276 lttv_hooks_call(hook_remover
,tsc
);
1277 lttv_hooks_destroy(hook_remover
);
1280 /* - for each request in list_in */
1282 GSList
*iter
= *list_in
;
1284 while(iter
!= NULL
) {
1285 gboolean remove
= FALSE
;
1286 gboolean free_data
= FALSE
;
1288 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1290 /* - set hooks'in_progress flag to FALSE */
1291 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1293 /* - set hooks'ready flag to TRUE */
1294 lttvwindowtraces_set_ready(bg_req
->module_name
,
1296 /* - call after request hook */
1297 /* Get after request hook */
1298 LttvAttribute
*module_attribute
;
1300 g_assert(module_attribute
=
1301 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1302 LTTV_IATTRIBUTE(g_attribute
),
1303 LTTV_COMPUTATION
)));
1305 g_assert(module_attribute
=
1306 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1307 LTTV_IATTRIBUTE(module_attribute
),
1308 bg_req
->module_name
)));
1310 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1313 g_assert(type
== LTTV_POINTER
);
1314 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1316 struct sum_traceset_closure t_closure
;
1317 t_closure
.tss
= (LttvTracesetStats
*)tsc
;
1318 t_closure
.current_time
= ltt_time_infinite
;
1319 if(after_request
!= NULL
) lttv_hooks_call(after_request
,
1323 if(bg_req
->dialog
!= NULL
)
1324 gtk_widget_destroy(bg_req
->dialog
);
1325 GtkWidget
*parent_window
;
1326 if(g_slist_find_custom(g_main_window_list
,
1327 bg_req
->parent_window
,
1328 (GCompareFunc
)find_window_widget
))
1329 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1331 parent_window
= NULL
;
1334 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1335 GTK_DIALOG_DESTROY_WITH_PARENT
,
1336 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1337 "Background computation %s finished for trace %s",
1338 g_quark_to_string(bg_req
->module_name
),
1339 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1340 if(parent_window
!= NULL
)
1341 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1342 GTK_WINDOW(parent_window
));
1343 g_signal_connect_swapped (dialog
, "response",
1344 G_CALLBACK (gtk_widget_destroy
),
1346 gtk_widget_show(dialog
);
1348 /* - remove request */
1355 GSList
*remove_iter
= iter
;
1357 iter
= g_slist_next(iter
);
1358 if(free_data
) g_free(remove_iter
->data
);
1359 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1360 } else { // not remove
1361 iter
= g_slist_next(iter
);
1366 /* - for each notifications in notify_in */
1368 GSList
*iter
= *notify_in
;
1370 while(iter
!= NULL
) {
1371 gboolean remove
= FALSE
;
1372 gboolean free_data
= FALSE
;
1374 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1376 /* - call notify and remove from notify_in */
1377 lttv_hooks_call(notify_req
->notify
, notify_req
);
1384 GSList
*remove_iter
= iter
;
1386 iter
= g_slist_next(iter
);
1388 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1389 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1390 } else { // not remove
1391 iter
= g_slist_next(iter
);
1396 /* - reset the context */
1397 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1398 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1400 /* - if list_out is empty */
1401 if(g_slist_length(*list_out
) == 0) {
1402 /* - return FALSE (scheduler stopped) */
1403 g_debug("Background computation scheduler stopped");
1404 g_info("Background computation finished for trace %p", trace
);
1405 /* FIXME : remove status bar info, need context id and message id */
1412 /* 3.4 else, end of trace not reached */
1413 /* - return TRUE (scheduler still registered) */
1414 g_debug("Background computation left");
1419 /* 4. Unlock traces */
1421 lttv_process_traceset_get_sync_data(tsc
);
1422 //lttv_traceset_context_position_save(tsc, sync_position);
1426 iter_trace
<lttv_traceset_number(tsc
->ts
);
1428 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1430 lttvwindowtraces_unlock(trace_v
);
1439 * Register the background computation hooks for a specific module. It adds the
1440 * computation hooks to the global attrubutes, under "computation/module name".
1442 * @param module_name A GQuark : the name of the module which computes the
1445 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1446 LttvHooks
*before_chunk_traceset
,
1447 LttvHooks
*before_chunk_trace
,
1448 LttvHooks
*before_chunk_tracefile
,
1449 LttvHooks
*after_chunk_traceset
,
1450 LttvHooks
*after_chunk_trace
,
1451 LttvHooks
*after_chunk_tracefile
,
1452 LttvHooks
*before_request
,
1453 LttvHooks
*after_request
,
1454 LttvHooks
*event_hook
,
1455 LttvHooksById
*event_hook_by_id
,
1456 LttvHooks
*hook_adder
,
1457 LttvHooks
*hook_remover
)
1459 LttvAttribute
*g_attribute
= lttv_global_attributes();
1460 LttvAttribute
*attribute
;
1461 LttvAttributeValue value
;
1463 g_assert(attribute
=
1464 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1465 LTTV_COMPUTATION
)));
1467 g_assert(attribute
=
1468 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1471 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1472 LTTV_BEFORE_CHUNK_TRACESET
,
1475 *(value
.v_pointer
) = before_chunk_traceset
;
1477 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1478 LTTV_BEFORE_CHUNK_TRACE
,
1481 *(value
.v_pointer
) = before_chunk_trace
;
1483 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1484 LTTV_BEFORE_CHUNK_TRACEFILE
,
1487 *(value
.v_pointer
) = before_chunk_tracefile
;
1489 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1490 LTTV_AFTER_CHUNK_TRACESET
,
1493 *(value
.v_pointer
) = after_chunk_traceset
;
1495 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1496 LTTV_AFTER_CHUNK_TRACE
,
1499 *(value
.v_pointer
) = after_chunk_trace
;
1501 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1502 LTTV_AFTER_CHUNK_TRACEFILE
,
1505 *(value
.v_pointer
) = after_chunk_tracefile
;
1507 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1508 LTTV_BEFORE_REQUEST
,
1511 *(value
.v_pointer
) = before_request
;
1513 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1517 *(value
.v_pointer
) = after_request
;
1519 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1523 *(value
.v_pointer
) = event_hook
;
1525 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1526 LTTV_EVENT_HOOK_BY_ID
,
1529 *(value
.v_pointer
) = event_hook_by_id
;
1531 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1535 *(value
.v_pointer
) = hook_adder
;
1537 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1541 *(value
.v_pointer
) = hook_remover
;
1547 * It removes all the requests than can be currently processed by the
1548 * background computation algorithm for all the traces (list_in and list_out).
1550 * Leaves the flag to in_progress or none.. depending if current or queue
1552 * @param module_name A GQuark : the name of the module which computes the
1555 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1559 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1560 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1561 g_assert(trace_v
!= NULL
);
1563 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1564 LttvAttributeValue value
;
1565 GSList
**queue
, **current
;
1568 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1569 LTTV_REQUESTS_QUEUE
,
1572 queue
= (GSList
**)(value
.v_pointer
);
1575 while(iter
!= NULL
) {
1576 gboolean remove
= FALSE
;
1577 gboolean free_data
= FALSE
;
1579 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1581 if(bg_req
->module_name
== module_name
) {
1589 GSList
*remove_iter
= iter
;
1591 iter
= g_slist_next(iter
);
1592 if(free_data
) g_free(remove_iter
->data
);
1593 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1594 } else { // not remove
1595 iter
= g_slist_next(iter
);
1600 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1601 LTTV_REQUESTS_CURRENT
,
1604 current
= (GSList
**)(value
.v_pointer
);
1607 while(iter
!= NULL
) {
1608 gboolean remove
= FALSE
;
1609 gboolean free_data
= FALSE
;
1611 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1613 if(bg_req
->module_name
== module_name
) {
1621 GSList
*remove_iter
= iter
;
1623 iter
= g_slist_next(iter
);
1624 if(free_data
) g_free(remove_iter
->data
);
1625 *current
= g_slist_remove_link(*current
, remove_iter
);
1626 } else { // not remove
1627 iter
= g_slist_next(iter
);
1635 * Unregister the background computation hooks for a specific module.
1637 * It also removes all the requests than can be currently processed by the
1638 * background computation algorithm for all the traces (list_in and list_out).
1640 * @param module_name A GQuark : the name of the module which computes the
1644 void lttvwindowtraces_unregister_computation_hooks
1645 (LttvAttributeName module_name
)
1647 LttvAttribute
*g_attribute
= lttv_global_attributes();
1648 LttvAttribute
*attribute
;
1649 LttvAttributeValue value
;
1651 g_assert(attribute
=
1652 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1653 LTTV_COMPUTATION
)));
1654 g_assert(attribute
=
1655 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1659 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1660 LTTV_BEFORE_CHUNK_TRACESET
,
1663 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1664 if(before_chunk_traceset
!= NULL
)
1665 lttv_hooks_destroy(before_chunk_traceset
);
1667 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1668 LTTV_BEFORE_CHUNK_TRACE
,
1671 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1672 if(before_chunk_trace
!= NULL
)
1673 lttv_hooks_destroy(before_chunk_trace
);
1675 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1676 LTTV_BEFORE_CHUNK_TRACEFILE
,
1679 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1680 if(before_chunk_tracefile
!= NULL
)
1681 lttv_hooks_destroy(before_chunk_tracefile
);
1683 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1684 LTTV_AFTER_CHUNK_TRACESET
,
1687 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1688 if(after_chunk_traceset
!= NULL
)
1689 lttv_hooks_destroy(after_chunk_traceset
);
1691 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1692 LTTV_AFTER_CHUNK_TRACE
,
1695 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1696 if(after_chunk_trace
!= NULL
)
1697 lttv_hooks_destroy(after_chunk_trace
);
1699 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1700 LTTV_AFTER_CHUNK_TRACEFILE
,
1703 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1704 if(after_chunk_tracefile
!= NULL
)
1705 lttv_hooks_destroy(after_chunk_tracefile
);
1707 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1708 LTTV_BEFORE_REQUEST
,
1711 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1712 if(before_request
!= NULL
)
1713 lttv_hooks_destroy(before_request
);
1715 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1719 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1720 if(after_request
!= NULL
)
1721 lttv_hooks_destroy(after_request
);
1723 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1727 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1728 if(event_hook
!= NULL
)
1729 lttv_hooks_destroy(event_hook
);
1731 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1732 LTTV_EVENT_HOOK_BY_ID
,
1735 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1736 if(event_hook_by_id
!= NULL
)
1737 lttv_hooks_by_id_destroy(event_hook_by_id
);
1739 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1743 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1744 if(hook_adder
!= NULL
)
1745 lttv_hooks_destroy(hook_adder
);
1747 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1751 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1752 if(hook_remover
!= NULL
)
1753 lttv_hooks_destroy(hook_remover
);
1756 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1757 LTTV_EVENT_HOOK_BY_ID
);
1758 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1761 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1762 LTTV_AFTER_REQUEST
);
1763 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1764 LTTV_BEFORE_REQUEST
);
1766 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1767 LTTV_AFTER_CHUNK_TRACEFILE
);
1768 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1769 LTTV_AFTER_CHUNK_TRACE
);
1770 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1771 LTTV_AFTER_CHUNK_TRACESET
);
1773 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1774 LTTV_BEFORE_CHUNK_TRACEFILE
);
1775 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1776 LTTV_BEFORE_CHUNK_TRACE
);
1777 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1778 LTTV_BEFORE_CHUNK_TRACESET
);
1779 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1781 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1784 /* finally, remove module name */
1785 g_assert(attribute
=
1786 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1787 LTTV_COMPUTATION
)));
1788 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1794 * Lock a trace so no other instance can use it.
1796 * @param trace The trace to lock.
1797 * @return 0 on success, -1 if cannot get lock.
1799 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1801 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1802 LttvAttributeValue value
;
1803 LttvAttributeType type
;
1805 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1808 /* Verify the absence of the lock. */
1809 if(type
!= LTTV_NONE
) {
1810 g_critical("Cannot take trace lock");
1814 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1817 /* the value is left unset. The only presence of the attribute is necessary.
1826 * @param trace The trace to unlock.
1827 * @return 0 on success, -1 if cannot unlock (not locked ?).
1829 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1831 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1832 LttvAttributeType type
;
1833 LttvAttributeValue value
;
1835 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1838 /* Verify the presence of the lock. */
1839 if(type
== LTTV_NONE
) {
1840 g_critical("Cannot release trace lock");
1844 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1851 * Verify if a trace is locked.
1853 * @param trace The trace to verify.
1854 * @return TRUE if locked, FALSE is unlocked.
1856 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1858 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1859 LttvAttributeType type
;
1860 LttvAttributeValue value
;
1862 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1865 /* The only presence of the attribute is necessary. */
1866 if(type
== LTTV_NONE
)