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