update compat
[lttv.git] / tags / lttv-0.11.3-23102008 / lttv / modules / gui / lttvwindow / lttvwindow / lttvwindowtraces.c
CommitLineData
13ab9fcb 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
32#include <ltt/time.h>
33#include <ltt/trace.h>
34#include <glib.h>
35#include <lttv/lttv.h>
36#include <lttv/traceset.h>
37#include <lttv/attribute.h>
38#include <lttv/tracecontext.h>
39#include <lttvwindow/lttvwindowtraces.h>
40#include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
41#include <lttvwindow/mainwindow-private.h> /* for main window structure */
42
43extern GSList * g_main_window_list;
44
45typedef struct _BackgroundRequest {
46 LttvAttributeName module_name; /* Hook path in global attributes,
47 where all standard hooks under computation/.
48 i.e. modulename */
49 LttvTrace *trace; /* trace concerned */
50 GtkWidget *dialog; /* Dialog linked with the request, may be NULL */
51 GtkWidget *parent_window; /* Parent window the dialog must be transient for */
52} BackgroundRequest;
53
54typedef struct _BackgroundNotify {
55 gpointer owner;
56 LttvTrace *trace; /* trace */
57 LttTime notify_time;
58 LttvTracesetContextPosition *notify_position;
59 LttvHooks *notify; /* Hook to call when the notify is
60 passed, or at the end of trace */
61} BackgroundNotify;
62
63
64
65/* Prototypes */
66gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
67
68/* Get a trace by its path name.
69 *
70 * @param path path of the trace on the virtual file system.
71 * @return Pointer to trace if found
72 * NULL is returned if the trace is not present
73 */
74
75__EXPORT LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
76{
77 guint i;
78
79 for(i=0;i<lttvwindowtraces_get_number();i++) {
80 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
81 LttTrace *trace;
82 gchar *name;
83 g_assert(trace_v != NULL);
84
85 trace = lttv_trace(trace_v);
86 g_assert(trace != NULL);
87 name = g_quark_to_string(ltt_trace_name(trace));
88
89 if(strcmp(name, path) == 0) {
90 /* Found */
91 return trace_v;
92 }
93 }
94
95 return NULL;
96}
97
98/* Get a trace by its number identifier */
99
100__EXPORT LttvTrace *lttvwindowtraces_get_trace(guint num)
101{
102 LttvAttribute *g_attribute = lttv_global_attributes();
103 LttvAttribute *attribute;
104 LttvAttributeType type;
105 LttvAttributeName name;
106 LttvAttributeValue value;
107 gboolean is_named;
108
109 attribute =
110 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
111 LTTV_TRACES));
112 g_assert(attribute);
113
114 type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value,
115 &is_named);
116
117 if(type == LTTV_POINTER) {
118 return (LttvTrace *)*(value.v_pointer);
119 }
120
121 return NULL;
122}
123
124/* Total number of traces */
125
126__EXPORT guint lttvwindowtraces_get_number()
127{
128 LttvAttribute *g_attribute = lttv_global_attributes();
129 LttvAttribute *attribute;
130
131 attribute =
132 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
133 LTTV_TRACES));
134 g_assert(attribute);
135
136 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute)) );
137}
138
139/* Add a trace to the global attributes */
140
141void lttvwindowtraces_add_trace(LttvTrace *trace)
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
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, "%llu:%llu", buf.st_dev, buf.st_ino);
157 g_assert(result >= 0);
158
159 attribute =
160 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
161 LTTV_TRACES));
162 g_assert(attribute);
163
164 value = lttv_attribute_add(attribute,
165 g_quark_from_string(attribute_path),
166 LTTV_POINTER);
167
168 *(value.v_pointer) = (gpointer)trace;
169
170 /* create new traceset and tracesetcontext */
171 LttvTraceset *ts;
172 LttvTracesetStats *tss;
173 //LttvTracesetContextPosition *sync_position;
174
175 attribute = lttv_trace_attribute(trace);
176 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
177 LTTV_COMPUTATION_TRACESET,
178 LTTV_POINTER,
179 &value);
180 g_assert(result_b);
181
182 ts = lttv_traceset_new();
183 *(value.v_pointer) = ts;
184
185 lttv_traceset_add(ts,trace);
186
187 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
188 LTTV_COMPUTATION_TRACESET_CONTEXT,
189 LTTV_POINTER,
190 &value);
191 g_assert(result_b);
192
193 tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
194 *(value.v_pointer) = tss;
195
196 lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
197#if 0
198 result_b = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
199 LTTV_COMPUTATION_SYNC_POSITION,
200 LTTV_POINTER,
201 &value);
202 g_assert(result_b);
203
204 sync_position = lttv_traceset_context_position_new();
205 *(value.v_pointer) = sync_position;
206#endif //0
207 value = lttv_attribute_add(attribute,
208 LTTV_REQUESTS_QUEUE,
209 LTTV_POINTER);
210
211 value = lttv_attribute_add(attribute,
212 LTTV_REQUESTS_CURRENT,
213 LTTV_POINTER);
214
215 value = lttv_attribute_add(attribute,
216 LTTV_NOTIFY_QUEUE,
217 LTTV_POINTER);
218
219 value = lttv_attribute_add(attribute,
220 LTTV_NOTIFY_CURRENT,
221 LTTV_POINTER);
222}
223
224/* Remove a trace from the global attributes */
225
226void lttvwindowtraces_remove_trace(LttvTrace *trace)
227{
228 LttvAttribute *g_attribute = lttv_global_attributes();
229 LttvAttribute *attribute;
230 LttvAttributeValue value;
231 guint i;
232 gboolean result;
233
234 attribute =
235 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
236 LTTV_TRACES));
237 g_assert(attribute);
238
239 for(i=0;i<lttvwindowtraces_get_number();i++) {
240 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
241
242 g_assert(trace_v != NULL);
243
244 /* Remove and background computation that could be in progress */
245 g_idle_remove_by_data(trace_v);
246
247 if(trace_v == trace) {
248 /* Found */
249 LttvAttribute *l_attribute;
250
251 /* destroy traceset and tracesetcontext */
252 LttvTraceset *ts;
253 LttvTracesetStats *tss;
254 //LttvTracesetContextPosition *sync_position;
255
256 l_attribute = lttv_trace_attribute(trace);
257
258
259 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
260 LTTV_REQUESTS_QUEUE);
261
262 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
263 LTTV_REQUESTS_CURRENT);
264
265 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
266 LTTV_NOTIFY_QUEUE);
267
268 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
269 LTTV_NOTIFY_CURRENT);
270
271 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
272 LTTV_COMPUTATION_TRACESET,
273 LTTV_POINTER,
274 &value);
275 g_assert(result);
276
277 ts = (LttvTraceset*)*(value.v_pointer);
278#if 0
279 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
280 LTTV_COMPUTATION_SYNC_POSITION,
281 LTTV_POINTER,
282 &value);
283 g_assert(result);
284
285 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
286 lttv_traceset_context_position_destroy(sync_position);
287
288 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
289 LTTV_COMPUTATION_SYNC_POSITION);
290
291#endif //0
292 result = lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
293 LTTV_COMPUTATION_TRACESET_CONTEXT,
294 LTTV_POINTER,
295 &value);
296 g_assert(result);
297
298 tss = (LttvTracesetStats*)*(value.v_pointer);
299
300 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
301 g_object_unref(tss);
302 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
303 LTTV_COMPUTATION_TRACESET_CONTEXT);
304 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
305 LTTV_COMPUTATION_TRACESET);
306 /* Destroy the traceset and the trace also */
307 lttv_traceset_destroy(ts);
308
309 /* finally, remove the global attribute */
310 lttv_attribute_remove(attribute, i);
311
312 return;
313 }
314 }
315}
316
317static void destroy_dialog(BackgroundRequest *bg_req)
318{
319 gtk_widget_destroy(bg_req->dialog);
320 bg_req->dialog = NULL;
321}
322
323
324/**
325 * Function to request data from a specific trace
326 *
327 * The memory allocated for the request will be managed by the API.
328 *
329 * @param widget the current Window
330 * @param trace the trace to compute
331 * @param module_name the name of the module which registered global computation
332 * hooks.
333 */
334
335__EXPORT void lttvwindowtraces_background_request_queue
336 (GtkWidget *widget, LttvTrace *trace, gchar *module_name)
337{
338 BackgroundRequest *bg_req;
339 LttvAttribute *attribute = lttv_trace_attribute(trace);
340 LttvAttribute *g_attribute = lttv_global_attributes();
341 LttvAttribute *module_attribute;
342 LttvAttributeValue value;
343 LttvAttributeType type;
344 GSList **slist;
345 gboolean result;
346
347 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
348 LTTV_REQUESTS_QUEUE,
349 LTTV_POINTER,
350 &value);
351 g_assert(result);
352
353 slist = (GSList**)(value.v_pointer);
354
355 /* Verify that the calculator is loaded */
356 module_attribute =
357 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
358 LTTV_COMPUTATION));
359 g_assert(module_attribute);
360
361 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
362 g_quark_from_string(module_name),
363 &value);
364 if(type == LTTV_NONE) {
365 g_critical("Missing background calculator %s", module_name);
366 return;
367 }
368
369 bg_req = g_new(BackgroundRequest,1);
370 bg_req->module_name = g_quark_from_string(module_name);
371 bg_req->trace = trace;
372
373 *slist = g_slist_append(*slist, bg_req);
374
375 /* Priority lower than live servicing */
376 g_idle_remove_by_data(trace);
377 g_idle_add_full((G_PRIORITY_HIGH_IDLE + 23),
378 (GSourceFunc)lttvwindowtraces_process_pending_requests,
379 trace,
380 NULL);
381 /* FIXME : show message in status bar, need context and message id */
382 g_info("Background computation for %s started for trace %p", module_name,
383 trace);
384 GtkWidget *dialog =
385 gtk_message_dialog_new(
386 GTK_WINDOW(widget),
387 GTK_DIALOG_DESTROY_WITH_PARENT,
388 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
389 "Background computation for %s started for trace %s",
390 module_name,
391 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
392 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(widget));
393 g_signal_connect_swapped (dialog, "response",
394 G_CALLBACK (destroy_dialog),
395 bg_req);
396 bg_req->dialog = dialog;
397 /* the parent window might vanish : only use this pointer for a
398 * comparison with existing windows */
399 bg_req->parent_window = gtk_widget_get_toplevel(widget);
400 gtk_widget_show(dialog);
401}
402
403/**
404 * Remove a background request from a trace.
405 *
406 * This should ONLY be used by the modules which registered the global hooks
407 * (module_name). If this is called by the viewers, it may lead to incomplete
408 * and incoherent background processing information.
409 *
410 * Even if the module which deals with the hooks removes the background
411 * requests, it may cause a problem if the module gets loaded again in the
412 * session : the data will be partially calculated. The calculation function
413 * must deal with this case correctly.
414 *
415 * @param trace the trace to compute
416 * @param module_name the name of the module which registered global computation
417 * hooks.
418 */
419
420void lttvwindowtraces_background_request_remove
421 (LttvTrace *trace, gchar *module_name)
422{
423 LttvAttribute *attribute = lttv_trace_attribute(trace);
424 LttvAttributeValue value;
425 GSList *iter = NULL;
426 GSList **slist;
427 gboolean result;
428
429 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
430 LTTV_REQUESTS_QUEUE,
431 LTTV_POINTER,
432 &value);
433 g_assert(result);
434
435 slist = (GSList**)(value.v_pointer);
436
437 for(iter=*slist;iter!=NULL;) {
438 BackgroundRequest *bg_req =
439 (BackgroundRequest *)iter->data;
440
441 if(bg_req->module_name == g_quark_from_string(module_name)) {
442 GSList *rem_iter = iter;
443 iter=g_slist_next(iter);
444 g_free(bg_req);
445 *slist = g_slist_delete_link(*slist, rem_iter);
446 } else {
447 iter=g_slist_next(iter);
448 }
449 }
450}
451
452/**
453 * Find a background request in a trace
454 *
455 */
456
457__EXPORT gboolean lttvwindowtraces_background_request_find
458 (LttvTrace *trace, gchar *module_name)
459{
460 LttvAttribute *attribute = lttv_trace_attribute(trace);
461 LttvAttributeValue value;
462 GSList *iter = NULL;
463 GSList **slist;
464 gboolean result;
465
466 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
467 LTTV_REQUESTS_QUEUE,
468 LTTV_POINTER,
469 &value);
470 g_assert(result);
471
472 slist = (GSList**)(value.v_pointer);
473
474 for(iter=*slist;iter!=NULL;) {
475 BackgroundRequest *bg_req =
476 (BackgroundRequest *)iter->data;
477
478 if(bg_req->module_name == g_quark_from_string(module_name)) {
479 return TRUE;
480 } else {
481 iter=g_slist_next(iter);
482 }
483 }
484 return FALSE;
485}
486
487/**
488 * Register a callback to be called when requested data is passed in the next
489 * queued background processing.
490 *
491 * @param owner owner of the background notification
492 * @param trace the trace computed
493 * @param notify_time time when notification hooks must be called
494 * @param notify_position position when notification hooks must be called
495 * @param notify Hook to call when the notify position is passed
496 */
497
498__EXPORT void lttvwindowtraces_background_notify_queue
499 (gpointer owner,
500 LttvTrace *trace,
501 LttTime notify_time,
502 const LttvTracesetContextPosition *notify_position,
503 const LttvHooks *notify)
504{
505 BackgroundNotify *bg_notify;
506 LttvAttribute *attribute = lttv_trace_attribute(trace);
507 LttvAttributeValue value;
508 GSList **slist;
509 gboolean result;
510
511 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
512 LTTV_NOTIFY_QUEUE,
513 LTTV_POINTER,
514 &value);
515 g_assert(result);
516
517 slist = (GSList**)(value.v_pointer);
518
519 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
520 LTTV_COMPUTATION_TRACESET_CONTEXT,
521 LTTV_POINTER,
522 &value);
523 g_assert(result);
524
525 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
526
527 bg_notify = g_new(BackgroundNotify,1);
528
529 bg_notify->owner = owner;
530 bg_notify->trace = trace;
531 bg_notify->notify_time = notify_time;
532 if(notify_position != NULL) {
533 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
534 lttv_traceset_context_position_copy(bg_notify->notify_position,
535 notify_position);
536 } else {
537 bg_notify->notify_position = NULL;
538 }
539
540 bg_notify->notify = lttv_hooks_new();
541 lttv_hooks_add_list(bg_notify->notify, notify);
542
543 *slist = g_slist_append(*slist, bg_notify);
544}
545
546/**
547 * Register a callback to be called when requested data is passed in the current
548 * background processing.
549 *
550 * @param owner owner of the background notification
551 * @param trace the trace computed
552 * @param notify_time time when notification hooks must be called
553 * @param notify_position position when notification hooks must be called
554 * @param notify Hook to call when the notify position is passed
555 */
556
557__EXPORT void lttvwindowtraces_background_notify_current
558 (gpointer owner,
559 LttvTrace *trace,
560 LttTime notify_time,
561 const LttvTracesetContextPosition *notify_position,
562 const LttvHooks *notify)
563{
564 BackgroundNotify *bg_notify;
565 LttvAttribute *attribute = lttv_trace_attribute(trace);
566 LttvAttributeValue value;
567 GSList **slist;
568 gboolean result;
569
570 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
571 LTTV_NOTIFY_CURRENT,
572 LTTV_POINTER,
573 &value);
574 g_assert(result);
575
576 slist = (GSList**)(value.v_pointer);
577
578 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
579 LTTV_COMPUTATION_TRACESET_CONTEXT,
580 LTTV_POINTER,
581 &value);
582 g_assert(result);
583
584 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
585
586
587 bg_notify = g_new(BackgroundNotify,1);
588
589 bg_notify->owner = owner;
590 bg_notify->trace = trace;
591 bg_notify->notify_time = notify_time;
592 if(notify_position!= NULL) {
593 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
594 lttv_traceset_context_position_copy(bg_notify->notify_position,
595 notify_position);
596 } else {
597 bg_notify->notify_position = NULL;
598 }
599 bg_notify->notify = lttv_hooks_new();
600 lttv_hooks_add_list(bg_notify->notify, notify);
601
602 *slist = g_slist_append(*slist, bg_notify);
603}
604
605
606static void notify_request_free(BackgroundNotify *notify_req)
607{
608 if(notify_req == NULL) return;
609
610 if(notify_req->notify_position != NULL)
611 lttv_traceset_context_position_destroy(notify_req->notify_position);
612 if(notify_req->notify != NULL)
613 lttv_hooks_destroy(notify_req->notify);
614 g_free(notify_req);
615}
616
617/**
618 * Removes all the notifications requests from a specific viewer.
619 *
620 * @param owner owner of the background notification
621 */
622
623__EXPORT void lttvwindowtraces_background_notify_remove(gpointer owner)
624{
625 guint i;
626
627 for(i=0;i<lttvwindowtraces_get_number();i++) {
628 LttvAttribute *attribute;
629 LttvAttributeValue value;
630 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
631 GSList **slist;
632 GSList *iter = NULL;
633 gboolean result;
634
635 g_assert(trace_v != NULL);
636
637 attribute = lttv_trace_attribute(trace_v);
638
639 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
640 LTTV_NOTIFY_QUEUE,
641 LTTV_POINTER,
642 &value);
643 g_assert(result);
644
645 slist = (GSList**)(value.v_pointer);
646
647 for(iter=*slist;iter!=NULL;) {
648
649 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
650
651 if(bg_notify->owner == owner) {
652 GSList *rem_iter = iter;
653 iter=g_slist_next(iter);
654 notify_request_free(bg_notify);
655 *slist = g_slist_remove_link(*slist, rem_iter);
656 } else {
657 iter=g_slist_next(iter);
658 }
659 }
660
661 result = lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
662 LTTV_NOTIFY_CURRENT,
663 LTTV_POINTER,
664 &value);
665 g_assert(result);
666
667 slist = (GSList**)(value.v_pointer);
668
669 for(iter=*slist;iter!=NULL;) {
670
671 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
672
673 if(bg_notify->owner == owner) {
674 GSList *rem_iter = iter;
675 iter=g_slist_next(iter);
676 notify_request_free(bg_notify);
677 *slist = g_slist_remove_link(*slist, rem_iter);
678 } else {
679 iter=g_slist_next(iter);
680 }
681 }
682 }
683}
684
685
686/* Background processing helper functions */
687
688void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
689 LttvTracesetContext *tsc,
690 LttvHooks *hook_adder)
691{
692 LttvAttribute *g_attribute = lttv_global_attributes();
693 LttvAttribute *module_attribute;
694 LttvAttributeType type;
695 LttvAttributeValue value;
696
697
698 module_attribute =
699 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
700 LTTV_COMPUTATION));
701 g_assert(module_attribute);
702
703 module_attribute =
704 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
705 LTTV_IATTRIBUTE(module_attribute),
706 module_name));
707 g_assert(module_attribute);
708
709 /* Call the module's hook adder */
710 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
711 LTTV_HOOK_ADDER,
712 &value);
713 if(type == LTTV_POINTER) {
714 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
715 if(hook_adder != NULL)
716 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
717 }
718}
719
720void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
721 LttvTracesetContext *tsc,
722 LttvHooks *hook_remover)
723{
724 LttvAttribute *g_attribute = lttv_global_attributes();
725 LttvAttribute *module_attribute;
726 LttvAttributeType type;
727 LttvAttributeValue value;
728
729 module_attribute =
730 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
731 LTTV_COMPUTATION));
732 g_assert(module_attribute);
733
734 module_attribute =
735 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
736 LTTV_IATTRIBUTE(module_attribute),
737 module_name));
738 g_assert(module_attribute);
739
740 /* Call the module's hook remover */
741 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
742 LTTV_HOOK_REMOVER,
743 &value);
744 if(type == LTTV_POINTER) {
745 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
746 if(hook_remover != NULL)
747 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
748 }
749}
750
751void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
752 LttvTracesetContext *tsc)
753{
754 LttvAttribute *g_attribute = lttv_global_attributes();
755 LttvAttribute *module_attribute;
756 LttvAttributeType type;
757 LttvAttributeValue value;
758 LttvHooks *before_chunk_traceset=NULL;
759 LttvHooks *before_chunk_trace=NULL;
760 LttvHooks *before_chunk_tracefile=NULL;
761 LttvHooks *event_hook=NULL;
762 LttvHooksById *event_hook_by_id=NULL;
763
764
765 module_attribute =
766 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
767 LTTV_COMPUTATION));
768 g_assert(module_attribute);
769
770 module_attribute =
771 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
772 LTTV_IATTRIBUTE(module_attribute),
773 module_name));
774 g_assert(module_attribute);
775
776 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
777 LTTV_BEFORE_CHUNK_TRACESET,
778 &value);
779 if(type == LTTV_POINTER) {
780 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
781 }
782
783 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
784 LTTV_BEFORE_CHUNK_TRACE,
785 &value);
786 if(type == LTTV_POINTER) {
787 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
788 }
789
790 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
791 LTTV_BEFORE_CHUNK_TRACEFILE,
792 &value);
793 if(type == LTTV_POINTER) {
794 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
795 }
796
797 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
798 LTTV_EVENT_HOOK,
799 &value);
800 if(type == LTTV_POINTER) {
801 event_hook = (LttvHooks*)*(value.v_pointer);
802 }
803
804 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
805 LTTV_EVENT_HOOK_BY_ID,
806 &value);
807 if(type == LTTV_POINTER) {
808 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
809 }
810
811 lttv_process_traceset_begin(tsc,
812 before_chunk_traceset,
813 before_chunk_trace,
814 before_chunk_tracefile,
815 event_hook,
816 event_hook_by_id);
817}
818
819
820
821void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
822 LttvTracesetContext *tsc)
823{
824 LttvAttribute *g_attribute = lttv_global_attributes();
825 LttvAttribute *module_attribute;
826 LttvAttributeType type;
827 LttvAttributeValue value;
828 LttvHooks *after_chunk_traceset=NULL;
829 LttvHooks *after_chunk_trace=NULL;
830 LttvHooks *after_chunk_tracefile=NULL;
831 LttvHooks *event_hook=NULL;
832 LttvHooksById *event_hook_by_id=NULL;
833
834 module_attribute =
835 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
836 LTTV_COMPUTATION));
837 g_assert(module_attribute);
838
839 module_attribute =
840 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
841 LTTV_IATTRIBUTE(module_attribute),
842 module_name));
843 g_assert(module_attribute);
844
845 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
846 LTTV_AFTER_CHUNK_TRACESET,
847 &value);
848 if(type == LTTV_POINTER) {
849 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
850 }
851
852 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
853 LTTV_AFTER_CHUNK_TRACE,
854 &value);
855 if(type == LTTV_POINTER) {
856 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
857 }
858
859 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
860 LTTV_AFTER_CHUNK_TRACEFILE,
861 &value);
862 if(type == LTTV_POINTER) {
863 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
864 }
865
866 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
867 LTTV_EVENT_HOOK,
868 &value);
869 if(type == LTTV_POINTER) {
870 event_hook = (LttvHooks*)*(value.v_pointer);
871 }
872
873 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
874 LTTV_EVENT_HOOK_BY_ID,
875 &value);
876 if(type == LTTV_POINTER) {
877 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
878 }
879
880 lttv_process_traceset_end(tsc,
881 after_chunk_traceset,
882 after_chunk_trace,
883 after_chunk_tracefile,
884 event_hook,
885 event_hook_by_id);
886
887}
888
889
890void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
891 LttvTrace *trace)
892{
893 LttvAttribute *attribute = lttv_trace_attribute(trace);
894 LttvAttributeValue value;
895
896 attribute =
897 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
898 module_name));
899 g_assert(attribute);
900
901 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
902 LTTV_IN_PROGRESS,
903 LTTV_INT);
904 /* the value is left unset. The only presence of the attribute is necessary.
905 */
906}
907
908void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
909 LttvTrace *trace)
910{
911 LttvAttribute *attribute = lttv_trace_attribute(trace);
912
913 attribute =
914 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
915 module_name));
916 g_assert(attribute);
917
918 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
919 LTTV_IN_PROGRESS);
920}
921
922__EXPORT gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
923 LttvTrace *trace)
924{
925 LttvAttribute *attribute = lttv_trace_attribute(trace);
926 LttvAttributeType type;
927 LttvAttributeValue value;
928
929 attribute =
930 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
931 module_name));
932 g_assert(attribute);
933
934 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
935 LTTV_IN_PROGRESS,
936 &value);
937 /* The only presence of the attribute is necessary. */
938 if(type == LTTV_NONE)
939 return FALSE;
940 else
941 return TRUE;
942}
943
944void lttvwindowtraces_set_ready(LttvAttributeName module_name,
945 LttvTrace *trace)
946{
947 LttvAttribute *attribute = lttv_trace_attribute(trace);
948 LttvAttributeValue value;
949
950 attribute =
951 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
952 module_name));
953 g_assert(attribute);
954
955 value = 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
962void 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
998static 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
1015gboolean 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 */
1502void 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,
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,
1597 LTTV_POINTER,
1598 &value);
1599 g_assert(result);
1600 *(value.v_pointer) = event_hook_by_id;
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 */
1628void 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
1721void 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,
1831 LTTV_POINTER,
1832 &value);
1833 g_assert(result);
1834
1835 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1836 if(event_hook_by_id != NULL)
1837 lttv_hooks_by_id_destroy(event_hook_by_id);
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);
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 */
1904gint 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 */
1934gint 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 */
1961gint 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.103143 seconds and 4 git commands to generate.