fix seek so that adding and removing a trace from a traceset will work
[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
431
432 bg_notify = g_new(BackgroundNotify,1);
433
434 bg_notify->owner = owner;
435 bg_notify->trace = trace;
436 bg_notify->notify_time = notify_time;
313bd6fc 437 if(notify_position != NULL) {
b052368a 438 bg_notify->notify_position = lttv_traceset_context_position_new();
313bd6fc 439 lttv_traceset_context_position_copy(bg_notify->notify_position,
440 notify_position);
441 } else {
442 bg_notify->notify_position = NULL;
443 }
444
a1a2b649 445 bg_notify->notify = lttv_hooks_new();
446 lttv_hooks_add_list(bg_notify->notify, notify);
447
448 *slist = g_slist_append(*slist, bg_notify);
449}
450
451/**
452 * Register a callback to be called when requested data is passed in the current
453 * 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_current
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_CURRENT,
476 LTTV_POINTER,
477 &value));
478 slist = (GSList**)(value.v_pointer);
479
480 bg_notify = g_new(BackgroundNotify,1);
481
482 bg_notify->owner = owner;
483 bg_notify->trace = trace;
484 bg_notify->notify_time = notify_time;
313bd6fc 485 if(notify_position!= NULL) {
b052368a 486 bg_notify->notify_position = lttv_traceset_context_position_new();
313bd6fc 487 lttv_traceset_context_position_copy(bg_notify->notify_position,
488 notify_position);
489 } else {
490 bg_notify->notify_position = NULL;
491 }
a1a2b649 492 bg_notify->notify = lttv_hooks_new();
493 lttv_hooks_add_list(bg_notify->notify, notify);
494
495 *slist = g_slist_append(*slist, bg_notify);
496}
497
b052368a 498
499static void notify_request_free(BackgroundNotify *notify_req)
500{
501 if(notify_req == NULL) return;
502
503 if(notify_req->notify_position != NULL)
504 lttv_traceset_context_position_destroy(notify_req->notify_position);
505 if(notify_req->notify != NULL)
506 lttv_hooks_destroy(notify_req->notify);
507 g_free(notify_req);
508}
509
a1a2b649 510/**
511 * Removes all the notifications requests from a specific viewer.
512 *
513 * @param owner owner of the background notification
514 */
515
516void lttvwindowtraces_background_notify_remove(gpointer owner)
517{
518 guint i;
519
520 for(i=0;i<lttvwindowtraces_get_number();i++) {
521 LttvAttribute *attribute;
522 LttvAttributeValue value;
523 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
524 GSList **slist;
525 GSList *iter = NULL;
526
527 g_assert(trace_v != NULL);
528
b052368a 529 attribute = lttv_trace_attribute(trace_v);
a1a2b649 530
531 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
532 LTTV_NOTIFY_QUEUE,
533 LTTV_POINTER,
534 &value));
535 slist = (GSList**)(value.v_pointer);
536
537 for(iter=*slist;iter!=NULL;) {
538
539 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
540
541 if(bg_notify->owner == owner) {
542 GSList *rem_iter = iter;
543 iter=g_slist_next(iter);
b052368a 544 notify_request_free(bg_notify);
545 *slist = g_slist_remove_link(*slist, rem_iter);
a1a2b649 546 } else {
547 iter=g_slist_next(iter);
548 }
549 }
550
551 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
552 LTTV_NOTIFY_CURRENT,
553 LTTV_POINTER,
554 &value));
555 slist = (GSList**)(value.v_pointer);
556
557 for(iter=*slist;iter!=NULL;) {
558
559 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
560
561 if(bg_notify->owner == owner) {
562 GSList *rem_iter = iter;
563 iter=g_slist_next(iter);
b052368a 564 notify_request_free(bg_notify);
565 *slist = g_slist_remove_link(*slist, rem_iter);
a1a2b649 566 } else {
567 iter=g_slist_next(iter);
568 }
569 }
570 }
571}
572
8bc02ec8 573
574/* Background processing helper functions */
575
576void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
1ce324c6 577 LttvTracesetContext *tsc,
578 LttvHooks *hook_adder)
8bc02ec8 579{
580 LttvAttribute *g_attribute = lttv_global_attributes();
581 LttvAttribute *module_attribute;
582 LttvAttributeType type;
583 LttvAttributeValue value;
088f6772 584
585
586 g_assert(module_attribute =
587 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
588 LTTV_COMPUTATION)));
589
590 g_assert(module_attribute =
591 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
592 LTTV_IATTRIBUTE(module_attribute),
593 module_name)));
594
595 /* Call the module's hook adder */
596 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
597 LTTV_HOOK_ADDER,
598 &value);
599 if(type == LTTV_POINTER) {
600 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
601 if(hook_adder != NULL)
602 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
603 }
604}
605
606void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
607 LttvTracesetContext *tsc,
608 LttvHooks *hook_remover)
609{
610 LttvAttribute *g_attribute = lttv_global_attributes();
611 LttvAttribute *module_attribute;
612 LttvAttributeType type;
613 LttvAttributeValue value;
614
615 g_assert(module_attribute =
616 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
617 LTTV_COMPUTATION)));
618
619 g_assert(module_attribute =
620 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
621 LTTV_IATTRIBUTE(module_attribute),
622 module_name)));
623
624 /* Call the module's hook remover */
625 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
626 LTTV_HOOK_REMOVER,
627 &value);
628 if(type == LTTV_POINTER) {
629 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
630 if(hook_remover != NULL)
631 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
632 }
633}
634
635void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
636 LttvTracesetContext *tsc)
637{
638 LttvAttribute *g_attribute = lttv_global_attributes();
639 LttvAttribute *module_attribute;
640 LttvAttributeType type;
641 LttvAttributeValue value;
8bc02ec8 642 LttvHooks *before_chunk_traceset=NULL;
643 LttvHooks *before_chunk_trace=NULL;
644 LttvHooks *before_chunk_tracefile=NULL;
645 LttvHooks *event_hook=NULL;
646 LttvHooksById *event_hook_by_id=NULL;
313bd6fc 647 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
8bc02ec8 648
649
650 g_assert(module_attribute =
651 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
652 LTTV_COMPUTATION)));
653
654 g_assert(module_attribute =
655 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
656 LTTV_IATTRIBUTE(module_attribute),
657 module_name)));
658
659 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
660 LTTV_BEFORE_CHUNK_TRACESET,
661 &value);
662 if(type == LTTV_POINTER) {
663 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
664 }
665
666 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
667 LTTV_BEFORE_CHUNK_TRACE,
668 &value);
669 if(type == LTTV_POINTER) {
670 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
671 }
672
673 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
674 LTTV_BEFORE_CHUNK_TRACEFILE,
675 &value);
676 if(type == LTTV_POINTER) {
677 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
678 }
679
680 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
681 LTTV_EVENT_HOOK,
682 &value);
683 if(type == LTTV_POINTER) {
684 event_hook = (LttvHooks*)*(value.v_pointer);
685 }
686
687 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
688 LTTV_EVENT_HOOK_BY_ID,
689 &value);
690 if(type == LTTV_POINTER) {
691 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
692 }
693
8bc02ec8 694 lttv_process_traceset_begin(tsc,
695 before_chunk_traceset,
696 before_chunk_trace,
697 before_chunk_tracefile,
698 event_hook,
699 event_hook_by_id);
8bc02ec8 700}
088f6772 701
702
703
704void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
705 LttvTracesetContext *tsc)
8bc02ec8 706{
707 LttvAttribute *g_attribute = lttv_global_attributes();
708 LttvAttribute *module_attribute;
709 LttvAttributeType type;
710 LttvAttributeValue value;
711 LttvHooks *after_chunk_traceset=NULL;
712 LttvHooks *after_chunk_trace=NULL;
713 LttvHooks *after_chunk_tracefile=NULL;
714 LttvHooks *event_hook=NULL;
715 LttvHooksById *event_hook_by_id=NULL;
313bd6fc 716 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
8bc02ec8 717
718 g_assert(module_attribute =
719 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
720 LTTV_COMPUTATION)));
721
722 g_assert(module_attribute =
723 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
724 LTTV_IATTRIBUTE(module_attribute),
725 module_name)));
726
727 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
728 LTTV_AFTER_CHUNK_TRACESET,
729 &value);
730 if(type == LTTV_POINTER) {
731 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
732 }
733
734 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
735 LTTV_AFTER_CHUNK_TRACE,
736 &value);
737 if(type == LTTV_POINTER) {
738 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
739 }
740
741 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
742 LTTV_AFTER_CHUNK_TRACEFILE,
743 &value);
744 if(type == LTTV_POINTER) {
745 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
746 }
747
748 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
749 LTTV_EVENT_HOOK,
750 &value);
751 if(type == LTTV_POINTER) {
752 event_hook = (LttvHooks*)*(value.v_pointer);
753 }
754
755 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
756 LTTV_EVENT_HOOK_BY_ID,
757 &value);
758 if(type == LTTV_POINTER) {
759 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
760 }
313bd6fc 761
8bc02ec8 762 lttv_process_traceset_end(tsc,
763 after_chunk_traceset,
764 after_chunk_trace,
765 after_chunk_tracefile,
766 event_hook,
767 event_hook_by_id);
313bd6fc 768
8bc02ec8 769}
770
771
772void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
773 LttvTrace *trace)
774{
775 LttvAttribute *attribute = lttv_trace_attribute(trace);
776 LttvAttributeValue value;
777
778 g_assert(attribute =
779 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
780 module_name)));
781
782 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
783 LTTV_IN_PROGRESS,
784 LTTV_INT);
785 /* the value is left unset. The only presence of the attribute is necessary.
786 */
787}
788
789void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
790 LttvTrace *trace)
791{
792 LttvAttribute *attribute = lttv_trace_attribute(trace);
793
794 g_assert(attribute =
795 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
796 module_name)));
797
313bd6fc 798 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
8bc02ec8 799 LTTV_IN_PROGRESS);
800}
801
802gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
803 LttvTrace *trace)
804{
805 LttvAttribute *attribute = lttv_trace_attribute(trace);
806 LttvAttributeType type;
807 LttvAttributeValue value;
808
809 g_assert(attribute =
810 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
811 module_name)));
812
813 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
814 LTTV_IN_PROGRESS,
815 &value);
816 /* The only presence of the attribute is necessary. */
817 if(type == LTTV_NONE)
818 return FALSE;
819 else
820 return TRUE;
821}
822
823void lttvwindowtraces_set_ready(LttvAttributeName module_name,
824 LttvTrace *trace)
825{
826 LttvAttribute *attribute = lttv_trace_attribute(trace);
827 LttvAttributeValue value;
828
829 g_assert(attribute =
830 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
831 module_name)));
832
833 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
834 LTTV_READY,
835 LTTV_INT);
836 /* the value is left unset. The only presence of the attribute is necessary.
837 */
838}
839
840void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
841 LttvTrace *trace)
842{
843 LttvAttribute *attribute = lttv_trace_attribute(trace);
844
845 g_assert(attribute =
846 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
847 module_name)));
848
313bd6fc 849 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
8bc02ec8 850 LTTV_READY);
851}
852
853gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
854 LttvTrace *trace)
855{
856 LttvAttribute *attribute = lttv_trace_attribute(trace);
857 LttvAttributeType type;
858 LttvAttributeValue value;
859
860 g_assert(attribute =
861 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
862 module_name)));
863
864 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
865 LTTV_READY,
866 &value);
867 /* The only presence of the attribute is necessary. */
868 if(type == LTTV_NONE)
869 return FALSE;
870 else
871 return TRUE;
872}
873
874
8bc02ec8 875/* lttvwindowtraces_process_pending_requests
876 *
877 * This internal function gets called by g_idle, taking care of the pending
878 * requests.
879 *
880 */
881
882
883gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
884{
885 LttvTracesetContext *tsc;
313bd6fc 886 LttvTracesetStats *tss;
8bc02ec8 887 LttvTraceset *ts;
088f6772 888 //LttvTracesetContextPosition *sync_position;
8bc02ec8 889 LttvAttribute *attribute;
91fd6881 890 LttvAttribute *g_attribute = lttv_global_attributes();
313bd6fc 891 GSList **list_out, **list_in, **notify_in, **notify_out;
8bc02ec8 892 LttvAttributeValue value;
893 LttvAttributeType type;
b052368a 894 gboolean ret_val;
8bc02ec8 895
313bd6fc 896 if(trace == NULL)
8bc02ec8 897 return FALSE;
898
899 attribute = lttv_trace_attribute(trace);
900
901 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
902 LTTV_REQUESTS_QUEUE,
903 &value);
904 g_assert(type == LTTV_POINTER);
313bd6fc 905 list_out = (GSList**)(value.v_pointer);
8bc02ec8 906
907 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
908 LTTV_REQUESTS_CURRENT,
909 &value);
910 g_assert(type == LTTV_POINTER);
313bd6fc 911 list_in = (GSList**)(value.v_pointer);
8bc02ec8 912
913 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
914 LTTV_NOTIFY_QUEUE,
915 &value);
916 g_assert(type == LTTV_POINTER);
313bd6fc 917 notify_out = (GSList**)(value.v_pointer);
8bc02ec8 918
919 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
920 LTTV_NOTIFY_CURRENT,
921 &value);
922 g_assert(type == LTTV_POINTER);
313bd6fc 923 notify_in = (GSList**)(value.v_pointer);
8bc02ec8 924
925 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
926 LTTV_COMPUTATION_TRACESET,
927 &value);
928 g_assert(type == LTTV_POINTER);
929 ts = (LttvTraceset*)*(value.v_pointer);
930
931 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
932 LTTV_COMPUTATION_TRACESET_CONTEXT,
933 &value);
934 g_assert(type == LTTV_POINTER);
935 tsc = (LttvTracesetContext*)*(value.v_pointer);
313bd6fc 936 tss = (LttvTracesetStats*)*(value.v_pointer);
8bc02ec8 937 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
313bd6fc 938 g_assert(LTTV_IS_TRACESET_STATS(tss));
088f6772 939#if 0
79257ba5 940 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
941 LTTV_COMPUTATION_SYNC_POSITION,
942 &value);
943 g_assert(type == LTTV_POINTER);
944 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
088f6772 945#endif //0
8bc02ec8 946 /* There is no events requests pending : we should never have been called! */
313bd6fc 947 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
b052368a 948 /* 0.1 Lock traces */
949 {
950 guint iter_trace=0;
951
952 for(iter_trace=0;
953 iter_trace<lttv_traceset_number(tsc->ts);
954 iter_trace++) {
955 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
956
957 if(lttvwindowtraces_lock(trace_v) != 0)
958 return TRUE; /* Cannot get trace lock, try later */
8bc02ec8 959
b052368a 960 }
961 }
962 /* 0.2 Sync tracefiles */
088f6772 963 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
964 lttv_process_traceset_synchronize_tracefiles(tsc);
8bc02ec8 965 /* 1. Before processing */
966 {
967 /* if list_in is empty */
313bd6fc 968 if(g_slist_length(*list_in) == 0) {
8bc02ec8 969
970 {
971 /* - Add all requests in list_out to list_in, empty list_out */
313bd6fc 972 GSList *iter = *list_out;
8bc02ec8 973
974 while(iter != NULL) {
975 gboolean remove = FALSE;
976 gboolean free_data = FALSE;
977
978 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
979
980 remove = TRUE;
981 free_data = FALSE;
313bd6fc 982 *list_in = g_slist_append(*list_in, bg_req);
8bc02ec8 983
984 /* Go to next */
985 if(remove)
986 {
987 GSList *remove_iter = iter;
988
989 iter = g_slist_next(iter);
990 if(free_data) g_free(remove_iter->data);
313bd6fc 991 *list_out = g_slist_remove_link(*list_out, remove_iter);
8bc02ec8 992 } else { // not remove
993 iter = g_slist_next(iter);
994 }
995 }
996 }
997
998 {
313bd6fc 999 GSList *iter = *list_in;
8bc02ec8 1000 /* - for each request in list_in */
1001 while(iter != NULL) {
1002
1003 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
91fd6881 1004 /* - set hooks'in_progress flag to TRUE */
8bc02ec8 1005 lttvwindowtraces_set_in_progress(bg_req->module_name,
1006 bg_req->trace);
91fd6881 1007
1008 /* - call before request hook */
1009 /* Get before request hook */
1010 LttvAttribute *module_attribute;
1011
1012 g_assert(module_attribute =
1013 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1014 LTTV_IATTRIBUTE(g_attribute),
1015 LTTV_COMPUTATION)));
1016
1017 g_assert(module_attribute =
1018 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1019 LTTV_IATTRIBUTE(module_attribute),
1020 bg_req->module_name)));
1021
1022 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1023 LTTV_BEFORE_REQUEST,
1024 &value);
1025 g_assert(type == LTTV_POINTER);
1026 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
91fd6881 1027
1028 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
8bc02ec8 1029
1030 iter = g_slist_next(iter);
1031 }
1032 }
1033
1034 /* - seek trace to start */
1035 {
1036 LttTime start = { 0, 0};
1037 lttv_process_traceset_seek_time(tsc, start);
1038 }
1039
1040 /* - Move all notifications from notify_out to notify_in. */
1041 {
313bd6fc 1042 GSList *iter = *notify_out;
1043 g_assert(g_slist_length(*notify_in) == 0);
8bc02ec8 1044
1045 while(iter != NULL) {
1046 gboolean remove = FALSE;
1047 gboolean free_data = FALSE;
1048
1049 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1050
1051 remove = TRUE;
1052 free_data = FALSE;
313bd6fc 1053 *notify_in = g_slist_append(*notify_in, notify_req);
8bc02ec8 1054
1055 /* Go to next */
1056 if(remove)
1057 {
1058 GSList *remove_iter = iter;
1059
1060 iter = g_slist_next(iter);
b052368a 1061 if(free_data)
1062 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1063 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
8bc02ec8 1064 } else { // not remove
1065 iter = g_slist_next(iter);
1066 }
1067 }
1068 }
088f6772 1069 {
1070 GSList *iter = *list_in;
1071 LttvHooks *hook_adder = lttv_hooks_new();
1072 /* - for each request in list_in */
1073 while(iter != NULL) {
1074
1075 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1076 /*- add hooks to context*/
1077 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1078 tsc,
1079 hook_adder);
1080 iter = g_slist_next(iter);
1081 }
1082 lttv_hooks_call(hook_adder,tsc);
1083 lttv_hooks_destroy(hook_adder);
1084 }
1085
1086
8bc02ec8 1087 }
1088
1089 {
313bd6fc 1090 GSList *iter = *list_in;
8bc02ec8 1091 /* - for each request in list_in */
1092 while(iter != NULL) {
1093
1094 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1095 /*- Call before chunk hooks for list_in*/
088f6772 1096 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1097 tsc);
8bc02ec8 1098 iter = g_slist_next(iter);
1099 }
1100 }
8bc02ec8 1101
088f6772 1102 }
8bc02ec8 1103 /* 2. call process traceset middle for a chunk */
1104 {
1105 /*(assert list_in is not empty! : should not even be called in that case)*/
0aa6c3a1 1106 LttTime end = ltt_time_infinite;
313bd6fc 1107 g_assert(g_slist_length(*list_in) != 0);
8bc02ec8 1108
1109 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1110 }
1111
1112 /* 3. After the chunk */
1113 {
1114 /* 3.1 call after_chunk hooks for list_in */
1115 {
313bd6fc 1116 GSList *iter = *list_in;
8bc02ec8 1117 /* - for each request in list_in */
1118 while(iter != NULL) {
1119
1120 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1121 /* - Call after chunk hooks for list_in */
088f6772 1122 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1123 tsc);
8bc02ec8 1124 iter = g_slist_next(iter);
1125 }
1126 }
1127
1128 /* 3.2 for each notify_in */
1129 {
313bd6fc 1130 GSList *iter = *notify_in;
8bc02ec8 1131 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1132
1133 while(iter != NULL) {
1134 gboolean remove = FALSE;
1135 gboolean free_data = FALSE;
1136
1137 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1138
1139 /* - if current time >= notify time, call notify and remove from
1140 * notify_in.
1141 * - if current position >= notify position, call notify and remove
1142 * from notify_in.
1143 */
1144 if( (tfc != NULL &&
313bd6fc 1145 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
8bc02ec8 1146 ||
313bd6fc 1147 (notify_req->notify_position != NULL &&
1148 lttv_traceset_context_ctx_pos_compare(tsc,
1149 notify_req->notify_position) >= 0)
8bc02ec8 1150 ) {
1151
1152 lttv_hooks_call(notify_req->notify, notify_req);
1153
1154 remove = TRUE;
1155 free_data = TRUE;
1156 }
1157
1158 /* Go to next */
1159 if(remove)
1160 {
1161 GSList *remove_iter = iter;
1162
1163 iter = g_slist_next(iter);
b052368a 1164 if(free_data)
1165 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1166 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
8bc02ec8 1167 } else { // not remove
1168 iter = g_slist_next(iter);
1169 }
1170 }
1171 }
1172
1173 {
1174 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1175 /* 3.3 if end of trace reached */
313bd6fc 1176 if(tfc != NULL)
1177 g_debug("Current time : %lu sec, %lu nsec",
1178 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
8bc02ec8 1179 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1180 tsc->time_span.end_time) > 0) {
088f6772 1181
1182 {
1183 GSList *iter = *list_in;
1184 LttvHooks *hook_remover = lttv_hooks_new();
1185 /* - for each request in list_in */
1186 while(iter != NULL) {
1187
1188 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1189 /* - remove hooks from context */
1190 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1191 tsc,
1192 hook_remover);
1193 iter = g_slist_next(iter);
1194 }
1195 lttv_hooks_call(hook_remover,tsc);
1196 lttv_hooks_destroy(hook_remover);
1197 }
1198
8bc02ec8 1199 /* - for each request in list_in */
1200 {
313bd6fc 1201 GSList *iter = *list_in;
8bc02ec8 1202
1203 while(iter != NULL) {
1204 gboolean remove = FALSE;
1205 gboolean free_data = FALSE;
1206
1207 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1208
1209 /* - set hooks'in_progress flag to FALSE */
1210 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1211 bg_req->trace);
1212 /* - set hooks'ready flag to TRUE */
1213 lttvwindowtraces_set_ready(bg_req->module_name,
1214 bg_req->trace);
91fd6881 1215 /* - call after request hook */
1216 /* Get after request hook */
1217 LttvAttribute *module_attribute;
1218
1219 g_assert(module_attribute =
1220 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1221 LTTV_IATTRIBUTE(g_attribute),
1222 LTTV_COMPUTATION)));
1223
1224 g_assert(module_attribute =
1225 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1226 LTTV_IATTRIBUTE(module_attribute),
1227 bg_req->module_name)));
1228
1229 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1230 LTTV_AFTER_REQUEST,
1231 &value);
1232 g_assert(type == LTTV_POINTER);
1233 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1234
1235 if(after_request != NULL) lttv_hooks_call(after_request, tsc);
8bc02ec8 1236 /* - remove request */
1237 remove = TRUE;
1238 free_data = TRUE;
1239
1240 /* Go to next */
1241 if(remove)
1242 {
1243 GSList *remove_iter = iter;
1244
1245 iter = g_slist_next(iter);
1246 if(free_data) g_free(remove_iter->data);
313bd6fc 1247 *list_in = g_slist_remove_link(*list_in, remove_iter);
8bc02ec8 1248 } else { // not remove
1249 iter = g_slist_next(iter);
1250 }
1251 }
1252 }
1253
1254 /* - for each notifications in notify_in */
1255 {
313bd6fc 1256 GSList *iter = *notify_in;
8bc02ec8 1257
1258 while(iter != NULL) {
1259 gboolean remove = FALSE;
1260 gboolean free_data = FALSE;
1261
1262 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1263
1264 /* - call notify and remove from notify_in */
1265 lttv_hooks_call(notify_req->notify, notify_req);
1266 remove = TRUE;
1267 free_data = TRUE;
1268
1269 /* Go to next */
1270 if(remove)
1271 {
1272 GSList *remove_iter = iter;
1273
1274 iter = g_slist_next(iter);
b052368a 1275 if(free_data)
1276 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1277 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
8bc02ec8 1278 } else { // not remove
1279 iter = g_slist_next(iter);
1280 }
1281 }
1282 }
1ce324c6 1283 {
1284 /* - reset the context */
1285 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1286 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1287 }
3710295e 1288 /* - if list_out is empty */
1289 if(g_slist_length(*list_out) == 0) {
1290 /* - return FALSE (scheduler stopped) */
1291 g_debug("Background computation scheduler stopped");
1292 g_info("Background computation finished for trace %p", trace);
1293 /* FIXME : remove status bar info, need context id and message id */
1294 ret_val = FALSE;
1295 } else {
1296 ret_val = TRUE;
1297 }
8bc02ec8 1298 } else {
1299 /* 3.4 else, end of trace not reached */
1300 /* - return TRUE (scheduler still registered) */
313bd6fc 1301 g_debug("Background computation left");
b052368a 1302 ret_val = TRUE;
8bc02ec8 1303 }
1304 }
1305 }
b052368a 1306 /* 4. Unlock traces */
1307 {
088f6772 1308 lttv_process_traceset_get_sync_data(tsc);
1309 //lttv_traceset_context_position_save(tsc, sync_position);
b052368a 1310 guint iter_trace;
1311
1312 for(iter_trace=0;
1313 iter_trace<lttv_traceset_number(tsc->ts);
1314 iter_trace++) {
1315 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1316
1317 lttvwindowtraces_unlock(trace_v);
1318 }
1319 }
1320 return ret_val;
8bc02ec8 1321}
e62a7964 1322
1323
1324
1325/**
1326 * Register the background computation hooks for a specific module. It adds the
313bd6fc 1327 * computation hooks to the global attrubutes, under "computation/module name".
e62a7964 1328 *
1329 * @param module_name A GQuark : the name of the module which computes the
1330 * information.
1331 */
1332void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1333 LttvHooks *before_chunk_traceset,
1334 LttvHooks *before_chunk_trace,
1335 LttvHooks *before_chunk_tracefile,
1336 LttvHooks *after_chunk_traceset,
1337 LttvHooks *after_chunk_trace,
1338 LttvHooks *after_chunk_tracefile,
1339 LttvHooks *before_request,
1340 LttvHooks *after_request,
1341 LttvHooks *event_hook,
313bd6fc 1342 LttvHooksById *event_hook_by_id,
1343 LttvHooks *hook_adder,
1344 LttvHooks *hook_remover)
e62a7964 1345{
1346 LttvAttribute *g_attribute = lttv_global_attributes();
1347 LttvAttribute *attribute;
1348 LttvAttributeValue value;
1349
1350 g_assert(attribute =
1351 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1352 LTTV_COMPUTATION)));
1353
1354 g_assert(attribute =
1355 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1356 module_name)));
1357
1358 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1359 LTTV_BEFORE_CHUNK_TRACESET,
1360 LTTV_POINTER,
1361 &value));
1362 *(value.v_pointer) = before_chunk_traceset;
1363
1364 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1365 LTTV_BEFORE_CHUNK_TRACE,
1366 LTTV_POINTER,
1367 &value));
1368 *(value.v_pointer) = before_chunk_trace;
1369
1370 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1371 LTTV_BEFORE_CHUNK_TRACEFILE,
1372 LTTV_POINTER,
1373 &value));
1374 *(value.v_pointer) = before_chunk_tracefile;
1375
1376 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1377 LTTV_AFTER_CHUNK_TRACESET,
1378 LTTV_POINTER,
1379 &value));
1380 *(value.v_pointer) = after_chunk_traceset;
1381
1382 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1383 LTTV_AFTER_CHUNK_TRACE,
1384 LTTV_POINTER,
1385 &value));
1386 *(value.v_pointer) = after_chunk_trace;
1387
1388 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1389 LTTV_AFTER_CHUNK_TRACEFILE,
1390 LTTV_POINTER,
1391 &value));
1392 *(value.v_pointer) = after_chunk_tracefile;
1393
1394 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1395 LTTV_BEFORE_REQUEST,
1396 LTTV_POINTER,
1397 &value));
1398 *(value.v_pointer) = before_request;
1399
1400 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1401 LTTV_AFTER_REQUEST,
1402 LTTV_POINTER,
1403 &value));
1404 *(value.v_pointer) = after_request;
1405
1406 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1407 LTTV_EVENT_HOOK,
1408 LTTV_POINTER,
1409 &value));
1410 *(value.v_pointer) = event_hook;
1411
1412 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1413 LTTV_EVENT_HOOK_BY_ID,
1414 LTTV_POINTER,
1415 &value));
1416 *(value.v_pointer) = event_hook_by_id;
1417
313bd6fc 1418 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1419 LTTV_HOOK_ADDER,
1420 LTTV_POINTER,
1421 &value));
1422 *(value.v_pointer) = hook_adder;
1423
1424 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1425 LTTV_HOOK_REMOVER,
1426 LTTV_POINTER,
1427 &value));
1428 *(value.v_pointer) = hook_remover;
1429
e62a7964 1430}
1431
1432
1433/**
1434 * It removes all the requests than can be currently processed by the
1435 * background computation algorithm for all the traces (list_in and list_out).
1436 *
1437 * Leaves the flag to in_progress or none.. depending if current or queue
1438 *
1439 * @param module_name A GQuark : the name of the module which computes the
1440 * information.
1441 */
1442void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1443{
1444 guint i;
1445
1446 for(i=0;i<lttvwindowtraces_get_number();i++) {
1447 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1448 g_assert(trace_v != NULL);
1449 LttTrace *trace;
1450 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1451 LttvAttributeValue value;
313bd6fc 1452 GSList **queue, **current;
e62a7964 1453 GSList *iter;
1454
1455 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1456 LTTV_REQUESTS_QUEUE,
1457 LTTV_POINTER,
1458 &value));
313bd6fc 1459 queue = (GSList**)(value.v_pointer);
e62a7964 1460
313bd6fc 1461 iter = *queue;
e62a7964 1462 while(iter != NULL) {
1463 gboolean remove = FALSE;
1464 gboolean free_data = FALSE;
1465
1466 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1467
1468 if(bg_req->module_name == module_name) {
1469 remove = TRUE;
1470 free_data = TRUE;
1471 }
1472
1473 /* Go to next */
1474 if(remove)
1475 {
1476 GSList *remove_iter = iter;
1477
1478 iter = g_slist_next(iter);
1479 if(free_data) g_free(remove_iter->data);
313bd6fc 1480 *queue = g_slist_remove_link(*queue, remove_iter);
e62a7964 1481 } else { // not remove
1482 iter = g_slist_next(iter);
1483 }
1484 }
1485
1486
1487 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1488 LTTV_REQUESTS_CURRENT,
1489 LTTV_POINTER,
1490 &value));
313bd6fc 1491 current = (GSList**)(value.v_pointer);
e62a7964 1492
313bd6fc 1493 iter = *current;
e62a7964 1494 while(iter != NULL) {
1495 gboolean remove = FALSE;
1496 gboolean free_data = FALSE;
1497
1498 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1499
1500 if(bg_req->module_name == module_name) {
1501 remove = TRUE;
1502 free_data = TRUE;
1503 }
1504
1505 /* Go to next */
1506 if(remove)
1507 {
1508 GSList *remove_iter = iter;
1509
1510 iter = g_slist_next(iter);
1511 if(free_data) g_free(remove_iter->data);
313bd6fc 1512 *current = g_slist_remove_link(*current, remove_iter);
e62a7964 1513 } else { // not remove
1514 iter = g_slist_next(iter);
1515 }
1516 }
1517 }
1518}
1519
1520
1521/**
1522 * Unregister the background computation hooks for a specific module.
1523 *
1524 * It also removes all the requests than can be currently processed by the
1525 * background computation algorithm for all the traces (list_in and list_out).
1526 *
1527 * @param module_name A GQuark : the name of the module which computes the
1528 * information.
1529 */
1530
1531void lttvwindowtraces_unregister_computation_hooks
1532 (LttvAttributeName module_name)
1533{
1534 LttvAttribute *g_attribute = lttv_global_attributes();
1535 LttvAttribute *attribute;
91fd6881 1536 LttvAttributeValue value;
e62a7964 1537
1538 g_assert(attribute =
1539 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1540 LTTV_COMPUTATION)));
1541 g_assert(attribute =
1542 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1543 module_name)));
1544
1545
91fd6881 1546 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1547 LTTV_BEFORE_CHUNK_TRACESET,
1548 LTTV_POINTER,
1549 &value));
1550 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1551 if(before_chunk_traceset != NULL)
1552 lttv_hooks_destroy(before_chunk_traceset);
1553
1554 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1555 LTTV_BEFORE_CHUNK_TRACE,
1556 LTTV_POINTER,
1557 &value));
1558 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1559 if(before_chunk_trace != NULL)
1560 lttv_hooks_destroy(before_chunk_trace);
1561
1562 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1563 LTTV_BEFORE_CHUNK_TRACEFILE,
1564 LTTV_POINTER,
1565 &value));
1566 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1567 if(before_chunk_tracefile != NULL)
1568 lttv_hooks_destroy(before_chunk_tracefile);
1569
1570 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1571 LTTV_AFTER_CHUNK_TRACESET,
1572 LTTV_POINTER,
1573 &value));
1574 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1575 if(after_chunk_traceset != NULL)
1576 lttv_hooks_destroy(after_chunk_traceset);
1577
1578 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1579 LTTV_AFTER_CHUNK_TRACE,
1580 LTTV_POINTER,
1581 &value));
1582 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1583 if(after_chunk_trace != NULL)
1584 lttv_hooks_destroy(after_chunk_trace);
1585
1586 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1587 LTTV_AFTER_CHUNK_TRACEFILE,
1588 LTTV_POINTER,
1589 &value));
1590 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1591 if(after_chunk_tracefile != NULL)
1592 lttv_hooks_destroy(after_chunk_tracefile);
1593
1594 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1595 LTTV_BEFORE_REQUEST,
1596 LTTV_POINTER,
1597 &value));
1598 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1599 if(before_request != NULL)
1600 lttv_hooks_destroy(before_request);
1601
1602 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1603 LTTV_AFTER_REQUEST,
1604 LTTV_POINTER,
1605 &value));
1606 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1607 if(after_request != NULL)
1608 lttv_hooks_destroy(after_request);
1609
1610 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1611 LTTV_EVENT_HOOK,
1612 LTTV_POINTER,
1613 &value));
1614 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1615 if(event_hook != NULL)
1616 lttv_hooks_destroy(event_hook);
1617
1618 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1619 LTTV_EVENT_HOOK_BY_ID,
1620 LTTV_POINTER,
1621 &value));
1622 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1623 if(event_hook_by_id != NULL)
1624 lttv_hooks_by_id_destroy(event_hook_by_id);
1625
1626 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1627 LTTV_HOOK_ADDER,
1628 LTTV_POINTER,
1629 &value));
1630 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1631 if(hook_adder != NULL)
1632 lttv_hooks_destroy(hook_adder);
1633
1634 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1635 LTTV_HOOK_REMOVER,
1636 LTTV_POINTER,
1637 &value));
1638 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1639 if(hook_remover != NULL)
1640 lttv_hooks_destroy(hook_remover);
1641
1642
e62a7964 1643 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1644 LTTV_EVENT_HOOK_BY_ID);
1645 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1646 LTTV_EVENT_HOOK);
1647
1648 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1649 LTTV_AFTER_REQUEST);
1650 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1651 LTTV_BEFORE_REQUEST);
1652
1653 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1654 LTTV_AFTER_CHUNK_TRACEFILE);
1655 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1656 LTTV_AFTER_CHUNK_TRACE);
1657 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1658 LTTV_AFTER_CHUNK_TRACESET);
1659
1660 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1661 LTTV_BEFORE_CHUNK_TRACEFILE);
1662 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1663 LTTV_BEFORE_CHUNK_TRACE);
1664 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1665 LTTV_BEFORE_CHUNK_TRACESET);
313bd6fc 1666 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1667 LTTV_HOOK_ADDER);
1668 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1669 LTTV_HOOK_REMOVER);
1670
e62a7964 1671 /* finally, remove module name */
1672 g_assert(attribute =
1673 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1674 LTTV_COMPUTATION)));
1675 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1676 module_name);
1677
1678}
1679
b052368a 1680/**
1681 * Lock a trace so no other instance can use it.
1682 *
1683 * @param trace The trace to lock.
1684 * @return 0 on success, -1 if cannot get lock.
1685 */
1686gint lttvwindowtraces_lock(LttvTrace *trace)
1687{
1688 LttvAttribute *attribute = lttv_trace_attribute(trace);
1689 LttvAttributeValue value;
1690 LttvAttributeType type;
1691
1692 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1693 LTTV_LOCK,
1694 &value);
1695 /* Verify the absence of the lock. */
1696 if(type != LTTV_NONE) {
1697 g_critical("Cannot take trace lock");
1698 return -1;
1699 }
1700
1701 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1702 LTTV_LOCK,
1703 LTTV_INT);
1704 /* the value is left unset. The only presence of the attribute is necessary.
1705 */
1706
1707 return 0;
1708}
1709
1710/**
1711 * Unlock a trace.
1712 *
1713 * @param trace The trace to unlock.
1714 * @return 0 on success, -1 if cannot unlock (not locked ?).
1715 */
1716gint lttvwindowtraces_unlock(LttvTrace *trace)
1717{
1718 LttvAttribute *attribute = lttv_trace_attribute(trace);
1719 LttvAttributeType type;
1720 LttvAttributeValue value;
1721
1722 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1723 LTTV_LOCK,
1724 &value);
1725 /* Verify the presence of the lock. */
1726 if(type == LTTV_NONE) {
1727 g_critical("Cannot release trace lock");
1728 return -1;
1729 }
1730
1731 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1732 LTTV_LOCK);
1733
1734 return 0;
1735}
1736
1737/**
1738 * Verify if a trace is locked.
1739 *
1740 * @param trace The trace to verify.
1741 * @return TRUE if locked, FALSE is unlocked.
1742 */
1743gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1744{
1745 LttvAttribute *attribute = lttv_trace_attribute(trace);
1746 LttvAttributeType type;
1747 LttvAttributeValue value;
1748
1749 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1750 LTTV_LOCK,
1751 &value);
1752 /* The only presence of the attribute is necessary. */
1753 if(type == LTTV_NONE)
1754 return FALSE;
1755 else
1756 return TRUE;
1757}
e62a7964 1758
This page took 0.110885 seconds and 4 git commands to generate.