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