05ab4b436e758444496cb3b49a2401fb5b4203f7
[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 <lttv/tracecontext.h>
40 #include <lttvwindow/lttvwindowtraces.h>
41 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
42 #include <lttvwindow/mainwindow-private.h> /* for main window structure */
43
44 extern GSList * g_main_window_list;
45
46 typedef struct _BackgroundRequest {
47 LttvAttributeName module_name; /* Hook path in global attributes,
48 where all standard hooks under computation/.
49 i.e. modulename */
50 LttvTrace *trace; /* trace concerned */
51 GtkWidget *dialog; /* Dialog linked with the request, may be NULL */
52 GtkWidget *parent_window; /* Parent window the dialog must be transient for */
53 } BackgroundRequest;
54
55 typedef struct _BackgroundNotify {
56 gpointer owner;
57 LttvTrace *trace; /* trace */
58 LttTime notify_time;
59 LttvTracesetContextPosition *notify_position;
60 LttvHooks *notify; /* Hook to call when the notify is
61 passed, or at the end of trace */
62 } BackgroundNotify;
63
64
65
66 /* Prototypes */
67 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
68
69 /* Get a trace by its path name.
70 *
71 * @param path path of the trace on the virtual file system.
72 * @return Pointer to trace if found
73 * NULL is returned if the trace is not present
74 */
75
76 __EXPORT LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
77 {
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
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 LttvAttribute *g_attribute = lttv_global_attributes();
145 LttvAttribute *attribute;
146 LttvAttributeValue value;
147 struct stat buf;
148 gchar attribute_path[PATH_MAX];
149 int result;
150 gboolean result_b;
151
152 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace))), &buf)) {
153 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
154 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
155 return;
156 }
157 result = snprintf(attribute_path, PATH_MAX, "%" PRIu64 ":%" PRIu64,
158 buf.st_dev, buf.st_ino);
159 g_assert(result >= 0);
160
161 attribute =
162 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
163 LTTV_TRACES));
164 g_assert(attribute);
165
166 value = lttv_attribute_add(attribute,
167 g_quark_from_string(attribute_path),
168 LTTV_POINTER);
169
170 *(value.v_pointer) = (gpointer)trace;
171
172 /* create new traceset and tracesetcontext */
173 LttvTraceset *ts;
174 LttvTracesetStats *tss;
175 //LttvTracesetContextPosition *sync_position;
176
177 attribute = lttv_trace_attribute(trace);
178 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
179 LTTV_COMPUTATION_TRACESET,
180 LTTV_POINTER,
181 &value);
182 g_assert(result_b);
183
184 ts = lttv_traceset_new();
185 *(value.v_pointer) = ts;
186
187 lttv_traceset_add(ts,trace);
188
189 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
190 LTTV_COMPUTATION_TRACESET_CONTEXT,
191 LTTV_POINTER,
192 &value);
193 g_assert(result_b);
194
195 tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
196 *(value.v_pointer) = tss;
197
198 lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
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 LttvTracesetStats *tss;
256 //LttvTracesetContextPosition *sync_position;
257
258 l_attribute = lttv_trace_attribute(trace);
259
260
261 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
262 LTTV_REQUESTS_QUEUE);
263
264 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
265 LTTV_REQUESTS_CURRENT);
266
267 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
268 LTTV_NOTIFY_QUEUE);
269
270 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
271 LTTV_NOTIFY_CURRENT);
272
273 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
274 LTTV_COMPUTATION_TRACESET,
275 LTTV_POINTER,
276 &value);
277 g_assert(result);
278
279 ts = (LttvTraceset*)*(value.v_pointer);
280 #if 0
281 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
282 LTTV_COMPUTATION_SYNC_POSITION,
283 LTTV_POINTER,
284 &value);
285 g_assert(result);
286
287 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
288 lttv_traceset_context_position_destroy(sync_position);
289
290 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
291 LTTV_COMPUTATION_SYNC_POSITION);
292
293 #endif //0
294 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
295 LTTV_COMPUTATION_TRACESET_CONTEXT,
296 LTTV_POINTER,
297 &value);
298 g_assert(result);
299
300 tss = (LttvTracesetStats*)*(value.v_pointer);
301
302 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
303 g_object_unref(tss);
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 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
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 LttvTracesetContextPosition *notify_position,
505 const LttvHooks *notify)
506 {
507 BackgroundNotify *bg_notify;
508 LttvAttribute *attribute = lttv_trace_attribute(trace);
509 LttvAttributeValue value;
510 GSList **slist;
511 gboolean result;
512
513 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
514 LTTV_NOTIFY_QUEUE,
515 LTTV_POINTER,
516 &value);
517 g_assert(result);
518
519 slist = (GSList**)(value.v_pointer);
520
521 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
522 LTTV_COMPUTATION_TRACESET_CONTEXT,
523 LTTV_POINTER,
524 &value);
525 g_assert(result);
526
527 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
528
529 bg_notify = g_new(BackgroundNotify,1);
530
531 bg_notify->owner = owner;
532 bg_notify->trace = trace;
533 bg_notify->notify_time = notify_time;
534 if(notify_position != NULL) {
535 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
536 lttv_traceset_context_position_copy(bg_notify->notify_position,
537 notify_position);
538 } else {
539 bg_notify->notify_position = NULL;
540 }
541
542 bg_notify->notify = lttv_hooks_new();
543 lttv_hooks_add_list(bg_notify->notify, notify);
544
545 *slist = g_slist_append(*slist, bg_notify);
546 }
547
548 /**
549 * Register a callback to be called when requested data is passed in the current
550 * background processing.
551 *
552 * @param owner owner of the background notification
553 * @param trace the trace computed
554 * @param notify_time time when notification hooks must be called
555 * @param notify_position position when notification hooks must be called
556 * @param notify Hook to call when the notify position is passed
557 */
558
559 __EXPORT void lttvwindowtraces_background_notify_current
560 (gpointer owner,
561 LttvTrace *trace,
562 LttTime notify_time,
563 const LttvTracesetContextPosition *notify_position,
564 const LttvHooks *notify)
565 {
566 BackgroundNotify *bg_notify;
567 LttvAttribute *attribute = lttv_trace_attribute(trace);
568 LttvAttributeValue value;
569 GSList **slist;
570 gboolean result;
571
572 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
573 LTTV_NOTIFY_CURRENT,
574 LTTV_POINTER,
575 &value);
576 g_assert(result);
577
578 slist = (GSList**)(value.v_pointer);
579
580 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
581 LTTV_COMPUTATION_TRACESET_CONTEXT,
582 LTTV_POINTER,
583 &value);
584 g_assert(result);
585
586 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
587
588
589 bg_notify = g_new(BackgroundNotify,1);
590
591 bg_notify->owner = owner;
592 bg_notify->trace = trace;
593 bg_notify->notify_time = notify_time;
594 if(notify_position!= NULL) {
595 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
596 lttv_traceset_context_position_copy(bg_notify->notify_position,
597 notify_position);
598 } else {
599 bg_notify->notify_position = NULL;
600 }
601 bg_notify->notify = lttv_hooks_new();
602 lttv_hooks_add_list(bg_notify->notify, notify);
603
604 *slist = g_slist_append(*slist, bg_notify);
605 }
606
607
608 static void notify_request_free(BackgroundNotify *notify_req)
609 {
610 if(notify_req == NULL) return;
611
612 if(notify_req->notify_position != NULL)
613 lttv_traceset_context_position_destroy(notify_req->notify_position);
614 if(notify_req->notify != NULL)
615 lttv_hooks_destroy(notify_req->notify);
616 g_free(notify_req);
617 }
618
619 /**
620 * Removes all the notifications requests from a specific viewer.
621 *
622 * @param owner owner of the background notification
623 */
624
625 __EXPORT void lttvwindowtraces_background_notify_remove(gpointer owner)
626 {
627 guint i;
628
629 for(i=0;i<lttvwindowtraces_get_number();i++) {
630 LttvAttribute *attribute;
631 LttvAttributeValue value;
632 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
633 GSList **slist;
634 GSList *iter = NULL;
635 gboolean result;
636
637 g_assert(trace_v != NULL);
638
639 attribute = lttv_trace_attribute(trace_v);
640
641 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
642 LTTV_NOTIFY_QUEUE,
643 LTTV_POINTER,
644 &value);
645 g_assert(result);
646
647 slist = (GSList**)(value.v_pointer);
648
649 for(iter=*slist;iter!=NULL;) {
650
651 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
652
653 if(bg_notify->owner == owner) {
654 GSList *rem_iter = iter;
655 iter=g_slist_next(iter);
656 notify_request_free(bg_notify);
657 *slist = g_slist_remove_link(*slist, rem_iter);
658 } else {
659 iter=g_slist_next(iter);
660 }
661 }
662
663 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
664 LTTV_NOTIFY_CURRENT,
665 LTTV_POINTER,
666 &value);
667 g_assert(result);
668
669 slist = (GSList**)(value.v_pointer);
670
671 for(iter=*slist;iter!=NULL;) {
672
673 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
674
675 if(bg_notify->owner == owner) {
676 GSList *rem_iter = iter;
677 iter=g_slist_next(iter);
678 notify_request_free(bg_notify);
679 *slist = g_slist_remove_link(*slist, rem_iter);
680 } else {
681 iter=g_slist_next(iter);
682 }
683 }
684 }
685 }
686
687
688 /* Background processing helper functions */
689
690 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
691 LttvTracesetContext *tsc,
692 LttvHooks *hook_adder)
693 {
694 LttvAttribute *g_attribute = lttv_global_attributes();
695 LttvAttribute *module_attribute;
696 LttvAttributeType type;
697 LttvAttributeValue value;
698
699
700 module_attribute =
701 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
702 LTTV_COMPUTATION));
703 g_assert(module_attribute);
704
705 module_attribute =
706 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
707 LTTV_IATTRIBUTE(module_attribute),
708 module_name));
709 g_assert(module_attribute);
710
711 /* Call the module's hook adder */
712 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
713 LTTV_HOOK_ADDER,
714 &value);
715 if(type == LTTV_POINTER) {
716 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
717 if(hook_adder != NULL)
718 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
719 }
720 }
721
722 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
723 LttvTracesetContext *tsc,
724 LttvHooks *hook_remover)
725 {
726 LttvAttribute *g_attribute = lttv_global_attributes();
727 LttvAttribute *module_attribute;
728 LttvAttributeType type;
729 LttvAttributeValue value;
730
731 module_attribute =
732 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
733 LTTV_COMPUTATION));
734 g_assert(module_attribute);
735
736 module_attribute =
737 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
738 LTTV_IATTRIBUTE(module_attribute),
739 module_name));
740 g_assert(module_attribute);
741
742 /* Call the module's hook remover */
743 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
744 LTTV_HOOK_REMOVER,
745 &value);
746 if(type == LTTV_POINTER) {
747 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
748 if(hook_remover != NULL)
749 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
750 }
751 }
752
753 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
754 LttvTracesetContext *tsc)
755 {
756 LttvAttribute *g_attribute = lttv_global_attributes();
757 LttvAttribute *module_attribute;
758 LttvAttributeType type;
759 LttvAttributeValue value;
760 LttvHooks *before_chunk_traceset=NULL;
761 LttvHooks *before_chunk_trace=NULL;
762 LttvHooks *before_chunk_tracefile=NULL;
763 LttvHooks *event_hook=NULL;
764 LttvHooksByIdChannelArray *event_hook_by_id_channel=NULL;
765
766
767 module_attribute =
768 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
769 LTTV_COMPUTATION));
770 g_assert(module_attribute);
771
772 module_attribute =
773 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
774 LTTV_IATTRIBUTE(module_attribute),
775 module_name));
776 g_assert(module_attribute);
777
778 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
779 LTTV_BEFORE_CHUNK_TRACESET,
780 &value);
781 if(type == LTTV_POINTER) {
782 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
783 }
784
785 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
786 LTTV_BEFORE_CHUNK_TRACE,
787 &value);
788 if(type == LTTV_POINTER) {
789 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
790 }
791
792 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
793 LTTV_BEFORE_CHUNK_TRACEFILE,
794 &value);
795 if(type == LTTV_POINTER) {
796 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
797 }
798
799 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
800 LTTV_EVENT_HOOK,
801 &value);
802 if(type == LTTV_POINTER) {
803 event_hook = (LttvHooks*)*(value.v_pointer);
804 }
805
806 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
807 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
808 &value);
809 if(type == LTTV_POINTER) {
810 event_hook_by_id_channel = (LttvHooksByIdChannelArray*)*(value.v_pointer);
811 }
812
813 lttv_process_traceset_begin(tsc,
814 before_chunk_traceset,
815 before_chunk_trace,
816 before_chunk_tracefile,
817 event_hook,
818 event_hook_by_id_channel);
819 }
820
821
822
823 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
824 LttvTracesetContext *tsc)
825 {
826 LttvAttribute *g_attribute = lttv_global_attributes();
827 LttvAttribute *module_attribute;
828 LttvAttributeType type;
829 LttvAttributeValue value;
830 LttvHooks *after_chunk_traceset=NULL;
831 LttvHooks *after_chunk_trace=NULL;
832 LttvHooks *after_chunk_tracefile=NULL;
833 LttvHooks *event_hook=NULL;
834 LttvHooksByIdChannelArray *event_hook_by_id_channel=NULL;
835
836 module_attribute =
837 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
838 LTTV_COMPUTATION));
839 g_assert(module_attribute);
840
841 module_attribute =
842 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
843 LTTV_IATTRIBUTE(module_attribute),
844 module_name));
845 g_assert(module_attribute);
846
847 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
848 LTTV_AFTER_CHUNK_TRACESET,
849 &value);
850 if(type == LTTV_POINTER) {
851 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
852 }
853
854 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
855 LTTV_AFTER_CHUNK_TRACE,
856 &value);
857 if(type == LTTV_POINTER) {
858 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
859 }
860
861 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
862 LTTV_AFTER_CHUNK_TRACEFILE,
863 &value);
864 if(type == LTTV_POINTER) {
865 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
866 }
867
868 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
869 LTTV_EVENT_HOOK,
870 &value);
871 if(type == LTTV_POINTER) {
872 event_hook = (LttvHooks*)*(value.v_pointer);
873 }
874
875 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
876 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
877 &value);
878 if(type == LTTV_POINTER) {
879 event_hook_by_id_channel = (LttvHooksByIdChannelArray*)*(value.v_pointer);
880 }
881
882 lttv_process_traceset_end(tsc,
883 after_chunk_traceset,
884 after_chunk_trace,
885 after_chunk_tracefile,
886 event_hook,
887 event_hook_by_id_channel);
888
889 }
890
891
892 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
893 LttvTrace *trace)
894 {
895 LttvAttribute *attribute = lttv_trace_attribute(trace);
896
897 attribute =
898 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
899 module_name));
900 g_assert(attribute);
901
902 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
903 LTTV_IN_PROGRESS,
904 LTTV_INT);
905 /* the value is left unset. The only presence of the attribute is necessary.
906 */
907 }
908
909 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
910 LttvTrace *trace)
911 {
912 LttvAttribute *attribute = lttv_trace_attribute(trace);
913
914 attribute =
915 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
916 module_name));
917 g_assert(attribute);
918
919 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
920 LTTV_IN_PROGRESS);
921 }
922
923 __EXPORT gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
924 LttvTrace *trace)
925 {
926 LttvAttribute *attribute = lttv_trace_attribute(trace);
927 LttvAttributeType type;
928 LttvAttributeValue value;
929
930 attribute =
931 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
932 module_name));
933 g_assert(attribute);
934
935 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
936 LTTV_IN_PROGRESS,
937 &value);
938 /* The only presence of the attribute is necessary. */
939 if(type == LTTV_NONE)
940 return FALSE;
941 else
942 return TRUE;
943 }
944
945 void lttvwindowtraces_set_ready(LttvAttributeName module_name,
946 LttvTrace *trace)
947 {
948 LttvAttribute *attribute = lttv_trace_attribute(trace);
949
950 attribute =
951 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
952 module_name));
953 g_assert(attribute);
954
955 lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
956 LTTV_READY,
957 LTTV_INT);
958 /* the value is left unset. The only presence of the attribute is necessary.
959 */
960 }
961
962 void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
963 LttvTrace *trace)
964 {
965 LttvAttribute *attribute = lttv_trace_attribute(trace);
966
967 attribute =
968 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
969 module_name));
970 g_assert(attribute);
971
972 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
973 LTTV_READY);
974 }
975
976 __EXPORT gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
977 LttvTrace *trace)
978 {
979 LttvAttribute *attribute = lttv_trace_attribute(trace);
980 LttvAttributeType type;
981 LttvAttributeValue value;
982
983 attribute =
984 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
985 module_name));
986 g_assert(attribute);
987
988 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
989 LTTV_READY,
990 &value);
991 /* The only presence of the attribute is necessary. */
992 if(type == LTTV_NONE)
993 return FALSE;
994 else
995 return TRUE;
996 }
997
998 static gint find_window_widget(MainWindow *a, GtkWidget *b)
999 {
1000 if(a->mwindow == b) return 0;
1001 else return -1;
1002 }
1003
1004
1005 /* lttvwindowtraces_process_pending_requests
1006 *
1007 * Process the pending background computation requests
1008 *
1009 * This internal function gets called by g_idle, taking care of the pending
1010 * requests.
1011 *
1012 */
1013
1014
1015 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
1016 {
1017 LttvTracesetContext *tsc;
1018 LttvTracesetStats *tss;
1019 LttvTraceset *ts;
1020 //LttvTracesetContextPosition *sync_position;
1021 LttvAttribute *attribute;
1022 LttvAttribute *g_attribute = lttv_global_attributes();
1023 GSList **list_out, **list_in, **notify_in, **notify_out;
1024 LttvAttributeValue value;
1025 LttvAttributeType type;
1026 gboolean ret_val;
1027
1028 if(trace == NULL)
1029 return FALSE;
1030
1031 if(lttvwindow_preempt_count > 0) return TRUE;
1032
1033 attribute = lttv_trace_attribute(trace);
1034
1035 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1036 LTTV_REQUESTS_QUEUE,
1037 &value);
1038 g_assert(type == LTTV_POINTER);
1039 list_out = (GSList**)(value.v_pointer);
1040
1041 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1042 LTTV_REQUESTS_CURRENT,
1043 &value);
1044 g_assert(type == LTTV_POINTER);
1045 list_in = (GSList**)(value.v_pointer);
1046
1047 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1048 LTTV_NOTIFY_QUEUE,
1049 &value);
1050 g_assert(type == LTTV_POINTER);
1051 notify_out = (GSList**)(value.v_pointer);
1052
1053 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1054 LTTV_NOTIFY_CURRENT,
1055 &value);
1056 g_assert(type == LTTV_POINTER);
1057 notify_in = (GSList**)(value.v_pointer);
1058
1059 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1060 LTTV_COMPUTATION_TRACESET,
1061 &value);
1062 g_assert(type == LTTV_POINTER);
1063 ts = (LttvTraceset*)*(value.v_pointer);
1064
1065 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1066 LTTV_COMPUTATION_TRACESET_CONTEXT,
1067 &value);
1068 g_assert(type == LTTV_POINTER);
1069 tsc = (LttvTracesetContext*)*(value.v_pointer);
1070 tss = (LttvTracesetStats*)*(value.v_pointer);
1071 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
1072 g_assert(LTTV_IS_TRACESET_STATS(tss));
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 /* There is no events requests pending : we should never have been called! */
1081 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
1082 /* 0.1 Lock traces */
1083 {
1084 guint iter_trace=0;
1085
1086 for(iter_trace=0;
1087 iter_trace<lttv_traceset_number(tsc->ts);
1088 iter_trace++) {
1089 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
1090
1091 if(lttvwindowtraces_lock(trace_v) != 0)
1092 return TRUE; /* Cannot get trace lock, try later */
1093
1094 }
1095 }
1096 /* 0.2 Sync tracefiles */
1097 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1098 lttv_process_traceset_synchronize_tracefiles(tsc);
1099 /* 1. Before processing */
1100 {
1101 /* if list_in is empty */
1102 if(g_slist_length(*list_in) == 0) {
1103
1104 {
1105 /* - Add all requests in list_out to list_in, empty list_out */
1106 GSList *iter = *list_out;
1107
1108 while(iter != NULL) {
1109 gboolean remove = FALSE;
1110 gboolean free_data = FALSE;
1111
1112 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1113
1114 remove = TRUE;
1115 free_data = FALSE;
1116 *list_in = g_slist_append(*list_in, bg_req);
1117
1118 /* Go to next */
1119 if(remove)
1120 {
1121 GSList *remove_iter = iter;
1122
1123 iter = g_slist_next(iter);
1124 if(free_data) g_free(remove_iter->data);
1125 *list_out = g_slist_remove_link(*list_out, remove_iter);
1126 } else { // not remove
1127 iter = g_slist_next(iter);
1128 }
1129 }
1130 }
1131
1132 {
1133 GSList *iter = *list_in;
1134 /* - for each request in list_in */
1135 while(iter != NULL) {
1136
1137 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1138 /* - set hooks'in_progress flag to TRUE */
1139 lttvwindowtraces_set_in_progress(bg_req->module_name,
1140 bg_req->trace);
1141
1142 /* - call before request hook */
1143 /* Get before request hook */
1144 LttvAttribute *module_attribute;
1145
1146 module_attribute =
1147 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1148 LTTV_IATTRIBUTE(g_attribute),
1149 LTTV_COMPUTATION));
1150 g_assert(module_attribute);
1151
1152 module_attribute =
1153 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1154 LTTV_IATTRIBUTE(module_attribute),
1155 bg_req->module_name));
1156 g_assert(module_attribute);
1157
1158 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1159 LTTV_BEFORE_REQUEST,
1160 &value);
1161 g_assert(type == LTTV_POINTER);
1162 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1163
1164 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
1165
1166 iter = g_slist_next(iter);
1167 }
1168 }
1169
1170 /* - seek trace to start */
1171 {
1172 LttTime start = { 0, 0};
1173 lttv_process_traceset_seek_time(tsc, start);
1174 }
1175
1176 /* - Move all notifications from notify_out to notify_in. */
1177 {
1178 GSList *iter = *notify_out;
1179 g_assert(g_slist_length(*notify_in) == 0);
1180
1181 while(iter != NULL) {
1182 gboolean remove = FALSE;
1183 gboolean free_data = FALSE;
1184
1185 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1186
1187 remove = TRUE;
1188 free_data = FALSE;
1189 *notify_in = g_slist_append(*notify_in, notify_req);
1190
1191 /* Go to next */
1192 if(remove)
1193 {
1194 GSList *remove_iter = iter;
1195
1196 iter = g_slist_next(iter);
1197 if(free_data)
1198 notify_request_free((BackgroundNotify*)remove_iter->data);
1199 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
1200 } else { // not remove
1201 iter = g_slist_next(iter);
1202 }
1203 }
1204 }
1205 {
1206 GSList *iter = *list_in;
1207 LttvHooks *hook_adder = lttv_hooks_new();
1208 /* - for each request in list_in */
1209 while(iter != NULL) {
1210
1211 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1212 /*- add hooks to context*/
1213 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1214 tsc,
1215 hook_adder);
1216 iter = g_slist_next(iter);
1217 }
1218 lttv_hooks_call(hook_adder,tsc);
1219 lttv_hooks_destroy(hook_adder);
1220 }
1221
1222
1223 }
1224
1225 {
1226 GSList *iter = *list_in;
1227 /* - for each request in list_in */
1228 while(iter != NULL) {
1229
1230 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1231 /*- Call before chunk hooks for list_in*/
1232 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1233 tsc);
1234 iter = g_slist_next(iter);
1235 }
1236 }
1237
1238 }
1239 /* 2. call process traceset middle for a chunk */
1240 {
1241 /*(assert list_in is not empty! : should not even be called in that case)*/
1242 LttTime end = ltt_time_infinite;
1243 g_assert(g_slist_length(*list_in) != 0);
1244
1245 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1246 }
1247
1248 /* 3. After the chunk */
1249 {
1250 /* 3.1 call after_chunk hooks for list_in */
1251 {
1252 GSList *iter = *list_in;
1253 /* - for each request in list_in */
1254 while(iter != NULL) {
1255
1256 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1257 /* - Call after chunk hooks for list_in */
1258 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1259 tsc);
1260 iter = g_slist_next(iter);
1261 }
1262 }
1263
1264 /* 3.2 for each notify_in */
1265 {
1266 GSList *iter = *notify_in;
1267 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1268
1269 while(iter != NULL) {
1270 gboolean remove = FALSE;
1271 gboolean free_data = FALSE;
1272
1273 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1274
1275 /* - if current time >= notify time, call notify and remove from
1276 * notify_in.
1277 * - if current position >= notify position, call notify and remove
1278 * from notify_in.
1279 */
1280 if( (tfc != NULL &&
1281 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
1282 ||
1283 (notify_req->notify_position != NULL &&
1284 lttv_traceset_context_ctx_pos_compare(tsc,
1285 notify_req->notify_position) >= 0)
1286 ) {
1287
1288 lttv_hooks_call(notify_req->notify, notify_req);
1289
1290 remove = TRUE;
1291 free_data = TRUE;
1292 }
1293
1294 /* Go to next */
1295 if(remove)
1296 {
1297 GSList *remove_iter = iter;
1298
1299 iter = g_slist_next(iter);
1300 if(free_data)
1301 notify_request_free((BackgroundNotify*)remove_iter->data);
1302 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1303 } else { // not remove
1304 iter = g_slist_next(iter);
1305 }
1306 }
1307 }
1308
1309 {
1310 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1311 /* 3.3 if end of trace reached */
1312 if(tfc != NULL)
1313 g_debug("Current time : %lu sec, %lu nsec",
1314 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
1315 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1316 tsc->time_span.end_time) > 0) {
1317
1318 {
1319 GSList *iter = *list_in;
1320 LttvHooks *hook_remover = lttv_hooks_new();
1321 /* - for each request in list_in */
1322 while(iter != NULL) {
1323
1324 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1325 /* - remove hooks from context */
1326 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1327 tsc,
1328 hook_remover);
1329 iter = g_slist_next(iter);
1330 }
1331 lttv_hooks_call(hook_remover,tsc);
1332 lttv_hooks_destroy(hook_remover);
1333 }
1334
1335 /* - for each request in list_in */
1336 {
1337 GSList *iter = *list_in;
1338
1339 while(iter != NULL) {
1340 gboolean remove = FALSE;
1341 gboolean free_data = FALSE;
1342
1343 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1344
1345 /* - set hooks'in_progress flag to FALSE */
1346 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1347 bg_req->trace);
1348 /* - set hooks'ready flag to TRUE */
1349 lttvwindowtraces_set_ready(bg_req->module_name,
1350 bg_req->trace);
1351 /* - call after request hook */
1352 /* Get after request hook */
1353 LttvAttribute *module_attribute;
1354
1355 module_attribute =
1356 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1357 LTTV_IATTRIBUTE(g_attribute),
1358 LTTV_COMPUTATION));
1359 g_assert(module_attribute);
1360
1361 module_attribute =
1362 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1363 LTTV_IATTRIBUTE(module_attribute),
1364 bg_req->module_name));
1365 g_assert(module_attribute);
1366
1367 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1368 LTTV_AFTER_REQUEST,
1369 &value);
1370 g_assert(type == LTTV_POINTER);
1371 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1372 {
1373 struct sum_traceset_closure t_closure;
1374 t_closure.tss = (LttvTracesetStats*)tsc;
1375 t_closure.current_time = ltt_time_infinite;
1376 if(after_request != NULL) lttv_hooks_call(after_request,
1377 &t_closure);
1378 }
1379
1380 if(bg_req->dialog != NULL)
1381 gtk_widget_destroy(bg_req->dialog);
1382 GtkWidget *parent_window;
1383 if(g_slist_find_custom(g_main_window_list,
1384 bg_req->parent_window,
1385 (GCompareFunc)find_window_widget))
1386 parent_window = GTK_WIDGET(bg_req->parent_window);
1387 else
1388 parent_window = NULL;
1389
1390 GtkWidget *dialog =
1391 gtk_message_dialog_new(GTK_WINDOW(parent_window),
1392 GTK_DIALOG_DESTROY_WITH_PARENT,
1393 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1394 "Background computation %s finished for trace %s",
1395 g_quark_to_string(bg_req->module_name),
1396 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
1397 if(parent_window != NULL)
1398 gtk_window_set_transient_for(GTK_WINDOW(dialog),
1399 GTK_WINDOW(parent_window));
1400 g_signal_connect_swapped (dialog, "response",
1401 G_CALLBACK (gtk_widget_destroy),
1402 dialog);
1403 gtk_widget_show(dialog);
1404
1405 /* - remove request */
1406 remove = TRUE;
1407 free_data = TRUE;
1408
1409 /* Go to next */
1410 if(remove)
1411 {
1412 GSList *remove_iter = iter;
1413
1414 iter = g_slist_next(iter);
1415 if(free_data) g_free(remove_iter->data);
1416 *list_in = g_slist_remove_link(*list_in, remove_iter);
1417 } else { // not remove
1418 iter = g_slist_next(iter);
1419 }
1420 }
1421 }
1422
1423 /* - for each notifications in notify_in */
1424 {
1425 GSList *iter = *notify_in;
1426
1427 while(iter != NULL) {
1428 gboolean remove = FALSE;
1429 gboolean free_data = FALSE;
1430
1431 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1432
1433 /* - call notify and remove from notify_in */
1434 lttv_hooks_call(notify_req->notify, notify_req);
1435 remove = TRUE;
1436 free_data = TRUE;
1437
1438 /* Go to next */
1439 if(remove)
1440 {
1441 GSList *remove_iter = iter;
1442
1443 iter = g_slist_next(iter);
1444 if(free_data)
1445 notify_request_free((BackgroundNotify*)remove_iter->data);
1446 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1447 } else { // not remove
1448 iter = g_slist_next(iter);
1449 }
1450 }
1451 }
1452 {
1453 /* - reset the context */
1454 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1455 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1456 }
1457 /* - if list_out is empty */
1458 if(g_slist_length(*list_out) == 0) {
1459 /* - return FALSE (scheduler stopped) */
1460 g_debug("Background computation scheduler stopped");
1461 g_info("Background computation finished for trace %p", trace);
1462 /* FIXME : remove status bar info, need context id and message id */
1463
1464 ret_val = FALSE;
1465 } else {
1466 ret_val = TRUE;
1467 }
1468 } else {
1469 /* 3.4 else, end of trace not reached */
1470 /* - return TRUE (scheduler still registered) */
1471 g_debug("Background computation left");
1472 ret_val = TRUE;
1473 }
1474 }
1475 }
1476 /* 4. Unlock traces */
1477 {
1478 lttv_process_traceset_get_sync_data(tsc);
1479 //lttv_traceset_context_position_save(tsc, sync_position);
1480 guint iter_trace;
1481
1482 for(iter_trace=0;
1483 iter_trace<lttv_traceset_number(tsc->ts);
1484 iter_trace++) {
1485 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1486
1487 lttvwindowtraces_unlock(trace_v);
1488 }
1489 }
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 LttvHooksById *event_hook_by_id_channel,
1513 LttvHooks *hook_adder,
1514 LttvHooks *hook_remover)
1515 {
1516 LttvAttribute *g_attribute = lttv_global_attributes();
1517 LttvAttribute *attribute;
1518 LttvAttributeValue value;
1519 gboolean result;
1520
1521 attribute =
1522 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1523 LTTV_COMPUTATION));
1524 g_assert(attribute);
1525
1526 attribute =
1527 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1528 module_name));
1529 g_assert(attribute);
1530
1531 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1532 LTTV_BEFORE_CHUNK_TRACESET,
1533 LTTV_POINTER,
1534 &value);
1535 g_assert(result);
1536
1537 *(value.v_pointer) = before_chunk_traceset;
1538
1539 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1540 LTTV_BEFORE_CHUNK_TRACE,
1541 LTTV_POINTER,
1542 &value);
1543 g_assert(result);
1544 *(value.v_pointer) = before_chunk_trace;
1545
1546 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1547 LTTV_BEFORE_CHUNK_TRACEFILE,
1548 LTTV_POINTER,
1549 &value);
1550 g_assert(result);
1551 *(value.v_pointer) = before_chunk_tracefile;
1552
1553 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1554 LTTV_AFTER_CHUNK_TRACESET,
1555 LTTV_POINTER,
1556 &value);
1557 g_assert(result);
1558 *(value.v_pointer) = after_chunk_traceset;
1559
1560 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1561 LTTV_AFTER_CHUNK_TRACE,
1562 LTTV_POINTER,
1563 &value);
1564 g_assert(result);
1565 *(value.v_pointer) = after_chunk_trace;
1566
1567 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1568 LTTV_AFTER_CHUNK_TRACEFILE,
1569 LTTV_POINTER,
1570 &value);
1571 g_assert(result);
1572 *(value.v_pointer) = after_chunk_tracefile;
1573
1574 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1575 LTTV_BEFORE_REQUEST,
1576 LTTV_POINTER,
1577 &value);
1578 g_assert(result);
1579 *(value.v_pointer) = before_request;
1580
1581 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1582 LTTV_AFTER_REQUEST,
1583 LTTV_POINTER,
1584 &value);
1585 g_assert(result);
1586 *(value.v_pointer) = after_request;
1587
1588 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1589 LTTV_EVENT_HOOK,
1590 LTTV_POINTER,
1591 &value);
1592 g_assert(result);
1593 *(value.v_pointer) = event_hook;
1594
1595 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1596 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
1597 LTTV_POINTER,
1598 &value);
1599 g_assert(result);
1600 *(value.v_pointer) = event_hook_by_id_channel;
1601
1602 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1603 LTTV_HOOK_ADDER,
1604 LTTV_POINTER,
1605 &value);
1606 g_assert(result);
1607 *(value.v_pointer) = hook_adder;
1608
1609 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1610 LTTV_HOOK_REMOVER,
1611 LTTV_POINTER,
1612 &value);
1613 g_assert(result);
1614 *(value.v_pointer) = hook_remover;
1615
1616 }
1617
1618
1619 /**
1620 * It removes all the requests that can be currently processed by the
1621 * background computation algorithm for all the traces (list_in and list_out).
1622 *
1623 * Leaves the flag to in_progress or none.. depending if current or queue
1624 *
1625 * @param module_name A GQuark : the name of the module which computes the
1626 * information.
1627 */
1628 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1629 {
1630 guint i;
1631 gboolean result;
1632
1633 for(i=0;i<lttvwindowtraces_get_number();i++) {
1634 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1635 g_assert(trace_v != NULL);
1636 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1637 LttvAttributeValue value;
1638 GSList **queue, **current;
1639 GSList *iter;
1640
1641 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1642 LTTV_REQUESTS_QUEUE,
1643 LTTV_POINTER,
1644 &value);
1645 g_assert(result);
1646
1647 queue = (GSList**)(value.v_pointer);
1648
1649 iter = *queue;
1650 while(iter != NULL) {
1651 gboolean remove = FALSE;
1652 gboolean free_data = FALSE;
1653
1654 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1655
1656 if(bg_req->module_name == module_name) {
1657 remove = TRUE;
1658 free_data = TRUE;
1659 }
1660
1661 /* Go to next */
1662 if(remove)
1663 {
1664 GSList *remove_iter = iter;
1665
1666 iter = g_slist_next(iter);
1667 if(free_data) g_free(remove_iter->data);
1668 *queue = g_slist_remove_link(*queue, remove_iter);
1669 } else { // not remove
1670 iter = g_slist_next(iter);
1671 }
1672 }
1673
1674
1675 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1676 LTTV_REQUESTS_CURRENT,
1677 LTTV_POINTER,
1678 &value);
1679 g_assert(result);
1680
1681 current = (GSList**)(value.v_pointer);
1682
1683 iter = *current;
1684 while(iter != NULL) {
1685 gboolean remove = FALSE;
1686 gboolean free_data = FALSE;
1687
1688 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1689
1690 if(bg_req->module_name == module_name) {
1691 remove = TRUE;
1692 free_data = TRUE;
1693 }
1694
1695 /* Go to next */
1696 if(remove)
1697 {
1698 GSList *remove_iter = iter;
1699
1700 iter = g_slist_next(iter);
1701 if(free_data) g_free(remove_iter->data);
1702 *current = g_slist_remove_link(*current, remove_iter);
1703 } else { // not remove
1704 iter = g_slist_next(iter);
1705 }
1706 }
1707 }
1708 }
1709
1710
1711 /**
1712 * Unregister the background computation hooks for a specific module.
1713 *
1714 * It also removes all the requests that can be currently processed by the
1715 * background computation algorithm for all the traces (list_in and list_out).
1716 *
1717 * @param module_name A GQuark : the name of the module which computes the
1718 * information.
1719 */
1720
1721 void lttvwindowtraces_unregister_computation_hooks
1722 (LttvAttributeName module_name)
1723 {
1724 LttvAttribute *g_attribute = lttv_global_attributes();
1725 LttvAttribute *attribute;
1726 LttvAttributeValue value;
1727 gboolean result;
1728
1729 attribute =
1730 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1731 LTTV_COMPUTATION));
1732 g_assert(attribute);
1733
1734 attribute =
1735 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1736 module_name));
1737 g_assert(attribute);
1738
1739 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1740 LTTV_BEFORE_CHUNK_TRACESET,
1741 LTTV_POINTER,
1742 &value);
1743 g_assert(result);
1744
1745 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1746 if(before_chunk_traceset != NULL)
1747 lttv_hooks_destroy(before_chunk_traceset);
1748
1749 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1750 LTTV_BEFORE_CHUNK_TRACE,
1751 LTTV_POINTER,
1752 &value);
1753 g_assert(result);
1754
1755 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1756 if(before_chunk_trace != NULL)
1757 lttv_hooks_destroy(before_chunk_trace);
1758
1759 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1760 LTTV_BEFORE_CHUNK_TRACEFILE,
1761 LTTV_POINTER,
1762 &value);
1763 g_assert(result);
1764
1765 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1766 if(before_chunk_tracefile != NULL)
1767 lttv_hooks_destroy(before_chunk_tracefile);
1768
1769 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1770 LTTV_AFTER_CHUNK_TRACESET,
1771 LTTV_POINTER,
1772 &value);
1773 g_assert(result);
1774
1775 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1776 if(after_chunk_traceset != NULL)
1777 lttv_hooks_destroy(after_chunk_traceset);
1778
1779 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1780 LTTV_AFTER_CHUNK_TRACE,
1781 LTTV_POINTER,
1782 &value);
1783 g_assert(result);
1784
1785 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1786 if(after_chunk_trace != NULL)
1787 lttv_hooks_destroy(after_chunk_trace);
1788
1789 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1790 LTTV_AFTER_CHUNK_TRACEFILE,
1791 LTTV_POINTER,
1792 &value);
1793 g_assert(result);
1794
1795 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1796 if(after_chunk_tracefile != NULL)
1797 lttv_hooks_destroy(after_chunk_tracefile);
1798
1799 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1800 LTTV_BEFORE_REQUEST,
1801 LTTV_POINTER,
1802 &value);
1803 g_assert(result);
1804
1805 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1806 if(before_request != NULL)
1807 lttv_hooks_destroy(before_request);
1808
1809 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1810 LTTV_AFTER_REQUEST,
1811 LTTV_POINTER,
1812 &value);
1813 g_assert(result);
1814
1815 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1816 if(after_request != NULL)
1817 lttv_hooks_destroy(after_request);
1818
1819 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1820 LTTV_EVENT_HOOK,
1821 LTTV_POINTER,
1822 &value);
1823 g_assert(result);
1824
1825 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1826 if(event_hook != NULL)
1827 lttv_hooks_destroy(event_hook);
1828
1829 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1830 LTTV_EVENT_HOOK_BY_ID_CHANNEL,
1831 LTTV_POINTER,
1832 &value);
1833 g_assert(result);
1834
1835 LttvHooksByIdChannelArray *event_hook_by_id_channel = (LttvHooksByIdChannelArray*)*(value.v_pointer);
1836 if(event_hook_by_id_channel != NULL)
1837 lttv_hooks_by_id_channel_destroy(event_hook_by_id_channel);
1838
1839 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1840 LTTV_HOOK_ADDER,
1841 LTTV_POINTER,
1842 &value);
1843 g_assert(result);
1844
1845 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1846 if(hook_adder != NULL)
1847 lttv_hooks_destroy(hook_adder);
1848
1849 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1850 LTTV_HOOK_REMOVER,
1851 LTTV_POINTER,
1852 &value);
1853 g_assert(result);
1854
1855 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1856 if(hook_remover != NULL)
1857 lttv_hooks_destroy(hook_remover);
1858
1859
1860 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1861 LTTV_EVENT_HOOK_BY_ID_CHANNEL);
1862 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1863 LTTV_EVENT_HOOK);
1864
1865 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1866 LTTV_AFTER_REQUEST);
1867 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1868 LTTV_BEFORE_REQUEST);
1869
1870 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1871 LTTV_AFTER_CHUNK_TRACEFILE);
1872 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1873 LTTV_AFTER_CHUNK_TRACE);
1874 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1875 LTTV_AFTER_CHUNK_TRACESET);
1876
1877 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1878 LTTV_BEFORE_CHUNK_TRACEFILE);
1879 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1880 LTTV_BEFORE_CHUNK_TRACE);
1881 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1882 LTTV_BEFORE_CHUNK_TRACESET);
1883 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1884 LTTV_HOOK_ADDER);
1885 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1886 LTTV_HOOK_REMOVER);
1887
1888 /* finally, remove module name */
1889 attribute =
1890 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1891 LTTV_COMPUTATION));
1892 g_assert(attribute);
1893 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1894 module_name);
1895
1896 }
1897
1898 /**
1899 * Lock a trace so no other instance can use it.
1900 *
1901 * @param trace The trace to lock.
1902 * @return 0 on success, -1 if cannot get lock.
1903 */
1904 gint lttvwindowtraces_lock(LttvTrace *trace)
1905 {
1906 LttvAttribute *attribute = lttv_trace_attribute(trace);
1907 LttvAttributeValue value;
1908 LttvAttributeType type;
1909
1910 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1911 LTTV_LOCK,
1912 &value);
1913 /* Verify the absence of the lock. */
1914 if(type != LTTV_NONE) {
1915 g_critical("Cannot take trace lock");
1916 return -1;
1917 }
1918
1919 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1920 LTTV_LOCK,
1921 LTTV_INT);
1922 /* the value is left unset. The only presence of the attribute is necessary.
1923 */
1924
1925 return 0;
1926 }
1927
1928 /**
1929 * Unlock a trace.
1930 *
1931 * @param trace The trace to unlock.
1932 * @return 0 on success, -1 if cannot unlock (not locked ?).
1933 */
1934 gint lttvwindowtraces_unlock(LttvTrace *trace)
1935 {
1936 LttvAttribute *attribute = lttv_trace_attribute(trace);
1937 LttvAttributeType type;
1938 LttvAttributeValue value;
1939
1940 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1941 LTTV_LOCK,
1942 &value);
1943 /* Verify the presence of the lock. */
1944 if(type == LTTV_NONE) {
1945 g_critical("Cannot release trace lock");
1946 return -1;
1947 }
1948
1949 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1950 LTTV_LOCK);
1951
1952 return 0;
1953 }
1954
1955 /**
1956 * Verify if a trace is locked.
1957 *
1958 * @param trace The trace to verify.
1959 * @return TRUE if locked, FALSE is unlocked.
1960 */
1961 gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1962 {
1963 LttvAttribute *attribute = lttv_trace_attribute(trace);
1964 LttvAttributeType type;
1965 LttvAttributeValue value;
1966
1967 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1968 LTTV_LOCK,
1969 &value);
1970 /* The only presence of the attribute is necessary. */
1971 if(type == LTTV_NONE)
1972 return FALSE;
1973 else
1974 return TRUE;
1975 }
1976
This page took 0.087285 seconds and 3 git commands to generate.