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