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