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