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