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 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 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 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
,
217 /* Remove a trace from the global attributes */
219 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
221 LttvAttribute
*g_attribute
= lttv_global_attributes();
222 LttvAttribute
*attribute
;
223 LttvAttributeValue value
;
227 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
230 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
231 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
233 g_assert(trace_v
!= NULL
);
235 /* Remove and background computation that could be in progress */
236 g_idle_remove_by_data(trace_v
);
238 if(trace_v
== trace
) {
240 LttvAttribute
*l_attribute
;
242 /* destroy traceset and tracesetcontext */
244 LttvTracesetStats
*tss
;
245 //LttvTracesetContextPosition *sync_position;
247 l_attribute
= lttv_trace_attribute(trace
);
250 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
251 LTTV_REQUESTS_QUEUE
);
253 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
254 LTTV_REQUESTS_CURRENT
);
256 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
259 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
260 LTTV_NOTIFY_CURRENT
);
262 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
263 LTTV_COMPUTATION_TRACESET
,
266 ts
= (LttvTraceset
*)*(value
.v_pointer
);
268 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
269 LTTV_COMPUTATION_SYNC_POSITION
,
272 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
273 lttv_traceset_context_position_destroy(sync_position
);
275 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
276 LTTV_COMPUTATION_SYNC_POSITION
);
279 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute
),
280 LTTV_COMPUTATION_TRACESET_CONTEXT
,
283 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
285 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss
));
287 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
288 LTTV_COMPUTATION_TRACESET_CONTEXT
);
289 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute
),
290 LTTV_COMPUTATION_TRACESET
);
291 /* Destroy the traceset and the trace also */
292 lttv_traceset_destroy(ts
);
294 /* finally, remove the global attribute */
295 lttv_attribute_remove(attribute
, i
);
302 static void destroy_dialog(BackgroundRequest
*bg_req
)
304 gtk_widget_destroy(bg_req
->dialog
);
305 bg_req
->dialog
= NULL
;
310 * Function to request data from a specific trace
312 * The memory allocated for the request will be managed by the API.
314 * @param widget the current Window
315 * @param trace the trace to compute
316 * @param module_name the name of the module which registered global computation
320 void lttvwindowtraces_background_request_queue
321 (GtkWidget
*widget
, LttvTrace
*trace
, gchar
*module_name
)
323 BackgroundRequest
*bg_req
;
324 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
325 LttvAttribute
*g_attribute
= lttv_global_attributes();
326 LttvAttribute
*module_attribute
;
327 LttvAttributeValue value
;
328 LttvAttributeType type
;
332 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
336 slist
= (GSList
**)(value
.v_pointer
);
338 /* Verify that the calculator is loaded */
339 g_assert(module_attribute
=
340 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
344 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
345 g_quark_from_string(module_name
),
347 if(type
== LTTV_NONE
) {
348 g_critical("Missing background calculator %s", module_name
);
352 bg_req
= g_new(BackgroundRequest
,1);
353 bg_req
->module_name
= g_quark_from_string(module_name
);
354 bg_req
->trace
= trace
;
356 *slist
= g_slist_append(*slist
, bg_req
);
358 /* Priority lower than live servicing */
359 g_idle_remove_by_data(trace
);
360 g_idle_add_full((G_PRIORITY_HIGH_IDLE
+ 23),
361 (GSourceFunc
)lttvwindowtraces_process_pending_requests
,
364 /* FIXME : show message in status bar, need context and message id */
365 g_info("Background computation for %s started for trace %p", module_name
,
368 gtk_message_dialog_new(
370 GTK_DIALOG_DESTROY_WITH_PARENT
,
371 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
372 "Background computation for %s started for trace %s",
374 g_quark_to_string(ltt_trace_name(lttv_trace(trace
))));
375 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(widget
));
376 g_signal_connect_swapped (dialog
, "response",
377 G_CALLBACK (destroy_dialog
),
379 bg_req
->dialog
= dialog
;
380 /* the parent window might vanish : only use this pointer for a
381 * comparison with existing windows */
382 bg_req
->parent_window
= gtk_widget_get_toplevel(widget
);
383 gtk_widget_show(dialog
);
387 * Remove a background request from a trace.
389 * This should ONLY be used by the modules which registered the global hooks
390 * (module_name). If this is called by the viewers, it may lead to incomplete
391 * and incoherent background processing information.
393 * Even if the module which deals with the hooks removes the background
394 * requests, it may cause a problem if the module gets loaded again in the
395 * session : the data will be partially calculated. The calculation function
396 * must deal with this case correctly.
398 * @param trace the trace to compute
399 * @param module_name the name of the module which registered global computation
403 void lttvwindowtraces_background_request_remove
404 (LttvTrace
*trace
, gchar
*module_name
)
406 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
407 LttvAttributeValue value
;
411 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
415 slist
= (GSList
**)(value
.v_pointer
);
417 for(iter
=*slist
;iter
!=NULL
;) {
418 BackgroundRequest
*bg_req
=
419 (BackgroundRequest
*)iter
->data
;
421 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
422 GSList
*rem_iter
= iter
;
423 iter
=g_slist_next(iter
);
425 *slist
= g_slist_delete_link(*slist
, rem_iter
);
427 iter
=g_slist_next(iter
);
433 * Find a background request in a trace
437 gboolean lttvwindowtraces_background_request_find
438 (LttvTrace
*trace
, gchar
*module_name
)
440 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
441 LttvAttributeValue value
;
445 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
449 slist
= (GSList
**)(value
.v_pointer
);
451 for(iter
=*slist
;iter
!=NULL
;) {
452 BackgroundRequest
*bg_req
=
453 (BackgroundRequest
*)iter
->data
;
455 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
458 iter
=g_slist_next(iter
);
465 * Register a callback to be called when requested data is passed in the next
466 * queued background processing.
468 * @param owner owner of the background notification
469 * @param trace the trace computed
470 * @param notify_time time when notification hooks must be called
471 * @param notify_position position when notification hooks must be called
472 * @param notify Hook to call when the notify position is passed
475 void lttvwindowtraces_background_notify_queue
479 const LttvTracesetContextPosition
*notify_position
,
480 const LttvHooks
*notify
)
482 BackgroundNotify
*bg_notify
;
483 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
484 LttvAttributeValue value
;
487 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
491 slist
= (GSList
**)(value
.v_pointer
);
493 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
494 LTTV_COMPUTATION_TRACESET_CONTEXT
,
497 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
499 bg_notify
= g_new(BackgroundNotify
,1);
501 bg_notify
->owner
= owner
;
502 bg_notify
->trace
= trace
;
503 bg_notify
->notify_time
= notify_time
;
504 if(notify_position
!= NULL
) {
505 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
506 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
509 bg_notify
->notify_position
= NULL
;
512 bg_notify
->notify
= lttv_hooks_new();
513 lttv_hooks_add_list(bg_notify
->notify
, notify
);
515 *slist
= g_slist_append(*slist
, bg_notify
);
519 * Register a callback to be called when requested data is passed in the current
520 * background processing.
522 * @param owner owner of the background notification
523 * @param trace the trace computed
524 * @param notify_time time when notification hooks must be called
525 * @param notify_position position when notification hooks must be called
526 * @param notify Hook to call when the notify position is passed
529 void lttvwindowtraces_background_notify_current
533 const LttvTracesetContextPosition
*notify_position
,
534 const LttvHooks
*notify
)
536 BackgroundNotify
*bg_notify
;
537 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
538 LttvAttributeValue value
;
541 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
545 slist
= (GSList
**)(value
.v_pointer
);
547 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
548 LTTV_COMPUTATION_TRACESET_CONTEXT
,
551 LttvTracesetContext
*tsc
= (LttvTracesetContext
*)(value
.v_pointer
);
554 bg_notify
= g_new(BackgroundNotify
,1);
556 bg_notify
->owner
= owner
;
557 bg_notify
->trace
= trace
;
558 bg_notify
->notify_time
= notify_time
;
559 if(notify_position
!= NULL
) {
560 bg_notify
->notify_position
= lttv_traceset_context_position_new(tsc
);
561 lttv_traceset_context_position_copy(bg_notify
->notify_position
,
564 bg_notify
->notify_position
= NULL
;
566 bg_notify
->notify
= lttv_hooks_new();
567 lttv_hooks_add_list(bg_notify
->notify
, notify
);
569 *slist
= g_slist_append(*slist
, bg_notify
);
573 static void notify_request_free(BackgroundNotify
*notify_req
)
575 if(notify_req
== NULL
) return;
577 if(notify_req
->notify_position
!= NULL
)
578 lttv_traceset_context_position_destroy(notify_req
->notify_position
);
579 if(notify_req
->notify
!= NULL
)
580 lttv_hooks_destroy(notify_req
->notify
);
585 * Removes all the notifications requests from a specific viewer.
587 * @param owner owner of the background notification
590 void lttvwindowtraces_background_notify_remove(gpointer owner
)
594 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
595 LttvAttribute
*attribute
;
596 LttvAttributeValue value
;
597 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
601 g_assert(trace_v
!= NULL
);
603 attribute
= lttv_trace_attribute(trace_v
);
605 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
609 slist
= (GSList
**)(value
.v_pointer
);
611 for(iter
=*slist
;iter
!=NULL
;) {
613 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
615 if(bg_notify
->owner
== owner
) {
616 GSList
*rem_iter
= iter
;
617 iter
=g_slist_next(iter
);
618 notify_request_free(bg_notify
);
619 *slist
= g_slist_remove_link(*slist
, rem_iter
);
621 iter
=g_slist_next(iter
);
625 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
629 slist
= (GSList
**)(value
.v_pointer
);
631 for(iter
=*slist
;iter
!=NULL
;) {
633 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
635 if(bg_notify
->owner
== owner
) {
636 GSList
*rem_iter
= iter
;
637 iter
=g_slist_next(iter
);
638 notify_request_free(bg_notify
);
639 *slist
= g_slist_remove_link(*slist
, rem_iter
);
641 iter
=g_slist_next(iter
);
648 /* Background processing helper functions */
650 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name
,
651 LttvTracesetContext
*tsc
,
652 LttvHooks
*hook_adder
)
654 LttvAttribute
*g_attribute
= lttv_global_attributes();
655 LttvAttribute
*module_attribute
;
656 LttvAttributeType type
;
657 LttvAttributeValue value
;
660 g_assert(module_attribute
=
661 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
664 g_assert(module_attribute
=
665 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
666 LTTV_IATTRIBUTE(module_attribute
),
669 /* Call the module's hook adder */
670 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
673 if(type
== LTTV_POINTER
) {
674 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
675 if(hook_adder
!= NULL
)
676 lttv_hooks_add_list(hook_adder
, (LttvHooks
*)*(value
.v_pointer
));
680 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name
,
681 LttvTracesetContext
*tsc
,
682 LttvHooks
*hook_remover
)
684 LttvAttribute
*g_attribute
= lttv_global_attributes();
685 LttvAttribute
*module_attribute
;
686 LttvAttributeType type
;
687 LttvAttributeValue value
;
689 g_assert(module_attribute
=
690 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
693 g_assert(module_attribute
=
694 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
695 LTTV_IATTRIBUTE(module_attribute
),
698 /* Call the module's hook remover */
699 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
702 if(type
== LTTV_POINTER
) {
703 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
704 if(hook_remover
!= NULL
)
705 lttv_hooks_add_list(hook_remover
, (LttvHooks
*)*(value
.v_pointer
));
709 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name
,
710 LttvTracesetContext
*tsc
)
712 LttvAttribute
*g_attribute
= lttv_global_attributes();
713 LttvAttribute
*module_attribute
;
714 LttvAttributeType type
;
715 LttvAttributeValue value
;
716 LttvHooks
*before_chunk_traceset
=NULL
;
717 LttvHooks
*before_chunk_trace
=NULL
;
718 LttvHooks
*before_chunk_tracefile
=NULL
;
719 LttvHooks
*event_hook
=NULL
;
720 LttvHooksById
*event_hook_by_id
=NULL
;
721 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
724 g_assert(module_attribute
=
725 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
728 g_assert(module_attribute
=
729 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
730 LTTV_IATTRIBUTE(module_attribute
),
733 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
734 LTTV_BEFORE_CHUNK_TRACESET
,
736 if(type
== LTTV_POINTER
) {
737 before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
740 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
741 LTTV_BEFORE_CHUNK_TRACE
,
743 if(type
== LTTV_POINTER
) {
744 before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
747 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
748 LTTV_BEFORE_CHUNK_TRACEFILE
,
750 if(type
== LTTV_POINTER
) {
751 before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
754 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
757 if(type
== LTTV_POINTER
) {
758 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
761 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
762 LTTV_EVENT_HOOK_BY_ID
,
764 if(type
== LTTV_POINTER
) {
765 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
768 lttv_process_traceset_begin(tsc
,
769 before_chunk_traceset
,
771 before_chunk_tracefile
,
778 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name
,
779 LttvTracesetContext
*tsc
)
781 LttvAttribute
*g_attribute
= lttv_global_attributes();
782 LttvAttribute
*module_attribute
;
783 LttvAttributeType type
;
784 LttvAttributeValue value
;
785 LttvHooks
*after_chunk_traceset
=NULL
;
786 LttvHooks
*after_chunk_trace
=NULL
;
787 LttvHooks
*after_chunk_tracefile
=NULL
;
788 LttvHooks
*event_hook
=NULL
;
789 LttvHooksById
*event_hook_by_id
=NULL
;
790 LttvTracesetStats
*tss
= LTTV_TRACESET_STATS(tsc
);
792 g_assert(module_attribute
=
793 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
796 g_assert(module_attribute
=
797 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
798 LTTV_IATTRIBUTE(module_attribute
),
801 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
802 LTTV_AFTER_CHUNK_TRACESET
,
804 if(type
== LTTV_POINTER
) {
805 after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
808 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
809 LTTV_AFTER_CHUNK_TRACE
,
811 if(type
== LTTV_POINTER
) {
812 after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
815 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
816 LTTV_AFTER_CHUNK_TRACEFILE
,
818 if(type
== LTTV_POINTER
) {
819 after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
822 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
825 if(type
== LTTV_POINTER
) {
826 event_hook
= (LttvHooks
*)*(value
.v_pointer
);
829 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
830 LTTV_EVENT_HOOK_BY_ID
,
832 if(type
== LTTV_POINTER
) {
833 event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
836 lttv_process_traceset_end(tsc
,
837 after_chunk_traceset
,
839 after_chunk_tracefile
,
846 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name
,
849 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
850 LttvAttributeValue value
;
853 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
856 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
859 /* the value is left unset. The only presence of the attribute is necessary.
863 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name
,
866 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
869 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
876 gboolean
lttvwindowtraces_get_in_progress(LttvAttributeName module_name
,
879 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
880 LttvAttributeType type
;
881 LttvAttributeValue value
;
884 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
887 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
890 /* The only presence of the attribute is necessary. */
891 if(type
== LTTV_NONE
)
897 void lttvwindowtraces_set_ready(LttvAttributeName module_name
,
900 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
901 LttvAttributeValue value
;
904 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
907 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
910 /* the value is left unset. The only presence of the attribute is necessary.
914 void lttvwindowtraces_unset_ready(LttvAttributeName module_name
,
917 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
920 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
923 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
927 gboolean
lttvwindowtraces_get_ready(LttvAttributeName module_name
,
930 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
931 LttvAttributeType type
;
932 LttvAttributeValue value
;
935 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
938 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
941 /* The only presence of the attribute is necessary. */
942 if(type
== LTTV_NONE
)
948 static gint
find_window_widget(MainWindow
*a
, GtkWidget
*b
)
950 if(a
->mwindow
== b
) return 0;
955 /* lttvwindowtraces_process_pending_requests
957 * This internal function gets called by g_idle, taking care of the pending
963 gboolean
lttvwindowtraces_process_pending_requests(LttvTrace
*trace
)
965 LttvTracesetContext
*tsc
;
966 LttvTracesetStats
*tss
;
968 //LttvTracesetContextPosition *sync_position;
969 LttvAttribute
*attribute
;
970 LttvAttribute
*g_attribute
= lttv_global_attributes();
971 GSList
**list_out
, **list_in
, **notify_in
, **notify_out
;
972 LttvAttributeValue value
;
973 LttvAttributeType type
;
979 if(lttvwindow_preempt_count
> 0) return TRUE
;
981 attribute
= lttv_trace_attribute(trace
);
983 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
986 g_assert(type
== LTTV_POINTER
);
987 list_out
= (GSList
**)(value
.v_pointer
);
989 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
990 LTTV_REQUESTS_CURRENT
,
992 g_assert(type
== LTTV_POINTER
);
993 list_in
= (GSList
**)(value
.v_pointer
);
995 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
998 g_assert(type
== LTTV_POINTER
);
999 notify_out
= (GSList
**)(value
.v_pointer
);
1001 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1002 LTTV_NOTIFY_CURRENT
,
1004 g_assert(type
== LTTV_POINTER
);
1005 notify_in
= (GSList
**)(value
.v_pointer
);
1007 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1008 LTTV_COMPUTATION_TRACESET
,
1010 g_assert(type
== LTTV_POINTER
);
1011 ts
= (LttvTraceset
*)*(value
.v_pointer
);
1013 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1014 LTTV_COMPUTATION_TRACESET_CONTEXT
,
1016 g_assert(type
== LTTV_POINTER
);
1017 tsc
= (LttvTracesetContext
*)*(value
.v_pointer
);
1018 tss
= (LttvTracesetStats
*)*(value
.v_pointer
);
1019 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc
));
1020 g_assert(LTTV_IS_TRACESET_STATS(tss
));
1022 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1023 LTTV_COMPUTATION_SYNC_POSITION
,
1025 g_assert(type
== LTTV_POINTER
);
1026 sync_position
= (LttvTracesetContextPosition
*)*(value
.v_pointer
);
1028 /* There is no events requests pending : we should never have been called! */
1029 g_assert(g_slist_length(*list_out
) != 0 || g_slist_length(*list_in
) != 0);
1030 /* 0.1 Lock traces */
1035 iter_trace
<lttv_traceset_number(tsc
->ts
);
1037 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
,iter_trace
);
1039 if(lttvwindowtraces_lock(trace_v
) != 0)
1040 return TRUE
; /* Cannot get trace lock, try later */
1044 /* 0.2 Sync tracefiles */
1045 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1046 lttv_process_traceset_synchronize_tracefiles(tsc
);
1047 /* 1. Before processing */
1049 /* if list_in is empty */
1050 if(g_slist_length(*list_in
) == 0) {
1053 /* - Add all requests in list_out to list_in, empty list_out */
1054 GSList
*iter
= *list_out
;
1056 while(iter
!= NULL
) {
1057 gboolean remove
= FALSE
;
1058 gboolean free_data
= FALSE
;
1060 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1064 *list_in
= g_slist_append(*list_in
, bg_req
);
1069 GSList
*remove_iter
= iter
;
1071 iter
= g_slist_next(iter
);
1072 if(free_data
) g_free(remove_iter
->data
);
1073 *list_out
= g_slist_remove_link(*list_out
, remove_iter
);
1074 } else { // not remove
1075 iter
= g_slist_next(iter
);
1081 GSList
*iter
= *list_in
;
1082 /* - for each request in list_in */
1083 while(iter
!= NULL
) {
1085 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1086 /* - set hooks'in_progress flag to TRUE */
1087 lttvwindowtraces_set_in_progress(bg_req
->module_name
,
1090 /* - call before request hook */
1091 /* Get before request hook */
1092 LttvAttribute
*module_attribute
;
1094 g_assert(module_attribute
=
1095 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1096 LTTV_IATTRIBUTE(g_attribute
),
1097 LTTV_COMPUTATION
)));
1099 g_assert(module_attribute
=
1100 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1101 LTTV_IATTRIBUTE(module_attribute
),
1102 bg_req
->module_name
)));
1104 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1105 LTTV_BEFORE_REQUEST
,
1107 g_assert(type
== LTTV_POINTER
);
1108 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1110 if(before_request
!= NULL
) lttv_hooks_call(before_request
, tsc
);
1112 iter
= g_slist_next(iter
);
1116 /* - seek trace to start */
1118 LttTime start
= { 0, 0};
1119 lttv_process_traceset_seek_time(tsc
, start
);
1122 /* - Move all notifications from notify_out to notify_in. */
1124 GSList
*iter
= *notify_out
;
1125 g_assert(g_slist_length(*notify_in
) == 0);
1127 while(iter
!= NULL
) {
1128 gboolean remove
= FALSE
;
1129 gboolean free_data
= FALSE
;
1131 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1135 *notify_in
= g_slist_append(*notify_in
, notify_req
);
1140 GSList
*remove_iter
= iter
;
1142 iter
= g_slist_next(iter
);
1144 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1145 *notify_out
= g_slist_remove_link(*notify_out
, remove_iter
);
1146 } else { // not remove
1147 iter
= g_slist_next(iter
);
1152 GSList
*iter
= *list_in
;
1153 LttvHooks
*hook_adder
= lttv_hooks_new();
1154 /* - for each request in list_in */
1155 while(iter
!= NULL
) {
1157 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1158 /*- add hooks to context*/
1159 lttvwindowtraces_add_computation_hooks(bg_req
->module_name
,
1162 iter
= g_slist_next(iter
);
1164 lttv_hooks_call(hook_adder
,tsc
);
1165 lttv_hooks_destroy(hook_adder
);
1172 GSList
*iter
= *list_in
;
1173 /* - for each request in list_in */
1174 while(iter
!= NULL
) {
1176 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1177 /*- Call before chunk hooks for list_in*/
1178 lttvwindowtraces_call_before_chunk(bg_req
->module_name
,
1180 iter
= g_slist_next(iter
);
1185 /* 2. call process traceset middle for a chunk */
1187 /*(assert list_in is not empty! : should not even be called in that case)*/
1188 LttTime end
= ltt_time_infinite
;
1189 g_assert(g_slist_length(*list_in
) != 0);
1191 lttv_process_traceset_middle(tsc
, end
, CHUNK_NUM_EVENTS
, NULL
);
1194 /* 3. After the chunk */
1196 /* 3.1 call after_chunk hooks for list_in */
1198 GSList
*iter
= *list_in
;
1199 /* - for each request in list_in */
1200 while(iter
!= NULL
) {
1202 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1203 /* - Call after chunk hooks for list_in */
1204 lttvwindowtraces_call_after_chunk(bg_req
->module_name
,
1206 iter
= g_slist_next(iter
);
1210 /* 3.2 for each notify_in */
1212 GSList
*iter
= *notify_in
;
1213 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1215 while(iter
!= NULL
) {
1216 gboolean remove
= FALSE
;
1217 gboolean free_data
= FALSE
;
1219 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1221 /* - if current time >= notify time, call notify and remove from
1223 * - if current position >= notify position, call notify and remove
1227 ltt_time_compare(notify_req
->notify_time
, tfc
->timestamp
) <= 0)
1229 (notify_req
->notify_position
!= NULL
&&
1230 lttv_traceset_context_ctx_pos_compare(tsc
,
1231 notify_req
->notify_position
) >= 0)
1234 lttv_hooks_call(notify_req
->notify
, notify_req
);
1243 GSList
*remove_iter
= iter
;
1245 iter
= g_slist_next(iter
);
1247 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1248 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1249 } else { // not remove
1250 iter
= g_slist_next(iter
);
1256 LttvTracefileContext
*tfc
= lttv_traceset_context_get_current_tfc(tsc
);
1257 /* 3.3 if end of trace reached */
1259 g_debug("Current time : %lu sec, %lu nsec",
1260 tfc
->timestamp
.tv_sec
, tfc
->timestamp
.tv_nsec
);
1261 if(tfc
== NULL
|| ltt_time_compare(tfc
->timestamp
,
1262 tsc
->time_span
.end_time
) > 0) {
1265 GSList
*iter
= *list_in
;
1266 LttvHooks
*hook_remover
= lttv_hooks_new();
1267 /* - for each request in list_in */
1268 while(iter
!= NULL
) {
1270 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1271 /* - remove hooks from context */
1272 lttvwindowtraces_remove_computation_hooks(bg_req
->module_name
,
1275 iter
= g_slist_next(iter
);
1277 lttv_hooks_call(hook_remover
,tsc
);
1278 lttv_hooks_destroy(hook_remover
);
1281 /* - for each request in list_in */
1283 GSList
*iter
= *list_in
;
1285 while(iter
!= NULL
) {
1286 gboolean remove
= FALSE
;
1287 gboolean free_data
= FALSE
;
1289 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1291 /* - set hooks'in_progress flag to FALSE */
1292 lttvwindowtraces_unset_in_progress(bg_req
->module_name
,
1294 /* - set hooks'ready flag to TRUE */
1295 lttvwindowtraces_set_ready(bg_req
->module_name
,
1297 /* - call after request hook */
1298 /* Get after request hook */
1299 LttvAttribute
*module_attribute
;
1301 g_assert(module_attribute
=
1302 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1303 LTTV_IATTRIBUTE(g_attribute
),
1304 LTTV_COMPUTATION
)));
1306 g_assert(module_attribute
=
1307 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1308 LTTV_IATTRIBUTE(module_attribute
),
1309 bg_req
->module_name
)));
1311 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute
),
1314 g_assert(type
== LTTV_POINTER
);
1315 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1317 if(after_request
!= NULL
) lttv_hooks_call(after_request
, tsc
);
1319 if(bg_req
->dialog
!= NULL
)
1320 gtk_widget_destroy(bg_req
->dialog
);
1321 GtkWidget
*parent_window
;
1322 if(g_slist_find_custom(g_main_window_list
,
1323 bg_req
->parent_window
,
1324 (GCompareFunc
)find_window_widget
))
1325 parent_window
= GTK_WIDGET(bg_req
->parent_window
);
1327 parent_window
= NULL
;
1330 gtk_message_dialog_new(GTK_WINDOW(parent_window
),
1331 GTK_DIALOG_DESTROY_WITH_PARENT
,
1332 GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1333 "Background computation %s finished for trace %s",
1334 g_quark_to_string(bg_req
->module_name
),
1335 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req
->trace
))));
1336 if(parent_window
!= NULL
)
1337 gtk_window_set_transient_for(GTK_WINDOW(dialog
),
1338 GTK_WINDOW(parent_window
));
1339 g_signal_connect_swapped (dialog
, "response",
1340 G_CALLBACK (gtk_widget_destroy
),
1342 gtk_widget_show(dialog
);
1344 /* - remove request */
1351 GSList
*remove_iter
= iter
;
1353 iter
= g_slist_next(iter
);
1354 if(free_data
) g_free(remove_iter
->data
);
1355 *list_in
= g_slist_remove_link(*list_in
, remove_iter
);
1356 } else { // not remove
1357 iter
= g_slist_next(iter
);
1362 /* - for each notifications in notify_in */
1364 GSList
*iter
= *notify_in
;
1366 while(iter
!= NULL
) {
1367 gboolean remove
= FALSE
;
1368 gboolean free_data
= FALSE
;
1370 BackgroundNotify
*notify_req
= (BackgroundNotify
*)iter
->data
;
1372 /* - call notify and remove from notify_in */
1373 lttv_hooks_call(notify_req
->notify
, notify_req
);
1380 GSList
*remove_iter
= iter
;
1382 iter
= g_slist_next(iter
);
1384 notify_request_free((BackgroundNotify
*)remove_iter
->data
);
1385 *notify_in
= g_slist_remove_link(*notify_in
, remove_iter
);
1386 } else { // not remove
1387 iter
= g_slist_next(iter
);
1392 /* - reset the context */
1393 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->fini(tsc
);
1394 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc
)->init(tsc
,ts
);
1396 /* - if list_out is empty */
1397 if(g_slist_length(*list_out
) == 0) {
1398 /* - return FALSE (scheduler stopped) */
1399 g_debug("Background computation scheduler stopped");
1400 g_info("Background computation finished for trace %p", trace
);
1401 /* FIXME : remove status bar info, need context id and message id */
1408 /* 3.4 else, end of trace not reached */
1409 /* - return TRUE (scheduler still registered) */
1410 g_debug("Background computation left");
1415 /* 4. Unlock traces */
1417 lttv_process_traceset_get_sync_data(tsc
);
1418 //lttv_traceset_context_position_save(tsc, sync_position);
1422 iter_trace
<lttv_traceset_number(tsc
->ts
);
1424 LttvTrace
*trace_v
= lttv_traceset_get(tsc
->ts
, iter_trace
);
1426 lttvwindowtraces_unlock(trace_v
);
1435 * Register the background computation hooks for a specific module. It adds the
1436 * computation hooks to the global attrubutes, under "computation/module name".
1438 * @param module_name A GQuark : the name of the module which computes the
1441 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name
,
1442 LttvHooks
*before_chunk_traceset
,
1443 LttvHooks
*before_chunk_trace
,
1444 LttvHooks
*before_chunk_tracefile
,
1445 LttvHooks
*after_chunk_traceset
,
1446 LttvHooks
*after_chunk_trace
,
1447 LttvHooks
*after_chunk_tracefile
,
1448 LttvHooks
*before_request
,
1449 LttvHooks
*after_request
,
1450 LttvHooks
*event_hook
,
1451 LttvHooksById
*event_hook_by_id
,
1452 LttvHooks
*hook_adder
,
1453 LttvHooks
*hook_remover
)
1455 LttvAttribute
*g_attribute
= lttv_global_attributes();
1456 LttvAttribute
*attribute
;
1457 LttvAttributeValue value
;
1459 g_assert(attribute
=
1460 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1461 LTTV_COMPUTATION
)));
1463 g_assert(attribute
=
1464 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1467 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1468 LTTV_BEFORE_CHUNK_TRACESET
,
1471 *(value
.v_pointer
) = before_chunk_traceset
;
1473 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1474 LTTV_BEFORE_CHUNK_TRACE
,
1477 *(value
.v_pointer
) = before_chunk_trace
;
1479 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1480 LTTV_BEFORE_CHUNK_TRACEFILE
,
1483 *(value
.v_pointer
) = before_chunk_tracefile
;
1485 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1486 LTTV_AFTER_CHUNK_TRACESET
,
1489 *(value
.v_pointer
) = after_chunk_traceset
;
1491 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1492 LTTV_AFTER_CHUNK_TRACE
,
1495 *(value
.v_pointer
) = after_chunk_trace
;
1497 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1498 LTTV_AFTER_CHUNK_TRACEFILE
,
1501 *(value
.v_pointer
) = after_chunk_tracefile
;
1503 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1504 LTTV_BEFORE_REQUEST
,
1507 *(value
.v_pointer
) = before_request
;
1509 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1513 *(value
.v_pointer
) = after_request
;
1515 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1519 *(value
.v_pointer
) = event_hook
;
1521 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1522 LTTV_EVENT_HOOK_BY_ID
,
1525 *(value
.v_pointer
) = event_hook_by_id
;
1527 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1531 *(value
.v_pointer
) = hook_adder
;
1533 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1537 *(value
.v_pointer
) = hook_remover
;
1543 * It removes all the requests than can be currently processed by the
1544 * background computation algorithm for all the traces (list_in and list_out).
1546 * Leaves the flag to in_progress or none.. depending if current or queue
1548 * @param module_name A GQuark : the name of the module which computes the
1551 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name
)
1555 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
1556 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
1557 g_assert(trace_v
!= NULL
);
1559 LttvAttribute
*attribute
= lttv_trace_attribute(trace_v
);
1560 LttvAttributeValue value
;
1561 GSList
**queue
, **current
;
1564 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1565 LTTV_REQUESTS_QUEUE
,
1568 queue
= (GSList
**)(value
.v_pointer
);
1571 while(iter
!= NULL
) {
1572 gboolean remove
= FALSE
;
1573 gboolean free_data
= FALSE
;
1575 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1577 if(bg_req
->module_name
== module_name
) {
1585 GSList
*remove_iter
= iter
;
1587 iter
= g_slist_next(iter
);
1588 if(free_data
) g_free(remove_iter
->data
);
1589 *queue
= g_slist_remove_link(*queue
, remove_iter
);
1590 } else { // not remove
1591 iter
= g_slist_next(iter
);
1596 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1597 LTTV_REQUESTS_CURRENT
,
1600 current
= (GSList
**)(value
.v_pointer
);
1603 while(iter
!= NULL
) {
1604 gboolean remove
= FALSE
;
1605 gboolean free_data
= FALSE
;
1607 BackgroundRequest
*bg_req
= (BackgroundRequest
*)iter
->data
;
1609 if(bg_req
->module_name
== module_name
) {
1617 GSList
*remove_iter
= iter
;
1619 iter
= g_slist_next(iter
);
1620 if(free_data
) g_free(remove_iter
->data
);
1621 *current
= g_slist_remove_link(*current
, remove_iter
);
1622 } else { // not remove
1623 iter
= g_slist_next(iter
);
1631 * Unregister the background computation hooks for a specific module.
1633 * It also removes all the requests than can be currently processed by the
1634 * background computation algorithm for all the traces (list_in and list_out).
1636 * @param module_name A GQuark : the name of the module which computes the
1640 void lttvwindowtraces_unregister_computation_hooks
1641 (LttvAttributeName module_name
)
1643 LttvAttribute
*g_attribute
= lttv_global_attributes();
1644 LttvAttribute
*attribute
;
1645 LttvAttributeValue value
;
1647 g_assert(attribute
=
1648 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1649 LTTV_COMPUTATION
)));
1650 g_assert(attribute
=
1651 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute
),
1655 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1656 LTTV_BEFORE_CHUNK_TRACESET
,
1659 LttvHooks
*before_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1660 if(before_chunk_traceset
!= NULL
)
1661 lttv_hooks_destroy(before_chunk_traceset
);
1663 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1664 LTTV_BEFORE_CHUNK_TRACE
,
1667 LttvHooks
*before_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1668 if(before_chunk_trace
!= NULL
)
1669 lttv_hooks_destroy(before_chunk_trace
);
1671 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1672 LTTV_BEFORE_CHUNK_TRACEFILE
,
1675 LttvHooks
*before_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1676 if(before_chunk_tracefile
!= NULL
)
1677 lttv_hooks_destroy(before_chunk_tracefile
);
1679 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1680 LTTV_AFTER_CHUNK_TRACESET
,
1683 LttvHooks
*after_chunk_traceset
= (LttvHooks
*)*(value
.v_pointer
);
1684 if(after_chunk_traceset
!= NULL
)
1685 lttv_hooks_destroy(after_chunk_traceset
);
1687 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1688 LTTV_AFTER_CHUNK_TRACE
,
1691 LttvHooks
*after_chunk_trace
= (LttvHooks
*)*(value
.v_pointer
);
1692 if(after_chunk_trace
!= NULL
)
1693 lttv_hooks_destroy(after_chunk_trace
);
1695 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1696 LTTV_AFTER_CHUNK_TRACEFILE
,
1699 LttvHooks
*after_chunk_tracefile
= (LttvHooks
*)*(value
.v_pointer
);
1700 if(after_chunk_tracefile
!= NULL
)
1701 lttv_hooks_destroy(after_chunk_tracefile
);
1703 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1704 LTTV_BEFORE_REQUEST
,
1707 LttvHooks
*before_request
= (LttvHooks
*)*(value
.v_pointer
);
1708 if(before_request
!= NULL
)
1709 lttv_hooks_destroy(before_request
);
1711 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1715 LttvHooks
*after_request
= (LttvHooks
*)*(value
.v_pointer
);
1716 if(after_request
!= NULL
)
1717 lttv_hooks_destroy(after_request
);
1719 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1723 LttvHooks
*event_hook
= (LttvHooks
*)*(value
.v_pointer
);
1724 if(event_hook
!= NULL
)
1725 lttv_hooks_destroy(event_hook
);
1727 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1728 LTTV_EVENT_HOOK_BY_ID
,
1731 LttvHooksById
*event_hook_by_id
= (LttvHooksById
*)*(value
.v_pointer
);
1732 if(event_hook_by_id
!= NULL
)
1733 lttv_hooks_by_id_destroy(event_hook_by_id
);
1735 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1739 LttvHooks
*hook_adder
= (LttvHooks
*)*(value
.v_pointer
);
1740 if(hook_adder
!= NULL
)
1741 lttv_hooks_destroy(hook_adder
);
1743 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
1747 LttvHooks
*hook_remover
= (LttvHooks
*)*(value
.v_pointer
);
1748 if(hook_remover
!= NULL
)
1749 lttv_hooks_destroy(hook_remover
);
1752 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1753 LTTV_EVENT_HOOK_BY_ID
);
1754 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1757 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1758 LTTV_AFTER_REQUEST
);
1759 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1760 LTTV_BEFORE_REQUEST
);
1762 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1763 LTTV_AFTER_CHUNK_TRACEFILE
);
1764 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1765 LTTV_AFTER_CHUNK_TRACE
);
1766 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1767 LTTV_AFTER_CHUNK_TRACESET
);
1769 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1770 LTTV_BEFORE_CHUNK_TRACEFILE
);
1771 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1772 LTTV_BEFORE_CHUNK_TRACE
);
1773 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1774 LTTV_BEFORE_CHUNK_TRACESET
);
1775 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1777 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1780 /* finally, remove module name */
1781 g_assert(attribute
=
1782 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
1783 LTTV_COMPUTATION
)));
1784 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1790 * Lock a trace so no other instance can use it.
1792 * @param trace The trace to lock.
1793 * @return 0 on success, -1 if cannot get lock.
1795 gint
lttvwindowtraces_lock(LttvTrace
*trace
)
1797 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1798 LttvAttributeValue value
;
1799 LttvAttributeType type
;
1801 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1804 /* Verify the absence of the lock. */
1805 if(type
!= LTTV_NONE
) {
1806 g_critical("Cannot take trace lock");
1810 value
= lttv_iattribute_add(LTTV_IATTRIBUTE(attribute
),
1813 /* the value is left unset. The only presence of the attribute is necessary.
1822 * @param trace The trace to unlock.
1823 * @return 0 on success, -1 if cannot unlock (not locked ?).
1825 gint
lttvwindowtraces_unlock(LttvTrace
*trace
)
1827 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1828 LttvAttributeType type
;
1829 LttvAttributeValue value
;
1831 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1834 /* Verify the presence of the lock. */
1835 if(type
== LTTV_NONE
) {
1836 g_critical("Cannot release trace lock");
1840 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute
),
1847 * Verify if a trace is locked.
1849 * @param trace The trace to verify.
1850 * @return TRUE if locked, FALSE is unlocked.
1852 gint
lttvwindowtraces_get_lock_state(LttvTrace
*trace
)
1854 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
1855 LttvAttributeType type
;
1856 LttvAttributeValue value
;
1858 type
= lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute
),
1861 /* The only presence of the attribute is necessary. */
1862 if(type
== LTTV_NONE
)