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