Remove more warnings in the GUI modules
[lttv.git] / lttv / modules / gui / lttvwindow / lttvwindow / lttvwindowtraces.c
1 /* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
3 *
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;
7 *
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.
12 *
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,
16 * MA 02111-1307, USA.
17 */
18
19 /* This file is the API used to launch any background computation on a trace */
20
21 /* Here is the implementation of the API */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <inttypes.h>
32
33 #include <glib.h>
34 #include <lttv/lttv.h>
35 #include <lttv/traceset.h>
36 #include <lttv/attribute.h>
37 #include <lttvwindow/lttvwindowtraces.h>
38 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
39 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
40
41 extern GSList * g_main_window_list;
42
43 typedef struct _BackgroundRequest {
44 LttvAttributeName module_name; /* Hook path in global attributes,
45 where all standard hooks under computation/.
46 i.e. modulename */
47 LttvTrace *trace; /* trace concerned */
48 GtkWidget *dialog; /* Dialog linked with the request, may be NULL */
49 GtkWidget *parent_window; /* Parent window the dialog must be transient for */
50 } BackgroundRequest;
51
52 typedef struct _BackgroundNotify {
53 gpointer owner;
54 LttvTrace *trace; /* trace */
55 LttTime notify_time;
56 LttvTracesetPosition *notify_position;
57 LttvHooks *notify; /* Hook to call when the notify is
58 passed, or at the end of trace */
59 } BackgroundNotify;
60
61
62
63 /* Prototypes */
64 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
65
66 /* Get a trace by its path name.
67 *
68 * @param path path of the trace on the virtual file system.
69 * @return Pointer to trace if found
70 * NULL is returned if the trace is not present
71 */
72
73 __EXPORT LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
74 {
75 #ifdef BABEL_CLEANUP
76 guint i;
77
78 for(i=0;i<lttvwindowtraces_get_number();i++) {
79 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
80 LttTrace *trace;
81 const gchar *name;
82 g_assert(trace_v != NULL);
83
84 trace = lttv_trace(trace_v);
85 g_assert(trace != NULL);
86 name = g_quark_to_string(ltt_trace_name(trace));
87
88 if(strcmp(name, path) == 0) {
89 /* Found */
90 return trace_v;
91 }
92 }
93 #endif
94 return NULL;
95 }
96
97 /* Get a trace by its number identifier */
98
99 __EXPORT LttvTrace *lttvwindowtraces_get_trace(guint num)
100 {
101 LttvAttribute *g_attribute = lttv_global_attributes();
102 LttvAttribute *attribute;
103 LttvAttributeType type;
104 LttvAttributeName name;
105 LttvAttributeValue value;
106 gboolean is_named;
107
108 attribute =
109 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
110 LTTV_TRACES));
111 g_assert(attribute);
112
113 type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value,
114 &is_named);
115
116 if(type == LTTV_POINTER) {
117 return (LttvTrace *)*(value.v_pointer);
118 }
119
120 return NULL;
121 }
122
123 /* Total number of traces */
124
125 __EXPORT guint lttvwindowtraces_get_number()
126 {
127 LttvAttribute *g_attribute = lttv_global_attributes();
128 LttvAttribute *attribute;
129
130 attribute =
131 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
132 LTTV_TRACES));
133 g_assert(attribute);
134
135 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute)) );
136 }
137
138 /* Add a trace to the global attributes */
139
140 void lttvwindowtraces_add_trace(LttvTrace *trace)
141 {
142
143 LttvAttribute *attribute;
144 #ifdef BABEL_CLEANUP
145
146 LttvAttribute *g_attribute = lttv_global_attributes();
147 struct stat buf;
148 gchar attribute_path[PATH_MAX];
149 int result;
150 gboolean result_b;
151 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace))), &buf)) {
152 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
153 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
154 return;
155 }
156 result = snprintf(attribute_path, PATH_MAX, "%" PRIu64 ":%" PRIu64,
157 buf.st_dev, buf.st_ino);
158 g_assert(result >= 0);
159
160 attribute =
161 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
162 LTTV_TRACES));
163 g_assert(attribute);
164
165 value = lttv_attribute_add(attribute,
166 g_quark_from_string(attribute_path),
167 LTTV_POINTER);
168
169 *(value.v_pointer) = (gpointer)trace;
170
171 /* create new traceset and tracesetcontext */
172 LttvTraceset *ts;
173 LttvTracesetStats *tss;
174 //LttvTracesetContextPosition *sync_position;
175
176 attribute = lttv_trace_attribute(trace);
177 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
178 LTTV_COMPUTATION_TRACESET,
179 LTTV_POINTER,
180 &value);
181 g_assert(result_b);
182
183 ts = lttv_traceset_new();
184 *(value.v_pointer) = ts;
185
186 lttv_traceset_add(ts,trace);
187
188 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
189 LTTV_COMPUTATION_TRACESET_CONTEXT,
190 LTTV_POINTER,
191 &value);
192 g_assert(result_b);
193
194 tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
195 *(value.v_pointer) = tss;
196
197 lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
198 #endif
199 #if 0
200 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
201 LTTV_COMPUTATION_SYNC_POSITION,
202 LTTV_POINTER,
203 &value);
204 g_assert(result_b);
205
206 sync_position = lttv_traceset_context_position_new();
207 *(value.v_pointer) = sync_position;
208 #endif //0
209 lttv_attribute_add(attribute,
210 LTTV_REQUESTS_QUEUE,
211 LTTV_POINTER);
212
213 lttv_attribute_add(attribute,
214 LTTV_REQUESTS_CURRENT,
215 LTTV_POINTER);
216
217 lttv_attribute_add(attribute,
218 LTTV_NOTIFY_QUEUE,
219 LTTV_POINTER);
220
221 lttv_attribute_add(attribute,
222 LTTV_NOTIFY_CURRENT,
223 LTTV_POINTER);
224 }
225
226 /* Remove a trace from the global attributes */
227
228 void lttvwindowtraces_remove_trace(LttvTrace *trace)
229 {
230 LttvAttribute *g_attribute = lttv_global_attributes();
231 LttvAttribute *attribute;
232 LttvAttributeValue value;
233 guint i;
234 gboolean result;
235
236 attribute =
237 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
238 LTTV_TRACES));
239 g_assert(attribute);
240
241 for(i=0;i<lttvwindowtraces_get_number();i++) {
242 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
243
244 g_assert(trace_v != NULL);
245
246 /* Remove and background computation that could be in progress */
247 g_idle_remove_by_data(trace_v);
248
249 if(trace_v == trace) {
250 /* Found */
251 LttvAttribute *l_attribute;
252
253 /* destroy traceset and tracesetcontext */
254 LttvTraceset *ts;
255 //LttvTracesetContextPosition *sync_position;
256
257 l_attribute = lttv_trace_attribute(trace);
258
259
260 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
261 LTTV_REQUESTS_QUEUE);
262
263 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
264 LTTV_REQUESTS_CURRENT);
265
266 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
267 LTTV_NOTIFY_QUEUE);
268
269 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
270 LTTV_NOTIFY_CURRENT);
271
272 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
273 LTTV_COMPUTATION_TRACESET,
274 LTTV_POINTER,
275 &value);
276 g_assert(result);
277
278 ts = (LttvTraceset*)*(value.v_pointer);
279 #if 0
280 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
281 LTTV_COMPUTATION_SYNC_POSITION,
282 LTTV_POINTER,
283 &value);
284 g_assert(result);
285
286 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
287 lttv_traceset_context_position_destroy(sync_position);
288
289 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
290 LTTV_COMPUTATION_SYNC_POSITION);
291
292 #endif //0
293 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
294 LTTV_COMPUTATION_TRACESET_CONTEXT,
295 LTTV_POINTER,
296 &value);
297 g_assert(result);
298 #ifdef BABEL_CLEANUP
299 tss = (LttvTracesetStats*)*(value.v_pointer);
300
301 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
302 g_object_unref(tss);
303 #endif /* BABEL_CLEANUP */
304 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
305 LTTV_COMPUTATION_TRACESET_CONTEXT);
306 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
307 LTTV_COMPUTATION_TRACESET);
308 /* Destroy the traceset and the trace also */
309 lttv_traceset_destroy(ts);
310
311 /* finally, remove the global attribute */
312 lttv_attribute_remove(attribute, i);
313
314 return;
315 }
316 }
317 }
318
319 static void destroy_dialog(BackgroundRequest *bg_req)
320 {
321 gtk_widget_destroy(bg_req->dialog);
322 bg_req->dialog = NULL;
323 }
324
325
326 /**
327 * Function to request data from a specific trace
328 *
329 * The memory allocated for the request will be managed by the API.
330 *
331 * @param widget the current Window
332 * @param trace the trace to compute
333 * @param module_name the name of the module which registered global computation
334 * hooks.
335 */
336
337 __EXPORT void lttvwindowtraces_background_request_queue
338 (GtkWidget *widget, LttvTrace *trace, gchar *module_name)
339 {
340 BackgroundRequest *bg_req;
341 LttvAttribute *attribute = lttv_trace_attribute(trace);
342 LttvAttribute *g_attribute = lttv_global_attributes();
343 LttvAttribute *module_attribute;
344 LttvAttributeValue value;
345 LttvAttributeType type;
346 GSList **slist;
347 gboolean result;
348
349 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
350 LTTV_REQUESTS_QUEUE,
351 LTTV_POINTER,
352 &value);
353 g_assert(result);
354
355 slist = (GSList**)(value.v_pointer);
356
357 /* Verify that the calculator is loaded */
358 module_attribute =
359 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
360 LTTV_COMPUTATION));
361 g_assert(module_attribute);
362
363 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
364 g_quark_from_string(module_name),
365 &value);
366 if(type == LTTV_NONE) {
367 g_critical("Missing background calculator %s", module_name);
368 return;
369 }
370
371 bg_req = g_new(BackgroundRequest,1);
372 bg_req->module_name = g_quark_from_string(module_name);
373 bg_req->trace = trace;
374
375 *slist = g_slist_append(*slist, bg_req);
376
377 /* Priority lower than live servicing */
378 g_idle_remove_by_data(trace);
379 g_idle_add_full((G_PRIORITY_HIGH_IDLE + 23),
380 (GSourceFunc)lttvwindowtraces_process_pending_requests,
381 trace,
382 NULL);
383 /* FIXME : show message in status bar, need context and message id */
384 g_info("Background computation for %s started for trace %p", module_name,
385 trace);
386 GtkWidget *dialog =
387 gtk_message_dialog_new(
388 GTK_WINDOW(widget),
389 GTK_DIALOG_DESTROY_WITH_PARENT,
390 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
391 "Background computation for %s started for trace %s",
392 module_name,
393 trace->traceset->filename);
394 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(widget));
395 g_signal_connect_swapped (dialog, "response",
396 G_CALLBACK (destroy_dialog),
397 bg_req);
398 bg_req->dialog = dialog;
399 /* the parent window might vanish : only use this pointer for a
400 * comparison with existing windows */
401 bg_req->parent_window = gtk_widget_get_toplevel(widget);
402 gtk_widget_show(dialog);
403 }
404
405 /**
406 * Remove a background request from a trace.
407 *
408 * This should ONLY be used by the modules which registered the global hooks
409 * (module_name). If this is called by the viewers, it may lead to incomplete
410 * and incoherent background processing information.
411 *
412 * Even if the module which deals with the hooks removes the background
413 * requests, it may cause a problem if the module gets loaded again in the
414 * session : the data will be partially calculated. The calculation function
415 * must deal with this case correctly.
416 *
417 * @param trace the trace to compute
418 * @param module_name the name of the module which registered global computation
419 * hooks.
420 */
421
422 void lttvwindowtraces_background_request_remove
423 (LttvTrace *trace, gchar *module_name)
424 {
425 LttvAttribute *attribute = lttv_trace_attribute(trace);
426 LttvAttributeValue value;
427 GSList *iter = NULL;
428 GSList **slist;
429 gboolean result;
430
431 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
432 LTTV_REQUESTS_QUEUE,
433 LTTV_POINTER,
434 &value);
435 g_assert(result);
436
437 slist = (GSList**)(value.v_pointer);
438
439 for(iter=*slist;iter!=NULL;) {
440 BackgroundRequest *bg_req =
441 (BackgroundRequest *)iter->data;
442
443 if(bg_req->module_name == g_quark_from_string(module_name)) {
444 GSList *rem_iter = iter;
445 iter=g_slist_next(iter);
446 g_free(bg_req);
447 *slist = g_slist_delete_link(*slist, rem_iter);
448 } else {
449 iter=g_slist_next(iter);
450 }
451 }
452 }
453
454 /**
455 * Find a background request in a trace
456 *
457 */
458
459 __EXPORT gboolean lttvwindowtraces_background_request_find
460 (LttvTrace *trace, gchar *module_name)
461 {
462 LttvAttribute *attribute = lttv_trace_attribute(trace);
463 LttvAttributeValue value;
464 GSList *iter = NULL;
465 GSList **slist;
466 gboolean result;
467
468 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
469 LTTV_REQUESTS_QUEUE,
470 LTTV_POINTER,
471 &value);
472 g_assert(result);
473
474 slist = (GSList**)(value.v_pointer);
475
476 for(iter=*slist;iter!=NULL;) {
477 BackgroundRequest *bg_req =
478 (BackgroundRequest *)iter->data;
479
480 if(bg_req->module_name == g_quark_from_string(module_name)) {
481 return TRUE;
482 } else {
483 iter=g_slist_next(iter);
484 }
485 }
486 return FALSE;
487 }
488
489 /**
490 * Register a callback to be called when requested data is passed in the next
491 * queued background processing.
492 *
493 * @param owner owner of the background notification
494 * @param trace the trace computed
495 * @param notify_time time when notification hooks must be called
496 * @param notify_position position when notification hooks must be called
497 * @param notify Hook to call when the notify position is passed
498 */
499
500 __EXPORT void lttvwindowtraces_background_notify_queue
501 (gpointer owner,
502 LttvTrace *trace,
503 LttTime notify_time,
504 const LttvTracesetPosition *notify_position,
505 const LttvHooks *notify)
506 {
507 #ifdef BABEL_CLEANUP
508 BackgroundNotify *bg_notify;
509 LttvAttribute *attribute = lttv_trace_attribute(trace);
510 LttvAttributeValue value;
511 GSList **slist;
512 gboolean result;
513
514 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
515 LTTV_NOTIFY_QUEUE,
516 LTTV_POINTER,
517 &value);
518 g_assert(result);
519
520 slist = (GSList**)(value.v_pointer);
521
522 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
523 LTTV_COMPUTATION_TRACESET_CONTEXT,
524 LTTV_POINTER,
525 &value);
526 g_assert(result);
527
528 LttvTraceset *ts = (LttvTraceset)(value.v_pointer);
529
530 bg_notify = g_new(BackgroundNotify,1);
531
532 bg_notify->owner = owner;
533 bg_notify->trace = trace;
534 bg_notify->notify_time = notify_time;
535 if(notify_position != NULL) {
536 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
537 lttv_traceset_context_position_copy(bg_notify->notify_position,
538 notify_position);
539 } else {
540 bg_notify->notify_position = NULL;
541 }
542
543 bg_notify->notify = lttv_hooks_new();
544 lttv_hooks_add_list(bg_notify->notify, notify);
545
546 *slist = g_slist_append(*slist, bg_notify);
547 #endif /* BABEL_CLEANUP*/
548 }
549
550 /**
551 * Register a callback to be called when requested data is passed in the current
552 * background processing.
553 *
554 * @param owner owner of the background notification
555 * @param trace the trace computed
556 * @param notify_time time when notification hooks must be called
557 * @param notify_position position when notification hooks must be called
558 * @param notify Hook to call when the notify position is passed
559 */
560
561 __EXPORT void lttvwindowtraces_background_notify_current
562 (gpointer owner,
563 LttvTrace *trace,
564 LttTime notify_time,
565 const LttvTracesetPosition *notify_position,
566 const LttvHooks *notify)
567 {
568 #ifdef BABEL_CLEANUP
569 BackgroundNotify *bg_notify;
570 LttvAttribute *attribute = lttv_trace_attribute(trace);
571 LttvAttributeValue value;
572 GSList **slist;
573 gboolean result;
574
575 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
576 LTTV_NOTIFY_CURRENT,
577 LTTV_POINTER,
578 &value);
579 g_assert(result);
580
581 slist = (GSList**)(value.v_pointer);
582
583 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
584 LTTV_COMPUTATION_TRACESET_CONTEXT,
585 LTTV_POINTER,
586 &value);
587 g_assert(result);
588
589 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
590
591
592 bg_notify = g_new(BackgroundNotify,1);
593
594 bg_notify->owner = owner;
595 bg_notify->trace = trace;
596 bg_notify->notify_time = notify_time;
597 if(notify_position!= NULL) {
598 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
599 lttv_traceset_context_position_copy(bg_notify->notify_position,
600 notify_position);
601 } else {
602 bg_notify->notify_position = NULL;
603 }
604 bg_notify->notify = lttv_hooks_new();
605 lttv_hooks_add_list(bg_notify->notify, notify);
606
607 *slist = g_slist_append(*slist, bg_notify);
608 #endif /* BABEL_CLEANUP */
609 }
610
611
612 static void notify_request_free(BackgroundNotify *notify_req)
613 {
614 #ifdef BABEL_CLEANUP
615 if(notify_req == NULL) return;
616
617 if(notify_req->notify_position != NULL)
618 lttv_traceset_context_position_destroy(notify_req->notify_position);
619 if(notify_req->notify != NULL)
620 lttv_hooks_destroy(notify_req->notify);
621 g_free(notify_req);
622 #endif /* BABEL_CLEANUP */
623 }
624
625 /**
626 * Removes all the notifications requests from a specific viewer.
627 *
628 * @param owner owner of the background notification
629 */
630
631 __EXPORT void lttvwindowtraces_background_notify_remove(gpointer owner)
632 {
633 guint i;
634
635 for(i=0;i<lttvwindowtraces_get_number();i++) {
636 LttvAttribute *attribute;
637 LttvAttributeValue value;
638 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
639 GSList **slist;
640 GSList *iter = NULL;
641 gboolean result;
642
643 g_assert(trace_v != NULL);
644
645 attribute = lttv_trace_attribute(trace_v);
646
647 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
648 LTTV_NOTIFY_QUEUE,
649 LTTV_POINTER,
650 &value);
651 g_assert(result);
652
653 slist = (GSList**)(value.v_pointer);
654
655 for(iter=*slist;iter!=NULL;) {
656
657 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
658
659 if(bg_notify->owner == owner) {
660 GSList *rem_iter = iter;
661 iter=g_slist_next(iter);
662 notify_request_free(bg_notify);
663 *slist = g_slist_remove_link(*slist, rem_iter);
664 } else {
665 iter=g_slist_next(iter);
666 }
667 }
668
669 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
670 LTTV_NOTIFY_CURRENT,
671 LTTV_POINTER,
672 &value);
673 g_assert(result);
674
675 slist = (GSList**)(value.v_pointer);
676
677 for(iter=*slist;iter!=NULL;) {
678
679 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
680
681 if(bg_notify->owner == owner) {
682 GSList *rem_iter = iter;
683 iter=g_slist_next(iter);
684 notify_request_free(bg_notify);
685 *slist = g_slist_remove_link(*slist, rem_iter);
686 } else {
687 iter=g_slist_next(iter);
688 }
689 }
690 }
691 }
692
693
694 /* Background processing helper functions */
695
696 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
697 LttvTraceset *ts,
698 LttvHooks *hook_adder)
699 {
700 #ifdef BABEL_CLEANUP
701 LttvAttribute *g_attribute = lttv_global_attributes();
702 LttvAttribute *module_attribute;
703 LttvAttributeType type;
704 LttvAttributeValue value;
705
706
707 module_attribute =
708 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
709 LTTV_COMPUTATION));
710 g_assert(module_attribute);
711
712 module_attribute =
713 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
714 LTTV_IATTRIBUTE(module_attribute),
715 module_name));
716 g_assert(module_attribute);
717
718 /* Call the module's hook adder */
719 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
720 LTTV_HOOK_ADDER,
721 &value);
722 if(type == LTTV_POINTER) {
723 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
724 if(hook_adder != NULL)
725 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
726 }
727 #endif /* BABEL_CLEANUP */
728 }
729
730 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
731 LttvTraceset *ts,
732 LttvHooks *hook_remover)
733 {
734 #ifdef BABEL_CLEANUP
735 LttvAttribute *g_attribute = lttv_global_attributes();
736 LttvAttribute *module_attribute;
737 LttvAttributeType type;
738 LttvAttributeValue value;
739
740 module_attribute =
741 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
742 LTTV_COMPUTATION));
743 g_assert(module_attribute);
744
745 module_attribute =
746 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
747 LTTV_IATTRIBUTE(module_attribute),
748 module_name));
749 g_assert(module_attribute);
750
751 /* Call the module's hook remover */
752 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
753 LTTV_HOOK_REMOVER,
754 &value);
755 if(type == LTTV_POINTER) {
756 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
757 if(hook_remover != NULL)
758 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
759 }
760 #endif /* BABEL_CLEANUP */
761 }
762
763 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
764 LttvTraceset *ts)
765 {
766 #ifdef BABEL_CLEANUP
767 LttvAttribute *g_attribute = lttv_global_attributes();
768 LttvAttribute *module_attribute;
769 LttvAttributeType type;
770 LttvAttributeValue value;
771 LttvHooks *before_chunk_traceset=NULL;
772 LttvHooks *before_chunk_trace=NULL;
773 LttvHooks *before_chunk_tracefile=NULL;
774 LttvHooks *event_hook=NULL;
775 LttvHooksByIdChannelArray *event_hook_by_id_channel=NULL;
776
777
778 module_attribute =
779 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
780 LTTV_COMPUTATION));
781 g_assert(module_attribute);
782
783 module_attribute =
784 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
785 LTTV_IATTRIBUTE(module_attribute),
786 module_name));
787 g_assert(module_attribute);
788
789 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
790 LTTV_BEFORE_CHUNK_TRACESET,
791 &value);
792 if(type == LTTV_POINTER) {
793 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
794 }
795
796 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
797 LTTV_BEFORE_CHUNK_TRACE,
798 &value);
799 if(type == LTTV_POINTER) {
800 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
801 }
802
803 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
804 LTTV_BEFORE_CHUNK_TRACEFILE,
805 &value);
806 if(type == LTTV_POINTER) {
807 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
808 }
809
810 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
811 LTTV_EVENT_HOOK,
812 &value);
813 if(type == LTTV_POINTER) {
814 event_hook = (LttvHooks*)*(value.v_pointer);
815 }
816
817 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
818 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
819 &value);
820 if(type == LTTV_POINTER) {
821 event_hook_by_id_channel = (LttvHooksByIdChannelArray*)*(value.v_pointer);
822 }
823
824 lttv_process_traceset_begin(tsc,
825 before_chunk_traceset,
826 before_chunk_trace,
827 before_chunk_tracefile,
828 event_hook,
829 event_hook_by_id_channel);
830 #endif /* BABEL_CLEANUP */
831 }
832
833
834
835 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
836 LttvTraceset *ts)
837 {
838 LttvAttribute *g_attribute = lttv_global_attributes();
839 LttvAttribute *module_attribute;
840 LttvAttributeType type;
841 LttvAttributeValue value;
842 LttvHooks *after_chunk_traceset=NULL;
843 LttvHooks *after_chunk_trace=NULL;
844 LttvHooks *after_chunk_tracefile=NULL;
845 LttvHooks *event_hook=NULL;
846
847 module_attribute =
848 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
849 LTTV_COMPUTATION));
850 g_assert(module_attribute);
851
852 module_attribute =
853 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
854 LTTV_IATTRIBUTE(module_attribute),
855 module_name));
856 g_assert(module_attribute);
857
858 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
859 LTTV_AFTER_CHUNK_TRACESET,
860 &value);
861 if(type == LTTV_POINTER) {
862 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
863 }
864
865 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
866 LTTV_AFTER_CHUNK_TRACE,
867 &value);
868 if(type == LTTV_POINTER) {
869 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
870 }
871
872 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
873 LTTV_AFTER_CHUNK_TRACEFILE,
874 &value);
875 if(type == LTTV_POINTER) {
876 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
877 }
878
879 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
880 LTTV_EVENT_HOOK,
881 &value);
882 if(type == LTTV_POINTER) {
883 event_hook = (LttvHooks*)*(value.v_pointer);
884 }
885
886 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
887 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
888 &value);
889 #ifdef BABEL_CLEANUP
890 lttv_process_traceset_end(tsc,
891 after_chunk_traceset,
892 after_chunk_trace,
893 after_chunk_tracefile,
894 event_hook);
895 #endif /* BABEL_CLEANUP*/
896
897 }
898
899
900 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
901 LttvTrace *trace)
902 {
903 LttvAttribute *attribute = lttv_trace_attribute(trace);
904
905 attribute =
906 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
907 module_name));
908 g_assert(attribute);
909
910 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
911 LTTV_IN_PROGRESS,
912 LTTV_INT);
913 /* the value is left unset. The only presence of the attribute is necessary.
914 */
915 }
916
917 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
918 LttvTrace *trace)
919 {
920 LttvAttribute *attribute = lttv_trace_attribute(trace);
921
922 attribute =
923 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
924 module_name));
925 g_assert(attribute);
926
927 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
928 LTTV_IN_PROGRESS);
929 }
930
931 __EXPORT gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
932 LttvTrace *trace)
933 {
934 LttvAttribute *attribute = lttv_trace_attribute(trace);
935 LttvAttributeType type;
936 LttvAttributeValue value;
937
938 attribute =
939 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
940 module_name));
941 g_assert(attribute);
942
943 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
944 LTTV_IN_PROGRESS,
945 &value);
946 /* The only presence of the attribute is necessary. */
947 if(type == LTTV_NONE)
948 return FALSE;
949 else
950 return TRUE;
951 }
952
953 void lttvwindowtraces_set_ready(LttvAttributeName module_name,
954 LttvTrace *trace)
955 {
956 LttvAttribute *attribute = lttv_trace_attribute(trace);
957
958 attribute =
959 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
960 module_name));
961 g_assert(attribute);
962
963 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
964 LTTV_READY,
965 LTTV_INT);
966 /* the value is left unset. The only presence of the attribute is necessary.
967 */
968 }
969
970 void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
971 LttvTrace *trace)
972 {
973 LttvAttribute *attribute = lttv_trace_attribute(trace);
974
975 attribute =
976 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
977 module_name));
978 g_assert(attribute);
979
980 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
981 LTTV_READY);
982 }
983
984 __EXPORT gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
985 LttvTrace *trace)
986 {
987 LttvAttribute *attribute = lttv_trace_attribute(trace);
988 LttvAttributeType type;
989 LttvAttributeValue value;
990
991 attribute =
992 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
993 module_name));
994 g_assert(attribute);
995
996 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
997 LTTV_READY,
998 &value);
999 /* The only presence of the attribute is necessary. */
1000 if(type == LTTV_NONE)
1001 return FALSE;
1002 else
1003 return TRUE;
1004 }
1005 #ifdef BABEL_CLEANUP
1006 static gint find_window_widget(MainWindow *a, GtkWidget *b)
1007 {
1008 if(a->mwindow == b) return 0;
1009 else return -1;
1010 }
1011 #endif
1012
1013 /* lttvwindowtraces_process_pending_requests
1014 *
1015 * Process the pending background computation requests
1016 *
1017 * This internal function gets called by g_idle, taking care of the pending
1018 * requests.
1019 *
1020 */
1021
1022
1023 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
1024 {
1025 LttvAttribute *attribute;
1026 LttvAttribute *g_attribute = lttv_global_attributes();
1027 GSList **list_out, **list_in, **notify_in, **notify_out;
1028 LttvAttributeValue value;
1029 LttvAttributeType type;
1030 gboolean ret_val;
1031
1032 if(trace == NULL)
1033 return FALSE;
1034
1035 if(lttvwindow_preempt_count > 0) return TRUE;
1036
1037 attribute = lttv_trace_attribute(trace);
1038
1039 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1040 LTTV_REQUESTS_QUEUE,
1041 &value);
1042 g_assert(type == LTTV_POINTER);
1043 list_out = (GSList**)(value.v_pointer);
1044
1045 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1046 LTTV_REQUESTS_CURRENT,
1047 &value);
1048 g_assert(type == LTTV_POINTER);
1049 list_in = (GSList**)(value.v_pointer);
1050
1051 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1052 LTTV_NOTIFY_QUEUE,
1053 &value);
1054 g_assert(type == LTTV_POINTER);
1055 notify_out = (GSList**)(value.v_pointer);
1056
1057 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1058 LTTV_NOTIFY_CURRENT,
1059 &value);
1060 g_assert(type == LTTV_POINTER);
1061 notify_in = (GSList**)(value.v_pointer);
1062
1063 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1064 LTTV_COMPUTATION_TRACESET,
1065 &value);
1066 g_assert(type == LTTV_POINTER);
1067 #ifdef BABEL_CLEANUP
1068 ts = (LttvTraceset*)*(value.v_pointer);
1069 #endif
1070 #if 0
1071 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1072 LTTV_COMPUTATION_SYNC_POSITION,
1073 &value);
1074 g_assert(type == LTTV_POINTER);
1075 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
1076 #endif //0
1077 #ifdef BABEL_CLEANUP
1078 /* There is no events requests pending : we should never have been called! */
1079 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
1080 /* 0.1 Lock traces */
1081 {
1082 guint iter_trace=0;
1083
1084 for(iter_trace=0;
1085 iter_trace<lttv_traceset_number(ts->ts);
1086 iter_trace++) {
1087 LttvTrace *trace_v = lttv_traceset_get(ts->ts,iter_trace);
1088
1089 if(lttvwindowtraces_lock(trace_v) != 0)
1090 return TRUE; /* Cannot get trace lock, try later */
1091
1092 }
1093 }
1094 /* 0.2 Sync tracefiles */
1095 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1096 lttv_process_traceset_synchronize_tracefiles(tsc);
1097 /* 1. Before processing */
1098 {
1099 /* if list_in is empty */
1100 if(g_slist_length(*list_in) == 0) {
1101
1102 {
1103 /* - Add all requests in list_out to list_in, empty list_out */
1104 GSList *iter = *list_out;
1105
1106 while(iter != NULL) {
1107 gboolean remove = FALSE;
1108 gboolean free_data = FALSE;
1109
1110 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1111
1112 remove = TRUE;
1113 free_data = FALSE;
1114 *list_in = g_slist_append(*list_in, bg_req);
1115
1116 /* Go to next */
1117 if(remove)
1118 {
1119 GSList *remove_iter = iter;
1120
1121 iter = g_slist_next(iter);
1122 if(free_data) g_free(remove_iter->data);
1123 *list_out = g_slist_remove_link(*list_out, remove_iter);
1124 } else { // not remove
1125 iter = g_slist_next(iter);
1126 }
1127 }
1128 }
1129
1130 {
1131 GSList *iter = *list_in;
1132 /* - for each request in list_in */
1133 while(iter != NULL) {
1134
1135 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1136 /* - set hooks'in_progress flag to TRUE */
1137 lttvwindowtraces_set_in_progress(bg_req->module_name,
1138 bg_req->trace);
1139
1140 /* - call before request hook */
1141 /* Get before request hook */
1142 LttvAttribute *module_attribute;
1143
1144 module_attribute =
1145 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1146 LTTV_IATTRIBUTE(g_attribute),
1147 LTTV_COMPUTATION));
1148 g_assert(module_attribute);
1149
1150 module_attribute =
1151 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1152 LTTV_IATTRIBUTE(module_attribute),
1153 bg_req->module_name));
1154 g_assert(module_attribute);
1155
1156 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1157 LTTV_BEFORE_REQUEST,
1158 &value);
1159 g_assert(type == LTTV_POINTER);
1160 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1161
1162 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
1163
1164 iter = g_slist_next(iter);
1165 }
1166 }
1167
1168 /* - seek trace to start */
1169 {
1170 LttTime start = { 0, 0};
1171 lttv_process_traceset_seek_time(tsc, start);
1172 }
1173
1174 /* - Move all notifications from notify_out to notify_in. */
1175 {
1176 GSList *iter = *notify_out;
1177 g_assert(g_slist_length(*notify_in) == 0);
1178
1179 while(iter != NULL) {
1180 gboolean remove = FALSE;
1181 gboolean free_data = FALSE;
1182
1183 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1184
1185 remove = TRUE;
1186 free_data = FALSE;
1187 *notify_in = g_slist_append(*notify_in, notify_req);
1188
1189 /* Go to next */
1190 if(remove)
1191 {
1192 GSList *remove_iter = iter;
1193
1194 iter = g_slist_next(iter);
1195 if(free_data)
1196 notify_request_free((BackgroundNotify*)remove_iter->data);
1197 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
1198 } else { // not remove
1199 iter = g_slist_next(iter);
1200 }
1201 }
1202 }
1203 {
1204 GSList *iter = *list_in;
1205 LttvHooks *hook_adder = lttv_hooks_new();
1206 /* - for each request in list_in */
1207 while(iter != NULL) {
1208
1209 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1210 /*- add hooks to context*/
1211 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1212 tsc,
1213 hook_adder);
1214 iter = g_slist_next(iter);
1215 }
1216 lttv_hooks_call(hook_adder,tsc);
1217 lttv_hooks_destroy(hook_adder);
1218 }
1219
1220
1221 }
1222
1223 {
1224 GSList *iter = *list_in;
1225 /* - for each request in list_in */
1226 while(iter != NULL) {
1227
1228 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1229 /*- Call before chunk hooks for list_in*/
1230 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1231 tsc);
1232 iter = g_slist_next(iter);
1233 }
1234 }
1235
1236 }
1237 /* 2. call process traceset middle for a chunk */
1238 {
1239 /*(assert list_in is not empty! : should not even be called in that case)*/
1240 LttTime end = ltt_time_infinite;
1241 g_assert(g_slist_length(*list_in) != 0);
1242
1243 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1244 }
1245
1246 /* 3. After the chunk */
1247 {
1248 /* 3.1 call after_chunk hooks for list_in */
1249 {
1250 GSList *iter = *list_in;
1251 /* - for each request in list_in */
1252 while(iter != NULL) {
1253
1254 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1255 /* - Call after chunk hooks for list_in */
1256 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1257 tsc);
1258 iter = g_slist_next(iter);
1259 }
1260 }
1261
1262 /* 3.2 for each notify_in */
1263 {
1264 GSList *iter = *notify_in;
1265 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1266
1267 while(iter != NULL) {
1268 gboolean remove = FALSE;
1269 gboolean free_data = FALSE;
1270
1271 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1272
1273 /* - if current time >= notify time, call notify and remove from
1274 * notify_in.
1275 * - if current position >= notify position, call notify and remove
1276 * from notify_in.
1277 */
1278 if( (tfc != NULL &&
1279 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
1280 ||
1281 (notify_req->notify_position != NULL &&
1282 lttv_traceset_context_ctx_pos_compare(tsc,
1283 notify_req->notify_position) >= 0)
1284 ) {
1285
1286 lttv_hooks_call(notify_req->notify, notify_req);
1287
1288 remove = TRUE;
1289 free_data = TRUE;
1290 }
1291
1292 /* Go to next */
1293 if(remove)
1294 {
1295 GSList *remove_iter = iter;
1296
1297 iter = g_slist_next(iter);
1298 if(free_data)
1299 notify_request_free((BackgroundNotify*)remove_iter->data);
1300 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1301 } else { // not remove
1302 iter = g_slist_next(iter);
1303 }
1304 }
1305 }
1306
1307 {
1308 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1309 /* 3.3 if end of trace reached */
1310 if(tfc != NULL)
1311 g_debug("Current time : %lu sec, %lu nsec",
1312 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
1313 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1314 tsc->time_span.end_time) > 0) {
1315
1316 {
1317 GSList *iter = *list_in;
1318 LttvHooks *hook_remover = lttv_hooks_new();
1319 /* - for each request in list_in */
1320 while(iter != NULL) {
1321
1322 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1323 /* - remove hooks from context */
1324 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1325 tsc,
1326 hook_remover);
1327 iter = g_slist_next(iter);
1328 }
1329 lttv_hooks_call(hook_remover,tsc);
1330 lttv_hooks_destroy(hook_remover);
1331 }
1332
1333 /* - for each request in list_in */
1334 {
1335 GSList *iter = *list_in;
1336
1337 while(iter != NULL) {
1338 gboolean remove = FALSE;
1339 gboolean free_data = FALSE;
1340
1341 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1342
1343 /* - set hooks'in_progress flag to FALSE */
1344 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1345 bg_req->trace);
1346 /* - set hooks'ready flag to TRUE */
1347 lttvwindowtraces_set_ready(bg_req->module_name,
1348 bg_req->trace);
1349 /* - call after request hook */
1350 /* Get after request hook */
1351 LttvAttribute *module_attribute;
1352
1353 module_attribute =
1354 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1355 LTTV_IATTRIBUTE(g_attribute),
1356 LTTV_COMPUTATION));
1357 g_assert(module_attribute);
1358
1359 module_attribute =
1360 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1361 LTTV_IATTRIBUTE(module_attribute),
1362 bg_req->module_name));
1363 g_assert(module_attribute);
1364
1365 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1366 LTTV_AFTER_REQUEST,
1367 &value);
1368 g_assert(type == LTTV_POINTER);
1369 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1370 {
1371 struct sum_traceset_closure t_closure;
1372 t_closure.tss = (LttvTracesetStats*)tsc;
1373 t_closure.current_time = ltt_time_infinite;
1374 if(after_request != NULL) lttv_hooks_call(after_request,
1375 &t_closure);
1376 }
1377
1378 if(bg_req->dialog != NULL)
1379 gtk_widget_destroy(bg_req->dialog);
1380 GtkWidget *parent_window;
1381 if(g_slist_find_custom(g_main_window_list,
1382 bg_req->parent_window,
1383 (GCompareFunc)find_window_widget))
1384 parent_window = GTK_WIDGET(bg_req->parent_window);
1385 else
1386 parent_window = NULL;
1387
1388 GtkWidget *dialog =
1389 gtk_message_dialog_new(GTK_WINDOW(parent_window),
1390 GTK_DIALOG_DESTROY_WITH_PARENT,
1391 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1392 "Background computation %s finished for trace %s",
1393 g_quark_to_string(bg_req->module_name),
1394 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
1395 if(parent_window != NULL)
1396 gtk_window_set_transient_for(GTK_WINDOW(dialog),
1397 GTK_WINDOW(parent_window));
1398 g_signal_connect_swapped (dialog, "response",
1399 G_CALLBACK (gtk_widget_destroy),
1400 dialog);
1401 gtk_widget_show(dialog);
1402
1403 /* - remove request */
1404 remove = TRUE;
1405 free_data = TRUE;
1406
1407 /* Go to next */
1408 if(remove)
1409 {
1410 GSList *remove_iter = iter;
1411
1412 iter = g_slist_next(iter);
1413 if(free_data) g_free(remove_iter->data);
1414 *list_in = g_slist_remove_link(*list_in, remove_iter);
1415 } else { // not remove
1416 iter = g_slist_next(iter);
1417 }
1418 }
1419 }
1420
1421 /* - for each notifications in notify_in */
1422 {
1423 GSList *iter = *notify_in;
1424
1425 while(iter != NULL) {
1426 gboolean remove = FALSE;
1427 gboolean free_data = FALSE;
1428
1429 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1430
1431 /* - call notify and remove from notify_in */
1432 lttv_hooks_call(notify_req->notify, notify_req);
1433 remove = TRUE;
1434 free_data = TRUE;
1435
1436 /* Go to next */
1437 if(remove)
1438 {
1439 GSList *remove_iter = iter;
1440
1441 iter = g_slist_next(iter);
1442 if(free_data)
1443 notify_request_free((BackgroundNotify*)remove_iter->data);
1444 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1445 } else { // not remove
1446 iter = g_slist_next(iter);
1447 }
1448 }
1449 }
1450 {
1451 /* - reset the context */
1452 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1453 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1454 }
1455 /* - if list_out is empty */
1456 if(g_slist_length(*list_out) == 0) {
1457 /* - return FALSE (scheduler stopped) */
1458 g_debug("Background computation scheduler stopped");
1459 g_info("Background computation finished for trace %p", trace);
1460 /* FIXME : remove status bar info, need context id and message id */
1461
1462 ret_val = FALSE;
1463 } else {
1464 ret_val = TRUE;
1465 }
1466 } else {
1467 /* 3.4 else, end of trace not reached */
1468 /* - return TRUE (scheduler still registered) */
1469 g_debug("Background computation left");
1470 ret_val = TRUE;
1471 }
1472 }
1473 }
1474 /* 4. Unlock traces */
1475 {
1476 lttv_process_traceset_get_sync_data(tsc);
1477 //lttv_traceset_context_position_save(tsc, sync_position);
1478 guint iter_trace;
1479
1480 for(iter_trace=0;
1481 iter_trace<lttv_traceset_number(tsc->ts);
1482 iter_trace++) {
1483 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1484
1485 lttvwindowtraces_unlock(trace_v);
1486 }
1487 }
1488 #endif /* BABEL_CLEANUP */
1489 return ret_val;
1490 }
1491
1492
1493
1494 /**
1495 * Register the background computation hooks for a specific module. It adds the
1496 * computation hooks to the global attrubutes, under "computation/module name".
1497 *
1498 * @param module_name A GQuark : the name of the module which computes the
1499 * information.
1500 */
1501 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1502 LttvHooks *before_chunk_traceset,
1503 LttvHooks *before_chunk_trace,
1504 LttvHooks *before_chunk_tracefile,
1505 LttvHooks *after_chunk_traceset,
1506 LttvHooks *after_chunk_trace,
1507 LttvHooks *after_chunk_tracefile,
1508 LttvHooks *before_request,
1509 LttvHooks *after_request,
1510 LttvHooks *event_hook,
1511 LttvHooks *hook_adder,
1512 LttvHooks *hook_remover)
1513 {
1514 LttvAttribute *g_attribute = lttv_global_attributes();
1515 LttvAttribute *attribute;
1516 LttvAttributeValue value;
1517 gboolean result;
1518
1519 attribute =
1520 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1521 LTTV_COMPUTATION));
1522 g_assert(attribute);
1523
1524 attribute =
1525 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1526 module_name));
1527 g_assert(attribute);
1528
1529 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1530 LTTV_BEFORE_CHUNK_TRACESET,
1531 LTTV_POINTER,
1532 &value);
1533 g_assert(result);
1534
1535 *(value.v_pointer) = before_chunk_traceset;
1536
1537 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1538 LTTV_BEFORE_CHUNK_TRACE,
1539 LTTV_POINTER,
1540 &value);
1541 g_assert(result);
1542 *(value.v_pointer) = before_chunk_trace;
1543
1544 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1545 LTTV_BEFORE_CHUNK_TRACEFILE,
1546 LTTV_POINTER,
1547 &value);
1548 g_assert(result);
1549 *(value.v_pointer) = before_chunk_tracefile;
1550
1551 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1552 LTTV_AFTER_CHUNK_TRACESET,
1553 LTTV_POINTER,
1554 &value);
1555 g_assert(result);
1556 *(value.v_pointer) = after_chunk_traceset;
1557
1558 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1559 LTTV_AFTER_CHUNK_TRACE,
1560 LTTV_POINTER,
1561 &value);
1562 g_assert(result);
1563 *(value.v_pointer) = after_chunk_trace;
1564
1565 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1566 LTTV_AFTER_CHUNK_TRACEFILE,
1567 LTTV_POINTER,
1568 &value);
1569 g_assert(result);
1570 *(value.v_pointer) = after_chunk_tracefile;
1571
1572 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1573 LTTV_BEFORE_REQUEST,
1574 LTTV_POINTER,
1575 &value);
1576 g_assert(result);
1577 *(value.v_pointer) = before_request;
1578
1579 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1580 LTTV_AFTER_REQUEST,
1581 LTTV_POINTER,
1582 &value);
1583 g_assert(result);
1584 *(value.v_pointer) = after_request;
1585
1586 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1587 LTTV_EVENT_HOOK,
1588 LTTV_POINTER,
1589 &value);
1590 g_assert(result);
1591 *(value.v_pointer) = event_hook;
1592
1593 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1594 LTTV_HOOK_ADDER,
1595 LTTV_POINTER,
1596 &value);
1597 g_assert(result);
1598 *(value.v_pointer) = hook_adder;
1599
1600 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1601 LTTV_HOOK_REMOVER,
1602 LTTV_POINTER,
1603 &value);
1604 g_assert(result);
1605 *(value.v_pointer) = hook_remover;
1606
1607 }
1608
1609
1610 /**
1611 * It removes all the requests that can be currently processed by the
1612 * background computation algorithm for all the traces (list_in and list_out).
1613 *
1614 * Leaves the flag to in_progress or none.. depending if current or queue
1615 *
1616 * @param module_name A GQuark : the name of the module which computes the
1617 * information.
1618 */
1619 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1620 {
1621 guint i;
1622 gboolean result;
1623
1624 for(i=0;i<lttvwindowtraces_get_number();i++) {
1625 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1626 g_assert(trace_v != NULL);
1627 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1628 LttvAttributeValue value;
1629 GSList **queue, **current;
1630 GSList *iter;
1631
1632 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1633 LTTV_REQUESTS_QUEUE,
1634 LTTV_POINTER,
1635 &value);
1636 g_assert(result);
1637
1638 queue = (GSList**)(value.v_pointer);
1639
1640 iter = *queue;
1641 while(iter != NULL) {
1642 gboolean remove = FALSE;
1643 gboolean free_data = FALSE;
1644
1645 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1646
1647 if(bg_req->module_name == module_name) {
1648 remove = TRUE;
1649 free_data = TRUE;
1650 }
1651
1652 /* Go to next */
1653 if(remove)
1654 {
1655 GSList *remove_iter = iter;
1656
1657 iter = g_slist_next(iter);
1658 if(free_data) g_free(remove_iter->data);
1659 *queue = g_slist_remove_link(*queue, remove_iter);
1660 } else { // not remove
1661 iter = g_slist_next(iter);
1662 }
1663 }
1664
1665
1666 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1667 LTTV_REQUESTS_CURRENT,
1668 LTTV_POINTER,
1669 &value);
1670 g_assert(result);
1671
1672 current = (GSList**)(value.v_pointer);
1673
1674 iter = *current;
1675 while(iter != NULL) {
1676 gboolean remove = FALSE;
1677 gboolean free_data = FALSE;
1678
1679 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1680
1681 if(bg_req->module_name == module_name) {
1682 remove = TRUE;
1683 free_data = TRUE;
1684 }
1685
1686 /* Go to next */
1687 if(remove)
1688 {
1689 GSList *remove_iter = iter;
1690
1691 iter = g_slist_next(iter);
1692 if(free_data) g_free(remove_iter->data);
1693 *current = g_slist_remove_link(*current, remove_iter);
1694 } else { // not remove
1695 iter = g_slist_next(iter);
1696 }
1697 }
1698 }
1699 }
1700
1701
1702 /**
1703 * Unregister the background computation hooks for a specific module.
1704 *
1705 * It also removes all the requests that can be currently processed by the
1706 * background computation algorithm for all the traces (list_in and list_out).
1707 *
1708 * @param module_name A GQuark : the name of the module which computes the
1709 * information.
1710 */
1711
1712 void lttvwindowtraces_unregister_computation_hooks
1713 (LttvAttributeName module_name)
1714 {
1715 LttvAttribute *g_attribute = lttv_global_attributes();
1716 LttvAttribute *attribute;
1717 LttvAttributeValue value;
1718 gboolean result;
1719
1720 attribute =
1721 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1722 LTTV_COMPUTATION));
1723 g_assert(attribute);
1724
1725 attribute =
1726 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1727 module_name));
1728 g_assert(attribute);
1729
1730 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1731 LTTV_BEFORE_CHUNK_TRACESET,
1732 LTTV_POINTER,
1733 &value);
1734 g_assert(result);
1735
1736 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1737 if(before_chunk_traceset != NULL)
1738 lttv_hooks_destroy(before_chunk_traceset);
1739
1740 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1741 LTTV_BEFORE_CHUNK_TRACE,
1742 LTTV_POINTER,
1743 &value);
1744 g_assert(result);
1745
1746 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1747 if(before_chunk_trace != NULL)
1748 lttv_hooks_destroy(before_chunk_trace);
1749
1750 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1751 LTTV_BEFORE_CHUNK_TRACEFILE,
1752 LTTV_POINTER,
1753 &value);
1754 g_assert(result);
1755
1756 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1757 if(before_chunk_tracefile != NULL)
1758 lttv_hooks_destroy(before_chunk_tracefile);
1759
1760 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1761 LTTV_AFTER_CHUNK_TRACESET,
1762 LTTV_POINTER,
1763 &value);
1764 g_assert(result);
1765
1766 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1767 if(after_chunk_traceset != NULL)
1768 lttv_hooks_destroy(after_chunk_traceset);
1769
1770 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1771 LTTV_AFTER_CHUNK_TRACE,
1772 LTTV_POINTER,
1773 &value);
1774 g_assert(result);
1775
1776 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1777 if(after_chunk_trace != NULL)
1778 lttv_hooks_destroy(after_chunk_trace);
1779
1780 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1781 LTTV_AFTER_CHUNK_TRACEFILE,
1782 LTTV_POINTER,
1783 &value);
1784 g_assert(result);
1785
1786 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1787 if(after_chunk_tracefile != NULL)
1788 lttv_hooks_destroy(after_chunk_tracefile);
1789
1790 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1791 LTTV_BEFORE_REQUEST,
1792 LTTV_POINTER,
1793 &value);
1794 g_assert(result);
1795
1796 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1797 if(before_request != NULL)
1798 lttv_hooks_destroy(before_request);
1799
1800 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1801 LTTV_AFTER_REQUEST,
1802 LTTV_POINTER,
1803 &value);
1804 g_assert(result);
1805
1806 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1807 if(after_request != NULL)
1808 lttv_hooks_destroy(after_request);
1809
1810 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1811 LTTV_EVENT_HOOK,
1812 LTTV_POINTER,
1813 &value);
1814 g_assert(result);
1815
1816 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1817 if(event_hook != NULL)
1818 lttv_hooks_destroy(event_hook);
1819
1820 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1821 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
1822 LTTV_POINTER,
1823 &value);
1824 g_assert(result);
1825
1826 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1827 LTTV_HOOK_ADDER,
1828 LTTV_POINTER,
1829 &value);
1830 g_assert(result);
1831
1832 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1833 if(hook_adder != NULL)
1834 lttv_hooks_destroy(hook_adder);
1835
1836 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1837 LTTV_HOOK_REMOVER,
1838 LTTV_POINTER,
1839 &value);
1840 g_assert(result);
1841
1842 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1843 if(hook_remover != NULL)
1844 lttv_hooks_destroy(hook_remover);
1845
1846
1847 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1848 LTTV_EVENT_HOOK_BY_ID_CHANNEL);
1849 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1850 LTTV_EVENT_HOOK);
1851
1852 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1853 LTTV_AFTER_REQUEST);
1854 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1855 LTTV_BEFORE_REQUEST);
1856
1857 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1858 LTTV_AFTER_CHUNK_TRACEFILE);
1859 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1860 LTTV_AFTER_CHUNK_TRACE);
1861 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1862 LTTV_AFTER_CHUNK_TRACESET);
1863
1864 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1865 LTTV_BEFORE_CHUNK_TRACEFILE);
1866 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1867 LTTV_BEFORE_CHUNK_TRACE);
1868 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1869 LTTV_BEFORE_CHUNK_TRACESET);
1870 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1871 LTTV_HOOK_ADDER);
1872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1873 LTTV_HOOK_REMOVER);
1874
1875 /* finally, remove module name */
1876 attribute =
1877 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1878 LTTV_COMPUTATION));
1879 g_assert(attribute);
1880 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1881 module_name);
1882
1883 }
1884
1885 /**
1886 * Lock a trace so no other instance can use it.
1887 *
1888 * @param trace The trace to lock.
1889 * @return 0 on success, -1 if cannot get lock.
1890 */
1891 gint lttvwindowtraces_lock(LttvTrace *trace)
1892 {
1893 LttvAttribute *attribute = lttv_trace_attribute(trace);
1894 LttvAttributeValue value;
1895 LttvAttributeType type;
1896
1897 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1898 LTTV_LOCK,
1899 &value);
1900 /* Verify the absence of the lock. */
1901 if(type != LTTV_NONE) {
1902 g_critical("Cannot take trace lock");
1903 return -1;
1904 }
1905
1906 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1907 LTTV_LOCK,
1908 LTTV_INT);
1909 /* the value is left unset. The only presence of the attribute is necessary.
1910 */
1911
1912 return 0;
1913 }
1914
1915 /**
1916 * Unlock a trace.
1917 *
1918 * @param trace The trace to unlock.
1919 * @return 0 on success, -1 if cannot unlock (not locked ?).
1920 */
1921 gint lttvwindowtraces_unlock(LttvTrace *trace)
1922 {
1923 LttvAttribute *attribute = lttv_trace_attribute(trace);
1924 LttvAttributeType type;
1925 LttvAttributeValue value;
1926
1927 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1928 LTTV_LOCK,
1929 &value);
1930 /* Verify the presence of the lock. */
1931 if(type == LTTV_NONE) {
1932 g_critical("Cannot release trace lock");
1933 return -1;
1934 }
1935
1936 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1937 LTTV_LOCK);
1938
1939 return 0;
1940 }
1941
1942 /**
1943 * Verify if a trace is locked.
1944 *
1945 * @param trace The trace to verify.
1946 * @return TRUE if locked, FALSE is unlocked.
1947 */
1948 gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1949 {
1950 LttvAttribute *attribute = lttv_trace_attribute(trace);
1951 LttvAttributeType type;
1952 LttvAttributeValue value;
1953
1954 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1955 LTTV_LOCK,
1956 &value);
1957 /* The only presence of the attribute is necessary. */
1958 if(type == LTTV_NONE)
1959 return FALSE;
1960 else
1961 return TRUE;
1962 }
1963
This page took 0.103542 seconds and 4 git commands to generate.