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