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