init trace scrollbar bugfix
[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 }
1177
1178 /* - return FALSE (scheduler stopped) */
313bd6fc 1179 g_debug("Background computation scheduler stopped");
b052368a 1180 g_info("Background computation finished for trace %p", trace);
1181 /* FIXME : remove status bar info, need context id and message id */
1182 ret_val = FALSE;
8bc02ec8 1183 } else {
1184 /* 3.4 else, end of trace not reached */
1185 /* - return TRUE (scheduler still registered) */
313bd6fc 1186 g_debug("Background computation left");
b052368a 1187 ret_val = TRUE;
8bc02ec8 1188 }
1189 }
1190 }
b052368a 1191 /* 4. Unlock traces */
1192 {
1193 //lttv_process_traceset_get_sync_data(tsc);
1194 guint iter_trace;
1195
1196 for(iter_trace=0;
1197 iter_trace<lttv_traceset_number(tsc->ts);
1198 iter_trace++) {
1199 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1200
1201 lttvwindowtraces_unlock(trace_v);
1202 }
1203 }
1204 return ret_val;
8bc02ec8 1205}
e62a7964 1206
1207
1208
1209/**
1210 * Register the background computation hooks for a specific module. It adds the
313bd6fc 1211 * computation hooks to the global attrubutes, under "computation/module name".
e62a7964 1212 *
1213 * @param module_name A GQuark : the name of the module which computes the
1214 * information.
1215 */
1216void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1217 LttvHooks *before_chunk_traceset,
1218 LttvHooks *before_chunk_trace,
1219 LttvHooks *before_chunk_tracefile,
1220 LttvHooks *after_chunk_traceset,
1221 LttvHooks *after_chunk_trace,
1222 LttvHooks *after_chunk_tracefile,
1223 LttvHooks *before_request,
1224 LttvHooks *after_request,
1225 LttvHooks *event_hook,
313bd6fc 1226 LttvHooksById *event_hook_by_id,
1227 LttvHooks *hook_adder,
1228 LttvHooks *hook_remover)
e62a7964 1229{
1230 LttvAttribute *g_attribute = lttv_global_attributes();
1231 LttvAttribute *attribute;
1232 LttvAttributeValue value;
1233
1234 g_assert(attribute =
1235 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1236 LTTV_COMPUTATION)));
1237
1238 g_assert(attribute =
1239 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1240 module_name)));
1241
1242 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1243 LTTV_BEFORE_CHUNK_TRACESET,
1244 LTTV_POINTER,
1245 &value));
1246 *(value.v_pointer) = before_chunk_traceset;
1247
1248 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1249 LTTV_BEFORE_CHUNK_TRACE,
1250 LTTV_POINTER,
1251 &value));
1252 *(value.v_pointer) = before_chunk_trace;
1253
1254 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1255 LTTV_BEFORE_CHUNK_TRACEFILE,
1256 LTTV_POINTER,
1257 &value));
1258 *(value.v_pointer) = before_chunk_tracefile;
1259
1260 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1261 LTTV_AFTER_CHUNK_TRACESET,
1262 LTTV_POINTER,
1263 &value));
1264 *(value.v_pointer) = after_chunk_traceset;
1265
1266 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1267 LTTV_AFTER_CHUNK_TRACE,
1268 LTTV_POINTER,
1269 &value));
1270 *(value.v_pointer) = after_chunk_trace;
1271
1272 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1273 LTTV_AFTER_CHUNK_TRACEFILE,
1274 LTTV_POINTER,
1275 &value));
1276 *(value.v_pointer) = after_chunk_tracefile;
1277
1278 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1279 LTTV_BEFORE_REQUEST,
1280 LTTV_POINTER,
1281 &value));
1282 *(value.v_pointer) = before_request;
1283
1284 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1285 LTTV_AFTER_REQUEST,
1286 LTTV_POINTER,
1287 &value));
1288 *(value.v_pointer) = after_request;
1289
1290 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1291 LTTV_EVENT_HOOK,
1292 LTTV_POINTER,
1293 &value));
1294 *(value.v_pointer) = event_hook;
1295
1296 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1297 LTTV_EVENT_HOOK_BY_ID,
1298 LTTV_POINTER,
1299 &value));
1300 *(value.v_pointer) = event_hook_by_id;
1301
313bd6fc 1302 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1303 LTTV_HOOK_ADDER,
1304 LTTV_POINTER,
1305 &value));
1306 *(value.v_pointer) = hook_adder;
1307
1308 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1309 LTTV_HOOK_REMOVER,
1310 LTTV_POINTER,
1311 &value));
1312 *(value.v_pointer) = hook_remover;
1313
e62a7964 1314}
1315
1316
1317/**
1318 * It removes all the requests than can be currently processed by the
1319 * background computation algorithm for all the traces (list_in and list_out).
1320 *
1321 * Leaves the flag to in_progress or none.. depending if current or queue
1322 *
1323 * @param module_name A GQuark : the name of the module which computes the
1324 * information.
1325 */
1326void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1327{
1328 guint i;
1329
1330 for(i=0;i<lttvwindowtraces_get_number();i++) {
1331 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1332 g_assert(trace_v != NULL);
1333 LttTrace *trace;
1334 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1335 LttvAttributeValue value;
313bd6fc 1336 GSList **queue, **current;
e62a7964 1337 GSList *iter;
1338
1339 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1340 LTTV_REQUESTS_QUEUE,
1341 LTTV_POINTER,
1342 &value));
313bd6fc 1343 queue = (GSList**)(value.v_pointer);
e62a7964 1344
313bd6fc 1345 iter = *queue;
e62a7964 1346 while(iter != NULL) {
1347 gboolean remove = FALSE;
1348 gboolean free_data = FALSE;
1349
1350 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1351
1352 if(bg_req->module_name == module_name) {
1353 remove = TRUE;
1354 free_data = TRUE;
1355 }
1356
1357 /* Go to next */
1358 if(remove)
1359 {
1360 GSList *remove_iter = iter;
1361
1362 iter = g_slist_next(iter);
1363 if(free_data) g_free(remove_iter->data);
313bd6fc 1364 *queue = g_slist_remove_link(*queue, remove_iter);
e62a7964 1365 } else { // not remove
1366 iter = g_slist_next(iter);
1367 }
1368 }
1369
1370
1371 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1372 LTTV_REQUESTS_CURRENT,
1373 LTTV_POINTER,
1374 &value));
313bd6fc 1375 current = (GSList**)(value.v_pointer);
e62a7964 1376
313bd6fc 1377 iter = *current;
e62a7964 1378 while(iter != NULL) {
1379 gboolean remove = FALSE;
1380 gboolean free_data = FALSE;
1381
1382 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1383
1384 if(bg_req->module_name == module_name) {
1385 remove = TRUE;
1386 free_data = TRUE;
1387 }
1388
1389 /* Go to next */
1390 if(remove)
1391 {
1392 GSList *remove_iter = iter;
1393
1394 iter = g_slist_next(iter);
1395 if(free_data) g_free(remove_iter->data);
313bd6fc 1396 *current = g_slist_remove_link(*current, remove_iter);
e62a7964 1397 } else { // not remove
1398 iter = g_slist_next(iter);
1399 }
1400 }
1401 }
1402}
1403
1404
1405/**
1406 * Unregister the background computation hooks for a specific module.
1407 *
1408 * It also removes all the requests than can be currently processed by the
1409 * background computation algorithm for all the traces (list_in and list_out).
1410 *
1411 * @param module_name A GQuark : the name of the module which computes the
1412 * information.
1413 */
1414
1415void lttvwindowtraces_unregister_computation_hooks
1416 (LttvAttributeName module_name)
1417{
1418 LttvAttribute *g_attribute = lttv_global_attributes();
1419 LttvAttribute *attribute;
91fd6881 1420 LttvAttributeValue value;
e62a7964 1421
1422 g_assert(attribute =
1423 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1424 LTTV_COMPUTATION)));
1425 g_assert(attribute =
1426 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1427 module_name)));
1428
1429
91fd6881 1430 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1431 LTTV_BEFORE_CHUNK_TRACESET,
1432 LTTV_POINTER,
1433 &value));
1434 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1435 if(before_chunk_traceset != NULL)
1436 lttv_hooks_destroy(before_chunk_traceset);
1437
1438 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1439 LTTV_BEFORE_CHUNK_TRACE,
1440 LTTV_POINTER,
1441 &value));
1442 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1443 if(before_chunk_trace != NULL)
1444 lttv_hooks_destroy(before_chunk_trace);
1445
1446 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1447 LTTV_BEFORE_CHUNK_TRACEFILE,
1448 LTTV_POINTER,
1449 &value));
1450 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1451 if(before_chunk_tracefile != NULL)
1452 lttv_hooks_destroy(before_chunk_tracefile);
1453
1454 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1455 LTTV_AFTER_CHUNK_TRACESET,
1456 LTTV_POINTER,
1457 &value));
1458 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1459 if(after_chunk_traceset != NULL)
1460 lttv_hooks_destroy(after_chunk_traceset);
1461
1462 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1463 LTTV_AFTER_CHUNK_TRACE,
1464 LTTV_POINTER,
1465 &value));
1466 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1467 if(after_chunk_trace != NULL)
1468 lttv_hooks_destroy(after_chunk_trace);
1469
1470 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1471 LTTV_AFTER_CHUNK_TRACEFILE,
1472 LTTV_POINTER,
1473 &value));
1474 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1475 if(after_chunk_tracefile != NULL)
1476 lttv_hooks_destroy(after_chunk_tracefile);
1477
1478 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1479 LTTV_BEFORE_REQUEST,
1480 LTTV_POINTER,
1481 &value));
1482 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1483 if(before_request != NULL)
1484 lttv_hooks_destroy(before_request);
1485
1486 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1487 LTTV_AFTER_REQUEST,
1488 LTTV_POINTER,
1489 &value));
1490 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1491 if(after_request != NULL)
1492 lttv_hooks_destroy(after_request);
1493
1494 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1495 LTTV_EVENT_HOOK,
1496 LTTV_POINTER,
1497 &value));
1498 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1499 if(event_hook != NULL)
1500 lttv_hooks_destroy(event_hook);
1501
1502 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1503 LTTV_EVENT_HOOK_BY_ID,
1504 LTTV_POINTER,
1505 &value));
1506 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1507 if(event_hook_by_id != NULL)
1508 lttv_hooks_by_id_destroy(event_hook_by_id);
1509
1510 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1511 LTTV_HOOK_ADDER,
1512 LTTV_POINTER,
1513 &value));
1514 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1515 if(hook_adder != NULL)
1516 lttv_hooks_destroy(hook_adder);
1517
1518 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1519 LTTV_HOOK_REMOVER,
1520 LTTV_POINTER,
1521 &value));
1522 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1523 if(hook_remover != NULL)
1524 lttv_hooks_destroy(hook_remover);
1525
1526
e62a7964 1527 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1528 LTTV_EVENT_HOOK_BY_ID);
1529 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1530 LTTV_EVENT_HOOK);
1531
1532 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1533 LTTV_AFTER_REQUEST);
1534 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1535 LTTV_BEFORE_REQUEST);
1536
1537 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1538 LTTV_AFTER_CHUNK_TRACEFILE);
1539 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1540 LTTV_AFTER_CHUNK_TRACE);
1541 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1542 LTTV_AFTER_CHUNK_TRACESET);
1543
1544 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1545 LTTV_BEFORE_CHUNK_TRACEFILE);
1546 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1547 LTTV_BEFORE_CHUNK_TRACE);
1548 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1549 LTTV_BEFORE_CHUNK_TRACESET);
313bd6fc 1550 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1551 LTTV_HOOK_ADDER);
1552 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1553 LTTV_HOOK_REMOVER);
1554
e62a7964 1555 /* finally, remove module name */
1556 g_assert(attribute =
1557 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1558 LTTV_COMPUTATION)));
1559 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1560 module_name);
1561
1562}
1563
b052368a 1564/**
1565 * Lock a trace so no other instance can use it.
1566 *
1567 * @param trace The trace to lock.
1568 * @return 0 on success, -1 if cannot get lock.
1569 */
1570gint lttvwindowtraces_lock(LttvTrace *trace)
1571{
1572 LttvAttribute *attribute = lttv_trace_attribute(trace);
1573 LttvAttributeValue value;
1574 LttvAttributeType type;
1575
1576 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1577 LTTV_LOCK,
1578 &value);
1579 /* Verify the absence of the lock. */
1580 if(type != LTTV_NONE) {
1581 g_critical("Cannot take trace lock");
1582 return -1;
1583 }
1584
1585 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1586 LTTV_LOCK,
1587 LTTV_INT);
1588 /* the value is left unset. The only presence of the attribute is necessary.
1589 */
1590
1591 return 0;
1592}
1593
1594/**
1595 * Unlock a trace.
1596 *
1597 * @param trace The trace to unlock.
1598 * @return 0 on success, -1 if cannot unlock (not locked ?).
1599 */
1600gint lttvwindowtraces_unlock(LttvTrace *trace)
1601{
1602 LttvAttribute *attribute = lttv_trace_attribute(trace);
1603 LttvAttributeType type;
1604 LttvAttributeValue value;
1605
1606 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1607 LTTV_LOCK,
1608 &value);
1609 /* Verify the presence of the lock. */
1610 if(type == LTTV_NONE) {
1611 g_critical("Cannot release trace lock");
1612 return -1;
1613 }
1614
1615 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1616 LTTV_LOCK);
1617
1618 return 0;
1619}
1620
1621/**
1622 * Verify if a trace is locked.
1623 *
1624 * @param trace The trace to verify.
1625 * @return TRUE if locked, FALSE is unlocked.
1626 */
1627gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1628{
1629 LttvAttribute *attribute = lttv_trace_attribute(trace);
1630 LttvAttributeType type;
1631 LttvAttributeValue value;
1632
1633 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1634 LTTV_LOCK,
1635 &value);
1636 /* The only presence of the attribute is necessary. */
1637 if(type == LTTV_NONE)
1638 return FALSE;
1639 else
1640 return TRUE;
1641}
e62a7964 1642
This page took 0.09437 seconds and 4 git commands to generate.