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