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