stats ok with functions
[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 attribute = lttv_trace_attribute(trace);
980
981 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
982 LTTV_REQUESTS_QUEUE,
983 &value);
984 g_assert(type == LTTV_POINTER);
985 list_out = (GSList**)(value.v_pointer);
986
987 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
988 LTTV_REQUESTS_CURRENT,
989 &value);
990 g_assert(type == LTTV_POINTER);
991 list_in = (GSList**)(value.v_pointer);
992
993 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
994 LTTV_NOTIFY_QUEUE,
995 &value);
996 g_assert(type == LTTV_POINTER);
997 notify_out = (GSList**)(value.v_pointer);
998
999 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1000 LTTV_NOTIFY_CURRENT,
1001 &value);
1002 g_assert(type == LTTV_POINTER);
1003 notify_in = (GSList**)(value.v_pointer);
1004
1005 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1006 LTTV_COMPUTATION_TRACESET,
1007 &value);
1008 g_assert(type == LTTV_POINTER);
1009 ts = (LttvTraceset*)*(value.v_pointer);
1010
1011 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1012 LTTV_COMPUTATION_TRACESET_CONTEXT,
1013 &value);
1014 g_assert(type == LTTV_POINTER);
1015 tsc = (LttvTracesetContext*)*(value.v_pointer);
1016 tss = (LttvTracesetStats*)*(value.v_pointer);
1017 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
1018 g_assert(LTTV_IS_TRACESET_STATS(tss));
1019 #if 0
1020 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1021 LTTV_COMPUTATION_SYNC_POSITION,
1022 &value);
1023 g_assert(type == LTTV_POINTER);
1024 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
1025 #endif //0
1026 /* There is no events requests pending : we should never have been called! */
1027 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
1028 /* 0.1 Lock traces */
1029 {
1030 guint iter_trace=0;
1031
1032 for(iter_trace=0;
1033 iter_trace<lttv_traceset_number(tsc->ts);
1034 iter_trace++) {
1035 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
1036
1037 if(lttvwindowtraces_lock(trace_v) != 0)
1038 return TRUE; /* Cannot get trace lock, try later */
1039
1040 }
1041 }
1042 /* 0.2 Sync tracefiles */
1043 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
1044 lttv_process_traceset_synchronize_tracefiles(tsc);
1045 /* 1. Before processing */
1046 {
1047 /* if list_in is empty */
1048 if(g_slist_length(*list_in) == 0) {
1049
1050 {
1051 /* - Add all requests in list_out to list_in, empty list_out */
1052 GSList *iter = *list_out;
1053
1054 while(iter != NULL) {
1055 gboolean remove = FALSE;
1056 gboolean free_data = FALSE;
1057
1058 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1059
1060 remove = TRUE;
1061 free_data = FALSE;
1062 *list_in = g_slist_append(*list_in, bg_req);
1063
1064 /* Go to next */
1065 if(remove)
1066 {
1067 GSList *remove_iter = iter;
1068
1069 iter = g_slist_next(iter);
1070 if(free_data) g_free(remove_iter->data);
1071 *list_out = g_slist_remove_link(*list_out, remove_iter);
1072 } else { // not remove
1073 iter = g_slist_next(iter);
1074 }
1075 }
1076 }
1077
1078 {
1079 GSList *iter = *list_in;
1080 /* - for each request in list_in */
1081 while(iter != NULL) {
1082
1083 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1084 /* - set hooks'in_progress flag to TRUE */
1085 lttvwindowtraces_set_in_progress(bg_req->module_name,
1086 bg_req->trace);
1087
1088 /* - call before request hook */
1089 /* Get before request hook */
1090 LttvAttribute *module_attribute;
1091
1092 g_assert(module_attribute =
1093 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1094 LTTV_IATTRIBUTE(g_attribute),
1095 LTTV_COMPUTATION)));
1096
1097 g_assert(module_attribute =
1098 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1099 LTTV_IATTRIBUTE(module_attribute),
1100 bg_req->module_name)));
1101
1102 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1103 LTTV_BEFORE_REQUEST,
1104 &value);
1105 g_assert(type == LTTV_POINTER);
1106 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1107
1108 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
1109
1110 iter = g_slist_next(iter);
1111 }
1112 }
1113
1114 /* - seek trace to start */
1115 {
1116 LttTime start = { 0, 0};
1117 lttv_process_traceset_seek_time(tsc, start);
1118 }
1119
1120 /* - Move all notifications from notify_out to notify_in. */
1121 {
1122 GSList *iter = *notify_out;
1123 g_assert(g_slist_length(*notify_in) == 0);
1124
1125 while(iter != NULL) {
1126 gboolean remove = FALSE;
1127 gboolean free_data = FALSE;
1128
1129 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1130
1131 remove = TRUE;
1132 free_data = FALSE;
1133 *notify_in = g_slist_append(*notify_in, notify_req);
1134
1135 /* Go to next */
1136 if(remove)
1137 {
1138 GSList *remove_iter = iter;
1139
1140 iter = g_slist_next(iter);
1141 if(free_data)
1142 notify_request_free((BackgroundNotify*)remove_iter->data);
1143 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
1144 } else { // not remove
1145 iter = g_slist_next(iter);
1146 }
1147 }
1148 }
1149 {
1150 GSList *iter = *list_in;
1151 LttvHooks *hook_adder = lttv_hooks_new();
1152 /* - for each request in list_in */
1153 while(iter != NULL) {
1154
1155 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1156 /*- add hooks to context*/
1157 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1158 tsc,
1159 hook_adder);
1160 iter = g_slist_next(iter);
1161 }
1162 lttv_hooks_call(hook_adder,tsc);
1163 lttv_hooks_destroy(hook_adder);
1164 }
1165
1166
1167 }
1168
1169 {
1170 GSList *iter = *list_in;
1171 /* - for each request in list_in */
1172 while(iter != NULL) {
1173
1174 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1175 /*- Call before chunk hooks for list_in*/
1176 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1177 tsc);
1178 iter = g_slist_next(iter);
1179 }
1180 }
1181
1182 }
1183 /* 2. call process traceset middle for a chunk */
1184 {
1185 /*(assert list_in is not empty! : should not even be called in that case)*/
1186 LttTime end = ltt_time_infinite;
1187 g_assert(g_slist_length(*list_in) != 0);
1188
1189 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1190 }
1191
1192 /* 3. After the chunk */
1193 {
1194 /* 3.1 call after_chunk hooks for list_in */
1195 {
1196 GSList *iter = *list_in;
1197 /* - for each request in list_in */
1198 while(iter != NULL) {
1199
1200 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1201 /* - Call after chunk hooks for list_in */
1202 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1203 tsc);
1204 iter = g_slist_next(iter);
1205 }
1206 }
1207
1208 /* 3.2 for each notify_in */
1209 {
1210 GSList *iter = *notify_in;
1211 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1212
1213 while(iter != NULL) {
1214 gboolean remove = FALSE;
1215 gboolean free_data = FALSE;
1216
1217 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1218
1219 /* - if current time >= notify time, call notify and remove from
1220 * notify_in.
1221 * - if current position >= notify position, call notify and remove
1222 * from notify_in.
1223 */
1224 if( (tfc != NULL &&
1225 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
1226 ||
1227 (notify_req->notify_position != NULL &&
1228 lttv_traceset_context_ctx_pos_compare(tsc,
1229 notify_req->notify_position) >= 0)
1230 ) {
1231
1232 lttv_hooks_call(notify_req->notify, notify_req);
1233
1234 remove = TRUE;
1235 free_data = TRUE;
1236 }
1237
1238 /* Go to next */
1239 if(remove)
1240 {
1241 GSList *remove_iter = iter;
1242
1243 iter = g_slist_next(iter);
1244 if(free_data)
1245 notify_request_free((BackgroundNotify*)remove_iter->data);
1246 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1247 } else { // not remove
1248 iter = g_slist_next(iter);
1249 }
1250 }
1251 }
1252
1253 {
1254 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1255 /* 3.3 if end of trace reached */
1256 if(tfc != NULL)
1257 g_debug("Current time : %lu sec, %lu nsec",
1258 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
1259 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1260 tsc->time_span.end_time) > 0) {
1261
1262 {
1263 GSList *iter = *list_in;
1264 LttvHooks *hook_remover = lttv_hooks_new();
1265 /* - for each request in list_in */
1266 while(iter != NULL) {
1267
1268 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1269 /* - remove hooks from context */
1270 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1271 tsc,
1272 hook_remover);
1273 iter = g_slist_next(iter);
1274 }
1275 lttv_hooks_call(hook_remover,tsc);
1276 lttv_hooks_destroy(hook_remover);
1277 }
1278
1279 /* - for each request in list_in */
1280 {
1281 GSList *iter = *list_in;
1282
1283 while(iter != NULL) {
1284 gboolean remove = FALSE;
1285 gboolean free_data = FALSE;
1286
1287 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1288
1289 /* - set hooks'in_progress flag to FALSE */
1290 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1291 bg_req->trace);
1292 /* - set hooks'ready flag to TRUE */
1293 lttvwindowtraces_set_ready(bg_req->module_name,
1294 bg_req->trace);
1295 /* - call after request hook */
1296 /* Get after request hook */
1297 LttvAttribute *module_attribute;
1298
1299 g_assert(module_attribute =
1300 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1301 LTTV_IATTRIBUTE(g_attribute),
1302 LTTV_COMPUTATION)));
1303
1304 g_assert(module_attribute =
1305 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1306 LTTV_IATTRIBUTE(module_attribute),
1307 bg_req->module_name)));
1308
1309 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1310 LTTV_AFTER_REQUEST,
1311 &value);
1312 g_assert(type == LTTV_POINTER);
1313 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1314
1315 if(after_request != NULL) lttv_hooks_call(after_request, tsc);
1316
1317 if(bg_req->dialog != NULL)
1318 gtk_widget_destroy(bg_req->dialog);
1319 GtkWidget *parent_window;
1320 if(g_slist_find_custom(g_main_window_list,
1321 bg_req->parent_window,
1322 (GCompareFunc)find_window_widget))
1323 parent_window = GTK_WIDGET(bg_req->parent_window);
1324 else
1325 parent_window = NULL;
1326
1327 GtkWidget *dialog =
1328 gtk_message_dialog_new(GTK_WINDOW(parent_window),
1329 GTK_DIALOG_DESTROY_WITH_PARENT,
1330 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1331 "Background computation %s finished for trace %s",
1332 g_quark_to_string(bg_req->module_name),
1333 g_quark_to_string(ltt_trace_name(lttv_trace(bg_req->trace))));
1334 if(parent_window != NULL)
1335 gtk_window_set_transient_for(GTK_WINDOW(dialog),
1336 GTK_WINDOW(parent_window));
1337 g_signal_connect_swapped (dialog, "response",
1338 G_CALLBACK (gtk_widget_destroy),
1339 dialog);
1340 gtk_widget_show(dialog);
1341
1342 /* - remove request */
1343 remove = TRUE;
1344 free_data = TRUE;
1345
1346 /* Go to next */
1347 if(remove)
1348 {
1349 GSList *remove_iter = iter;
1350
1351 iter = g_slist_next(iter);
1352 if(free_data) g_free(remove_iter->data);
1353 *list_in = g_slist_remove_link(*list_in, remove_iter);
1354 } else { // not remove
1355 iter = g_slist_next(iter);
1356 }
1357 }
1358 }
1359
1360 /* - for each notifications in notify_in */
1361 {
1362 GSList *iter = *notify_in;
1363
1364 while(iter != NULL) {
1365 gboolean remove = FALSE;
1366 gboolean free_data = FALSE;
1367
1368 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1369
1370 /* - call notify and remove from notify_in */
1371 lttv_hooks_call(notify_req->notify, notify_req);
1372 remove = TRUE;
1373 free_data = TRUE;
1374
1375 /* Go to next */
1376 if(remove)
1377 {
1378 GSList *remove_iter = iter;
1379
1380 iter = g_slist_next(iter);
1381 if(free_data)
1382 notify_request_free((BackgroundNotify*)remove_iter->data);
1383 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1384 } else { // not remove
1385 iter = g_slist_next(iter);
1386 }
1387 }
1388 }
1389 {
1390 /* - reset the context */
1391 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1392 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1393 }
1394 /* - if list_out is empty */
1395 if(g_slist_length(*list_out) == 0) {
1396 /* - return FALSE (scheduler stopped) */
1397 g_debug("Background computation scheduler stopped");
1398 g_info("Background computation finished for trace %p", trace);
1399 /* FIXME : remove status bar info, need context id and message id */
1400
1401 ret_val = FALSE;
1402 } else {
1403 ret_val = TRUE;
1404 }
1405 } else {
1406 /* 3.4 else, end of trace not reached */
1407 /* - return TRUE (scheduler still registered) */
1408 g_debug("Background computation left");
1409 ret_val = TRUE;
1410 }
1411 }
1412 }
1413 /* 4. Unlock traces */
1414 {
1415 lttv_process_traceset_get_sync_data(tsc);
1416 //lttv_traceset_context_position_save(tsc, sync_position);
1417 guint iter_trace;
1418
1419 for(iter_trace=0;
1420 iter_trace<lttv_traceset_number(tsc->ts);
1421 iter_trace++) {
1422 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1423
1424 lttvwindowtraces_unlock(trace_v);
1425 }
1426 }
1427 return ret_val;
1428 }
1429
1430
1431
1432 /**
1433 * Register the background computation hooks for a specific module. It adds the
1434 * computation hooks to the global attrubutes, under "computation/module name".
1435 *
1436 * @param module_name A GQuark : the name of the module which computes the
1437 * information.
1438 */
1439 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1440 LttvHooks *before_chunk_traceset,
1441 LttvHooks *before_chunk_trace,
1442 LttvHooks *before_chunk_tracefile,
1443 LttvHooks *after_chunk_traceset,
1444 LttvHooks *after_chunk_trace,
1445 LttvHooks *after_chunk_tracefile,
1446 LttvHooks *before_request,
1447 LttvHooks *after_request,
1448 LttvHooks *event_hook,
1449 LttvHooksById *event_hook_by_id,
1450 LttvHooks *hook_adder,
1451 LttvHooks *hook_remover)
1452 {
1453 LttvAttribute *g_attribute = lttv_global_attributes();
1454 LttvAttribute *attribute;
1455 LttvAttributeValue value;
1456
1457 g_assert(attribute =
1458 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1459 LTTV_COMPUTATION)));
1460
1461 g_assert(attribute =
1462 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1463 module_name)));
1464
1465 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1466 LTTV_BEFORE_CHUNK_TRACESET,
1467 LTTV_POINTER,
1468 &value));
1469 *(value.v_pointer) = before_chunk_traceset;
1470
1471 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1472 LTTV_BEFORE_CHUNK_TRACE,
1473 LTTV_POINTER,
1474 &value));
1475 *(value.v_pointer) = before_chunk_trace;
1476
1477 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1478 LTTV_BEFORE_CHUNK_TRACEFILE,
1479 LTTV_POINTER,
1480 &value));
1481 *(value.v_pointer) = before_chunk_tracefile;
1482
1483 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1484 LTTV_AFTER_CHUNK_TRACESET,
1485 LTTV_POINTER,
1486 &value));
1487 *(value.v_pointer) = after_chunk_traceset;
1488
1489 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1490 LTTV_AFTER_CHUNK_TRACE,
1491 LTTV_POINTER,
1492 &value));
1493 *(value.v_pointer) = after_chunk_trace;
1494
1495 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1496 LTTV_AFTER_CHUNK_TRACEFILE,
1497 LTTV_POINTER,
1498 &value));
1499 *(value.v_pointer) = after_chunk_tracefile;
1500
1501 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1502 LTTV_BEFORE_REQUEST,
1503 LTTV_POINTER,
1504 &value));
1505 *(value.v_pointer) = before_request;
1506
1507 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1508 LTTV_AFTER_REQUEST,
1509 LTTV_POINTER,
1510 &value));
1511 *(value.v_pointer) = after_request;
1512
1513 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1514 LTTV_EVENT_HOOK,
1515 LTTV_POINTER,
1516 &value));
1517 *(value.v_pointer) = event_hook;
1518
1519 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1520 LTTV_EVENT_HOOK_BY_ID,
1521 LTTV_POINTER,
1522 &value));
1523 *(value.v_pointer) = event_hook_by_id;
1524
1525 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1526 LTTV_HOOK_ADDER,
1527 LTTV_POINTER,
1528 &value));
1529 *(value.v_pointer) = hook_adder;
1530
1531 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1532 LTTV_HOOK_REMOVER,
1533 LTTV_POINTER,
1534 &value));
1535 *(value.v_pointer) = hook_remover;
1536
1537 }
1538
1539
1540 /**
1541 * It removes all the requests than can be currently processed by the
1542 * background computation algorithm for all the traces (list_in and list_out).
1543 *
1544 * Leaves the flag to in_progress or none.. depending if current or queue
1545 *
1546 * @param module_name A GQuark : the name of the module which computes the
1547 * information.
1548 */
1549 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1550 {
1551 guint i;
1552
1553 for(i=0;i<lttvwindowtraces_get_number();i++) {
1554 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1555 g_assert(trace_v != NULL);
1556 LttTrace *trace;
1557 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1558 LttvAttributeValue value;
1559 GSList **queue, **current;
1560 GSList *iter;
1561
1562 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1563 LTTV_REQUESTS_QUEUE,
1564 LTTV_POINTER,
1565 &value));
1566 queue = (GSList**)(value.v_pointer);
1567
1568 iter = *queue;
1569 while(iter != NULL) {
1570 gboolean remove = FALSE;
1571 gboolean free_data = FALSE;
1572
1573 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1574
1575 if(bg_req->module_name == module_name) {
1576 remove = TRUE;
1577 free_data = TRUE;
1578 }
1579
1580 /* Go to next */
1581 if(remove)
1582 {
1583 GSList *remove_iter = iter;
1584
1585 iter = g_slist_next(iter);
1586 if(free_data) g_free(remove_iter->data);
1587 *queue = g_slist_remove_link(*queue, remove_iter);
1588 } else { // not remove
1589 iter = g_slist_next(iter);
1590 }
1591 }
1592
1593
1594 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1595 LTTV_REQUESTS_CURRENT,
1596 LTTV_POINTER,
1597 &value));
1598 current = (GSList**)(value.v_pointer);
1599
1600 iter = *current;
1601 while(iter != NULL) {
1602 gboolean remove = FALSE;
1603 gboolean free_data = FALSE;
1604
1605 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1606
1607 if(bg_req->module_name == module_name) {
1608 remove = TRUE;
1609 free_data = TRUE;
1610 }
1611
1612 /* Go to next */
1613 if(remove)
1614 {
1615 GSList *remove_iter = iter;
1616
1617 iter = g_slist_next(iter);
1618 if(free_data) g_free(remove_iter->data);
1619 *current = g_slist_remove_link(*current, remove_iter);
1620 } else { // not remove
1621 iter = g_slist_next(iter);
1622 }
1623 }
1624 }
1625 }
1626
1627
1628 /**
1629 * Unregister the background computation hooks for a specific module.
1630 *
1631 * It also removes all the requests than can be currently processed by the
1632 * background computation algorithm for all the traces (list_in and list_out).
1633 *
1634 * @param module_name A GQuark : the name of the module which computes the
1635 * information.
1636 */
1637
1638 void lttvwindowtraces_unregister_computation_hooks
1639 (LttvAttributeName module_name)
1640 {
1641 LttvAttribute *g_attribute = lttv_global_attributes();
1642 LttvAttribute *attribute;
1643 LttvAttributeValue value;
1644
1645 g_assert(attribute =
1646 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1647 LTTV_COMPUTATION)));
1648 g_assert(attribute =
1649 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1650 module_name)));
1651
1652
1653 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1654 LTTV_BEFORE_CHUNK_TRACESET,
1655 LTTV_POINTER,
1656 &value));
1657 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1658 if(before_chunk_traceset != NULL)
1659 lttv_hooks_destroy(before_chunk_traceset);
1660
1661 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1662 LTTV_BEFORE_CHUNK_TRACE,
1663 LTTV_POINTER,
1664 &value));
1665 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1666 if(before_chunk_trace != NULL)
1667 lttv_hooks_destroy(before_chunk_trace);
1668
1669 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1670 LTTV_BEFORE_CHUNK_TRACEFILE,
1671 LTTV_POINTER,
1672 &value));
1673 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1674 if(before_chunk_tracefile != NULL)
1675 lttv_hooks_destroy(before_chunk_tracefile);
1676
1677 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1678 LTTV_AFTER_CHUNK_TRACESET,
1679 LTTV_POINTER,
1680 &value));
1681 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1682 if(after_chunk_traceset != NULL)
1683 lttv_hooks_destroy(after_chunk_traceset);
1684
1685 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1686 LTTV_AFTER_CHUNK_TRACE,
1687 LTTV_POINTER,
1688 &value));
1689 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1690 if(after_chunk_trace != NULL)
1691 lttv_hooks_destroy(after_chunk_trace);
1692
1693 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1694 LTTV_AFTER_CHUNK_TRACEFILE,
1695 LTTV_POINTER,
1696 &value));
1697 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1698 if(after_chunk_tracefile != NULL)
1699 lttv_hooks_destroy(after_chunk_tracefile);
1700
1701 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1702 LTTV_BEFORE_REQUEST,
1703 LTTV_POINTER,
1704 &value));
1705 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1706 if(before_request != NULL)
1707 lttv_hooks_destroy(before_request);
1708
1709 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1710 LTTV_AFTER_REQUEST,
1711 LTTV_POINTER,
1712 &value));
1713 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1714 if(after_request != NULL)
1715 lttv_hooks_destroy(after_request);
1716
1717 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1718 LTTV_EVENT_HOOK,
1719 LTTV_POINTER,
1720 &value));
1721 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1722 if(event_hook != NULL)
1723 lttv_hooks_destroy(event_hook);
1724
1725 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1726 LTTV_EVENT_HOOK_BY_ID,
1727 LTTV_POINTER,
1728 &value));
1729 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1730 if(event_hook_by_id != NULL)
1731 lttv_hooks_by_id_destroy(event_hook_by_id);
1732
1733 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1734 LTTV_HOOK_ADDER,
1735 LTTV_POINTER,
1736 &value));
1737 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1738 if(hook_adder != NULL)
1739 lttv_hooks_destroy(hook_adder);
1740
1741 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1742 LTTV_HOOK_REMOVER,
1743 LTTV_POINTER,
1744 &value));
1745 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1746 if(hook_remover != NULL)
1747 lttv_hooks_destroy(hook_remover);
1748
1749
1750 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1751 LTTV_EVENT_HOOK_BY_ID);
1752 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1753 LTTV_EVENT_HOOK);
1754
1755 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1756 LTTV_AFTER_REQUEST);
1757 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1758 LTTV_BEFORE_REQUEST);
1759
1760 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1761 LTTV_AFTER_CHUNK_TRACEFILE);
1762 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1763 LTTV_AFTER_CHUNK_TRACE);
1764 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1765 LTTV_AFTER_CHUNK_TRACESET);
1766
1767 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1768 LTTV_BEFORE_CHUNK_TRACEFILE);
1769 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1770 LTTV_BEFORE_CHUNK_TRACE);
1771 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1772 LTTV_BEFORE_CHUNK_TRACESET);
1773 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1774 LTTV_HOOK_ADDER);
1775 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1776 LTTV_HOOK_REMOVER);
1777
1778 /* finally, remove module name */
1779 g_assert(attribute =
1780 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1781 LTTV_COMPUTATION)));
1782 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1783 module_name);
1784
1785 }
1786
1787 /**
1788 * Lock a trace so no other instance can use it.
1789 *
1790 * @param trace The trace to lock.
1791 * @return 0 on success, -1 if cannot get lock.
1792 */
1793 gint lttvwindowtraces_lock(LttvTrace *trace)
1794 {
1795 LttvAttribute *attribute = lttv_trace_attribute(trace);
1796 LttvAttributeValue value;
1797 LttvAttributeType type;
1798
1799 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1800 LTTV_LOCK,
1801 &value);
1802 /* Verify the absence of the lock. */
1803 if(type != LTTV_NONE) {
1804 g_critical("Cannot take trace lock");
1805 return -1;
1806 }
1807
1808 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1809 LTTV_LOCK,
1810 LTTV_INT);
1811 /* the value is left unset. The only presence of the attribute is necessary.
1812 */
1813
1814 return 0;
1815 }
1816
1817 /**
1818 * Unlock a trace.
1819 *
1820 * @param trace The trace to unlock.
1821 * @return 0 on success, -1 if cannot unlock (not locked ?).
1822 */
1823 gint lttvwindowtraces_unlock(LttvTrace *trace)
1824 {
1825 LttvAttribute *attribute = lttv_trace_attribute(trace);
1826 LttvAttributeType type;
1827 LttvAttributeValue value;
1828
1829 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1830 LTTV_LOCK,
1831 &value);
1832 /* Verify the presence of the lock. */
1833 if(type == LTTV_NONE) {
1834 g_critical("Cannot release trace lock");
1835 return -1;
1836 }
1837
1838 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1839 LTTV_LOCK);
1840
1841 return 0;
1842 }
1843
1844 /**
1845 * Verify if a trace is locked.
1846 *
1847 * @param trace The trace to verify.
1848 * @return TRUE if locked, FALSE is unlocked.
1849 */
1850 gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1851 {
1852 LttvAttribute *attribute = lttv_trace_attribute(trace);
1853 LttvAttributeType type;
1854 LttvAttributeValue value;
1855
1856 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1857 LTTV_LOCK,
1858 &value);
1859 /* The only presence of the attribute is necessary. */
1860 if(type == LTTV_NONE)
1861 return FALSE;
1862 else
1863 return TRUE;
1864 }
1865
This page took 0.068434 seconds and 4 git commands to generate.