header missing
[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>
2eef04b5 26#include <string.h>
0fdb8bb0 27
a1a2b649 28#include <ltt/time.h>
29#include <ltt/trace.h>
30#include <glib.h>
31#include <lttv/lttv.h>
32#include <lttv/traceset.h>
33#include <lttv/attribute.h>
34#include <lttv/tracecontext.h>
35#include <lttvwindow/lttvwindowtraces.h>
8bc02ec8 36#include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
a1a2b649 37
38
39typedef struct _BackgroundRequest {
40 LttvAttributeName module_name; /* Hook path in global attributes,
41 where all standard hooks under computation/.
42 i.e. modulename */
43 LttvTrace *trace; /* trace concerned */
44} BackgroundRequest;
45
46typedef struct _BackgroundNotify {
47 gpointer owner;
48 LttvTrace *trace; /* trace */
49 LttTime notify_time;
50 LttvTracesetContextPosition *notify_position;
51 LttvHooks *notify; /* Hook to call when the notify is
52 passed, or at the end of trace */
53} BackgroundNotify;
54
55
56
313bd6fc 57/* Prototypes */
58gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
59
a1a2b649 60/* Get a trace by its path name.
61 *
62 * @param path path of the trace on the virtual file system.
63 * @return Pointer to trace if found
64 * NULL is returned if the trace is not present
65 */
66
67LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
68{
a1a2b649 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;
8bc02ec8 832
313bd6fc 833 if(trace == NULL)
8bc02ec8 834 return FALSE;
835
836 attribute = lttv_trace_attribute(trace);
837
838 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
839 LTTV_REQUESTS_QUEUE,
840 &value);
841 g_assert(type == LTTV_POINTER);
313bd6fc 842 list_out = (GSList**)(value.v_pointer);
8bc02ec8 843
844 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
845 LTTV_REQUESTS_CURRENT,
846 &value);
847 g_assert(type == LTTV_POINTER);
313bd6fc 848 list_in = (GSList**)(value.v_pointer);
8bc02ec8 849
850 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
851 LTTV_NOTIFY_QUEUE,
852 &value);
853 g_assert(type == LTTV_POINTER);
313bd6fc 854 notify_out = (GSList**)(value.v_pointer);
8bc02ec8 855
856 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
857 LTTV_NOTIFY_CURRENT,
858 &value);
859 g_assert(type == LTTV_POINTER);
313bd6fc 860 notify_in = (GSList**)(value.v_pointer);
8bc02ec8 861
862 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
863 LTTV_COMPUTATION_TRACESET,
864 &value);
865 g_assert(type == LTTV_POINTER);
866 ts = (LttvTraceset*)*(value.v_pointer);
867
868 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
869 LTTV_COMPUTATION_TRACESET_CONTEXT,
870 &value);
871 g_assert(type == LTTV_POINTER);
872 tsc = (LttvTracesetContext*)*(value.v_pointer);
313bd6fc 873 tss = (LttvTracesetStats*)*(value.v_pointer);
8bc02ec8 874 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
313bd6fc 875 g_assert(LTTV_IS_TRACESET_STATS(tss));
8bc02ec8 876
877 /* There is no events requests pending : we should never have been called! */
313bd6fc 878 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
8bc02ec8 879
b052368a 880 /* 0.1 Lock traces */
881 {
882 guint iter_trace=0;
883
884 for(iter_trace=0;
885 iter_trace<lttv_traceset_number(tsc->ts);
886 iter_trace++) {
887 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
888
889 if(lttvwindowtraces_lock(trace_v) != 0)
890 return TRUE; /* Cannot get trace lock, try later */
8bc02ec8 891
b052368a 892 }
893 }
894 /* 0.2 Sync tracefiles */
895 lttv_process_traceset_synchronize_tracefiles(tsc);
8bc02ec8 896
897 /* 1. Before processing */
898 {
899 /* if list_in is empty */
313bd6fc 900 if(g_slist_length(*list_in) == 0) {
8bc02ec8 901
902 {
903 /* - Add all requests in list_out to list_in, empty list_out */
313bd6fc 904 GSList *iter = *list_out;
8bc02ec8 905
906 while(iter != NULL) {
907 gboolean remove = FALSE;
908 gboolean free_data = FALSE;
909
910 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
911
912 remove = TRUE;
913 free_data = FALSE;
313bd6fc 914 *list_in = g_slist_append(*list_in, bg_req);
8bc02ec8 915
916 /* Go to next */
917 if(remove)
918 {
919 GSList *remove_iter = iter;
920
921 iter = g_slist_next(iter);
922 if(free_data) g_free(remove_iter->data);
313bd6fc 923 *list_out = g_slist_remove_link(*list_out, remove_iter);
8bc02ec8 924 } else { // not remove
925 iter = g_slist_next(iter);
926 }
927 }
928 }
929
930 {
313bd6fc 931 GSList *iter = *list_in;
8bc02ec8 932 /* - for each request in list_in */
933 while(iter != NULL) {
934
935 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
91fd6881 936 /* - set hooks'in_progress flag to TRUE */
8bc02ec8 937 lttvwindowtraces_set_in_progress(bg_req->module_name,
938 bg_req->trace);
91fd6881 939
940 /* - call before request hook */
941 /* Get before request hook */
942 LttvAttribute *module_attribute;
943
944 g_assert(module_attribute =
945 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
946 LTTV_IATTRIBUTE(g_attribute),
947 LTTV_COMPUTATION)));
948
949 g_assert(module_attribute =
950 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
951 LTTV_IATTRIBUTE(module_attribute),
952 bg_req->module_name)));
953
954 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
955 LTTV_BEFORE_REQUEST,
956 &value);
957 g_assert(type == LTTV_POINTER);
958 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
91fd6881 959
960 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
8bc02ec8 961
962 iter = g_slist_next(iter);
963 }
964 }
965
966 /* - seek trace to start */
967 {
968 LttTime start = { 0, 0};
969 lttv_process_traceset_seek_time(tsc, start);
970 }
971
972 /* - Move all notifications from notify_out to notify_in. */
973 {
313bd6fc 974 GSList *iter = *notify_out;
975 g_assert(g_slist_length(*notify_in) == 0);
8bc02ec8 976
977 while(iter != NULL) {
978 gboolean remove = FALSE;
979 gboolean free_data = FALSE;
980
981 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
982
983 remove = TRUE;
984 free_data = FALSE;
313bd6fc 985 *notify_in = g_slist_append(*notify_in, notify_req);
8bc02ec8 986
987 /* Go to next */
988 if(remove)
989 {
990 GSList *remove_iter = iter;
991
992 iter = g_slist_next(iter);
b052368a 993 if(free_data)
994 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 995 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
8bc02ec8 996 } else { // not remove
997 iter = g_slist_next(iter);
998 }
999 }
1000 }
1001 }
1002
1003 {
313bd6fc 1004 GSList *iter = *list_in;
1ce324c6 1005 LttvHooks *hook_adder = lttv_hooks_new();
8bc02ec8 1006 /* - for each request in list_in */
1007 while(iter != NULL) {
1008
1009 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1010 /*- Call before chunk hooks for list_in*/
1011 /*- add hooks to context*/
1012 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1ce324c6 1013 tsc,
1014 hook_adder);
8bc02ec8 1015 iter = g_slist_next(iter);
1016 }
1ce324c6 1017 lttv_hooks_call(hook_adder,tsc);
1018 lttv_hooks_destroy(hook_adder);
8bc02ec8 1019 }
1020 }
1021
1022 /* 2. call process traceset middle for a chunk */
1023 {
1024 /*(assert list_in is not empty! : should not even be called in that case)*/
0aa6c3a1 1025 LttTime end = ltt_time_infinite;
313bd6fc 1026 g_assert(g_slist_length(*list_in) != 0);
8bc02ec8 1027
1028 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1029 }
1030
1031 /* 3. After the chunk */
1032 {
1033 /* 3.1 call after_chunk hooks for list_in */
1034 {
313bd6fc 1035 GSList *iter = *list_in;
1ce324c6 1036 LttvHooks *hook_remover = lttv_hooks_new();
8bc02ec8 1037 /* - for each request in list_in */
1038 while(iter != NULL) {
1039
1040 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1041 /* - Call after chunk hooks for list_in */
1042 /* - remove hooks from context */
1043 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1ce324c6 1044 tsc,
1045 hook_remover);
8bc02ec8 1046 iter = g_slist_next(iter);
1047 }
1ce324c6 1048 lttv_hooks_call(hook_remover,tsc);
1049 lttv_hooks_destroy(hook_remover);
8bc02ec8 1050 }
1051
1052 /* 3.2 for each notify_in */
1053 {
313bd6fc 1054 GSList *iter = *notify_in;
8bc02ec8 1055 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1056
1057 while(iter != NULL) {
1058 gboolean remove = FALSE;
1059 gboolean free_data = FALSE;
1060
1061 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1062
1063 /* - if current time >= notify time, call notify and remove from
1064 * notify_in.
1065 * - if current position >= notify position, call notify and remove
1066 * from notify_in.
1067 */
1068 if( (tfc != NULL &&
313bd6fc 1069 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
8bc02ec8 1070 ||
313bd6fc 1071 (notify_req->notify_position != NULL &&
1072 lttv_traceset_context_ctx_pos_compare(tsc,
1073 notify_req->notify_position) >= 0)
8bc02ec8 1074 ) {
1075
1076 lttv_hooks_call(notify_req->notify, notify_req);
1077
1078 remove = TRUE;
1079 free_data = TRUE;
1080 }
1081
1082 /* Go to next */
1083 if(remove)
1084 {
1085 GSList *remove_iter = iter;
1086
1087 iter = g_slist_next(iter);
b052368a 1088 if(free_data)
1089 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1090 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
8bc02ec8 1091 } else { // not remove
1092 iter = g_slist_next(iter);
1093 }
1094 }
1095 }
1096
1097 {
1098 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1099 /* 3.3 if end of trace reached */
313bd6fc 1100 if(tfc != NULL)
1101 g_debug("Current time : %lu sec, %lu nsec",
1102 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
8bc02ec8 1103 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1104 tsc->time_span.end_time) > 0) {
1105
1106 /* - for each request in list_in */
1107 {
313bd6fc 1108 GSList *iter = *list_in;
8bc02ec8 1109
1110 while(iter != NULL) {
1111 gboolean remove = FALSE;
1112 gboolean free_data = FALSE;
1113
1114 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1115
1116 /* - set hooks'in_progress flag to FALSE */
1117 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1118 bg_req->trace);
1119 /* - set hooks'ready flag to TRUE */
1120 lttvwindowtraces_set_ready(bg_req->module_name,
1121 bg_req->trace);
91fd6881 1122 /* - call after request hook */
1123 /* Get after request hook */
1124 LttvAttribute *module_attribute;
1125
1126 g_assert(module_attribute =
1127 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1128 LTTV_IATTRIBUTE(g_attribute),
1129 LTTV_COMPUTATION)));
1130
1131 g_assert(module_attribute =
1132 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1133 LTTV_IATTRIBUTE(module_attribute),
1134 bg_req->module_name)));
1135
1136 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1137 LTTV_AFTER_REQUEST,
1138 &value);
1139 g_assert(type == LTTV_POINTER);
1140 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1141
1142 if(after_request != NULL) lttv_hooks_call(after_request, tsc);
8bc02ec8 1143 /* - remove request */
1144 remove = TRUE;
1145 free_data = TRUE;
1146
1147 /* Go to next */
1148 if(remove)
1149 {
1150 GSList *remove_iter = iter;
1151
1152 iter = g_slist_next(iter);
1153 if(free_data) g_free(remove_iter->data);
313bd6fc 1154 *list_in = g_slist_remove_link(*list_in, remove_iter);
8bc02ec8 1155 } else { // not remove
1156 iter = g_slist_next(iter);
1157 }
1158 }
1159 }
1160
1161 /* - for each notifications in notify_in */
1162 {
313bd6fc 1163 GSList *iter = *notify_in;
8bc02ec8 1164
1165 while(iter != NULL) {
1166 gboolean remove = FALSE;
1167 gboolean free_data = FALSE;
1168
1169 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1170
1171 /* - call notify and remove from notify_in */
1172 lttv_hooks_call(notify_req->notify, notify_req);
1173 remove = TRUE;
1174 free_data = TRUE;
1175
1176 /* Go to next */
1177 if(remove)
1178 {
1179 GSList *remove_iter = iter;
1180
1181 iter = g_slist_next(iter);
b052368a 1182 if(free_data)
1183 notify_request_free((BackgroundNotify*)remove_iter->data);
313bd6fc 1184 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
8bc02ec8 1185 } else { // not remove
1186 iter = g_slist_next(iter);
1187 }
1188 }
1189 }
1ce324c6 1190 {
1191 /* - reset the context */
1192 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1193 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1194 }
3710295e 1195 /* - if list_out is empty */
1196 if(g_slist_length(*list_out) == 0) {
1197 /* - return FALSE (scheduler stopped) */
1198 g_debug("Background computation scheduler stopped");
1199 g_info("Background computation finished for trace %p", trace);
1200 /* FIXME : remove status bar info, need context id and message id */
1201 ret_val = FALSE;
1202 } else {
1203 ret_val = TRUE;
1204 }
8bc02ec8 1205 } else {
1206 /* 3.4 else, end of trace not reached */
1207 /* - return TRUE (scheduler still registered) */
313bd6fc 1208 g_debug("Background computation left");
b052368a 1209 ret_val = TRUE;
8bc02ec8 1210 }
1211 }
1212 }
b052368a 1213 /* 4. Unlock traces */
1214 {
1215 //lttv_process_traceset_get_sync_data(tsc);
1216 guint iter_trace;
1217
1218 for(iter_trace=0;
1219 iter_trace<lttv_traceset_number(tsc->ts);
1220 iter_trace++) {
1221 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1222
1223 lttvwindowtraces_unlock(trace_v);
1224 }
1225 }
1226 return ret_val;
8bc02ec8 1227}
e62a7964 1228
1229
1230
1231/**
1232 * Register the background computation hooks for a specific module. It adds the
313bd6fc 1233 * computation hooks to the global attrubutes, under "computation/module name".
e62a7964 1234 *
1235 * @param module_name A GQuark : the name of the module which computes the
1236 * information.
1237 */
1238void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1239 LttvHooks *before_chunk_traceset,
1240 LttvHooks *before_chunk_trace,
1241 LttvHooks *before_chunk_tracefile,
1242 LttvHooks *after_chunk_traceset,
1243 LttvHooks *after_chunk_trace,
1244 LttvHooks *after_chunk_tracefile,
1245 LttvHooks *before_request,
1246 LttvHooks *after_request,
1247 LttvHooks *event_hook,
313bd6fc 1248 LttvHooksById *event_hook_by_id,
1249 LttvHooks *hook_adder,
1250 LttvHooks *hook_remover)
e62a7964 1251{
1252 LttvAttribute *g_attribute = lttv_global_attributes();
1253 LttvAttribute *attribute;
1254 LttvAttributeValue value;
1255
1256 g_assert(attribute =
1257 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1258 LTTV_COMPUTATION)));
1259
1260 g_assert(attribute =
1261 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1262 module_name)));
1263
1264 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1265 LTTV_BEFORE_CHUNK_TRACESET,
1266 LTTV_POINTER,
1267 &value));
1268 *(value.v_pointer) = before_chunk_traceset;
1269
1270 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1271 LTTV_BEFORE_CHUNK_TRACE,
1272 LTTV_POINTER,
1273 &value));
1274 *(value.v_pointer) = before_chunk_trace;
1275
1276 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1277 LTTV_BEFORE_CHUNK_TRACEFILE,
1278 LTTV_POINTER,
1279 &value));
1280 *(value.v_pointer) = before_chunk_tracefile;
1281
1282 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1283 LTTV_AFTER_CHUNK_TRACESET,
1284 LTTV_POINTER,
1285 &value));
1286 *(value.v_pointer) = after_chunk_traceset;
1287
1288 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1289 LTTV_AFTER_CHUNK_TRACE,
1290 LTTV_POINTER,
1291 &value));
1292 *(value.v_pointer) = after_chunk_trace;
1293
1294 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1295 LTTV_AFTER_CHUNK_TRACEFILE,
1296 LTTV_POINTER,
1297 &value));
1298 *(value.v_pointer) = after_chunk_tracefile;
1299
1300 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1301 LTTV_BEFORE_REQUEST,
1302 LTTV_POINTER,
1303 &value));
1304 *(value.v_pointer) = before_request;
1305
1306 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1307 LTTV_AFTER_REQUEST,
1308 LTTV_POINTER,
1309 &value));
1310 *(value.v_pointer) = after_request;
1311
1312 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1313 LTTV_EVENT_HOOK,
1314 LTTV_POINTER,
1315 &value));
1316 *(value.v_pointer) = event_hook;
1317
1318 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1319 LTTV_EVENT_HOOK_BY_ID,
1320 LTTV_POINTER,
1321 &value));
1322 *(value.v_pointer) = event_hook_by_id;
1323
313bd6fc 1324 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1325 LTTV_HOOK_ADDER,
1326 LTTV_POINTER,
1327 &value));
1328 *(value.v_pointer) = hook_adder;
1329
1330 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1331 LTTV_HOOK_REMOVER,
1332 LTTV_POINTER,
1333 &value));
1334 *(value.v_pointer) = hook_remover;
1335
e62a7964 1336}
1337
1338
1339/**
1340 * It removes all the requests than can be currently processed by the
1341 * background computation algorithm for all the traces (list_in and list_out).
1342 *
1343 * Leaves the flag to in_progress or none.. depending if current or queue
1344 *
1345 * @param module_name A GQuark : the name of the module which computes the
1346 * information.
1347 */
1348void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1349{
1350 guint i;
1351
1352 for(i=0;i<lttvwindowtraces_get_number();i++) {
1353 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1354 g_assert(trace_v != NULL);
1355 LttTrace *trace;
1356 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1357 LttvAttributeValue value;
313bd6fc 1358 GSList **queue, **current;
e62a7964 1359 GSList *iter;
1360
1361 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1362 LTTV_REQUESTS_QUEUE,
1363 LTTV_POINTER,
1364 &value));
313bd6fc 1365 queue = (GSList**)(value.v_pointer);
e62a7964 1366
313bd6fc 1367 iter = *queue;
e62a7964 1368 while(iter != NULL) {
1369 gboolean remove = FALSE;
1370 gboolean free_data = FALSE;
1371
1372 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1373
1374 if(bg_req->module_name == module_name) {
1375 remove = TRUE;
1376 free_data = TRUE;
1377 }
1378
1379 /* Go to next */
1380 if(remove)
1381 {
1382 GSList *remove_iter = iter;
1383
1384 iter = g_slist_next(iter);
1385 if(free_data) g_free(remove_iter->data);
313bd6fc 1386 *queue = g_slist_remove_link(*queue, remove_iter);
e62a7964 1387 } else { // not remove
1388 iter = g_slist_next(iter);
1389 }
1390 }
1391
1392
1393 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1394 LTTV_REQUESTS_CURRENT,
1395 LTTV_POINTER,
1396 &value));
313bd6fc 1397 current = (GSList**)(value.v_pointer);
e62a7964 1398
313bd6fc 1399 iter = *current;
e62a7964 1400 while(iter != NULL) {
1401 gboolean remove = FALSE;
1402 gboolean free_data = FALSE;
1403
1404 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1405
1406 if(bg_req->module_name == module_name) {
1407 remove = TRUE;
1408 free_data = TRUE;
1409 }
1410
1411 /* Go to next */
1412 if(remove)
1413 {
1414 GSList *remove_iter = iter;
1415
1416 iter = g_slist_next(iter);
1417 if(free_data) g_free(remove_iter->data);
313bd6fc 1418 *current = g_slist_remove_link(*current, remove_iter);
e62a7964 1419 } else { // not remove
1420 iter = g_slist_next(iter);
1421 }
1422 }
1423 }
1424}
1425
1426
1427/**
1428 * Unregister the background computation hooks for a specific module.
1429 *
1430 * It also removes all the requests than can be currently processed by the
1431 * background computation algorithm for all the traces (list_in and list_out).
1432 *
1433 * @param module_name A GQuark : the name of the module which computes the
1434 * information.
1435 */
1436
1437void lttvwindowtraces_unregister_computation_hooks
1438 (LttvAttributeName module_name)
1439{
1440 LttvAttribute *g_attribute = lttv_global_attributes();
1441 LttvAttribute *attribute;
91fd6881 1442 LttvAttributeValue value;
e62a7964 1443
1444 g_assert(attribute =
1445 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1446 LTTV_COMPUTATION)));
1447 g_assert(attribute =
1448 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1449 module_name)));
1450
1451
91fd6881 1452 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1453 LTTV_BEFORE_CHUNK_TRACESET,
1454 LTTV_POINTER,
1455 &value));
1456 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1457 if(before_chunk_traceset != NULL)
1458 lttv_hooks_destroy(before_chunk_traceset);
1459
1460 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1461 LTTV_BEFORE_CHUNK_TRACE,
1462 LTTV_POINTER,
1463 &value));
1464 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1465 if(before_chunk_trace != NULL)
1466 lttv_hooks_destroy(before_chunk_trace);
1467
1468 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1469 LTTV_BEFORE_CHUNK_TRACEFILE,
1470 LTTV_POINTER,
1471 &value));
1472 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1473 if(before_chunk_tracefile != NULL)
1474 lttv_hooks_destroy(before_chunk_tracefile);
1475
1476 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1477 LTTV_AFTER_CHUNK_TRACESET,
1478 LTTV_POINTER,
1479 &value));
1480 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1481 if(after_chunk_traceset != NULL)
1482 lttv_hooks_destroy(after_chunk_traceset);
1483
1484 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1485 LTTV_AFTER_CHUNK_TRACE,
1486 LTTV_POINTER,
1487 &value));
1488 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1489 if(after_chunk_trace != NULL)
1490 lttv_hooks_destroy(after_chunk_trace);
1491
1492 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1493 LTTV_AFTER_CHUNK_TRACEFILE,
1494 LTTV_POINTER,
1495 &value));
1496 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1497 if(after_chunk_tracefile != NULL)
1498 lttv_hooks_destroy(after_chunk_tracefile);
1499
1500 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1501 LTTV_BEFORE_REQUEST,
1502 LTTV_POINTER,
1503 &value));
1504 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1505 if(before_request != NULL)
1506 lttv_hooks_destroy(before_request);
1507
1508 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1509 LTTV_AFTER_REQUEST,
1510 LTTV_POINTER,
1511 &value));
1512 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1513 if(after_request != NULL)
1514 lttv_hooks_destroy(after_request);
1515
1516 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1517 LTTV_EVENT_HOOK,
1518 LTTV_POINTER,
1519 &value));
1520 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1521 if(event_hook != NULL)
1522 lttv_hooks_destroy(event_hook);
1523
1524 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1525 LTTV_EVENT_HOOK_BY_ID,
1526 LTTV_POINTER,
1527 &value));
1528 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1529 if(event_hook_by_id != NULL)
1530 lttv_hooks_by_id_destroy(event_hook_by_id);
1531
1532 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1533 LTTV_HOOK_ADDER,
1534 LTTV_POINTER,
1535 &value));
1536 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1537 if(hook_adder != NULL)
1538 lttv_hooks_destroy(hook_adder);
1539
1540 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1541 LTTV_HOOK_REMOVER,
1542 LTTV_POINTER,
1543 &value));
1544 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1545 if(hook_remover != NULL)
1546 lttv_hooks_destroy(hook_remover);
1547
1548
e62a7964 1549 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1550 LTTV_EVENT_HOOK_BY_ID);
1551 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1552 LTTV_EVENT_HOOK);
1553
1554 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1555 LTTV_AFTER_REQUEST);
1556 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1557 LTTV_BEFORE_REQUEST);
1558
1559 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1560 LTTV_AFTER_CHUNK_TRACEFILE);
1561 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1562 LTTV_AFTER_CHUNK_TRACE);
1563 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1564 LTTV_AFTER_CHUNK_TRACESET);
1565
1566 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1567 LTTV_BEFORE_CHUNK_TRACEFILE);
1568 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1569 LTTV_BEFORE_CHUNK_TRACE);
1570 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1571 LTTV_BEFORE_CHUNK_TRACESET);
313bd6fc 1572 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1573 LTTV_HOOK_ADDER);
1574 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1575 LTTV_HOOK_REMOVER);
1576
e62a7964 1577 /* finally, remove module name */
1578 g_assert(attribute =
1579 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1580 LTTV_COMPUTATION)));
1581 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1582 module_name);
1583
1584}
1585
b052368a 1586/**
1587 * Lock a trace so no other instance can use it.
1588 *
1589 * @param trace The trace to lock.
1590 * @return 0 on success, -1 if cannot get lock.
1591 */
1592gint lttvwindowtraces_lock(LttvTrace *trace)
1593{
1594 LttvAttribute *attribute = lttv_trace_attribute(trace);
1595 LttvAttributeValue value;
1596 LttvAttributeType type;
1597
1598 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1599 LTTV_LOCK,
1600 &value);
1601 /* Verify the absence of the lock. */
1602 if(type != LTTV_NONE) {
1603 g_critical("Cannot take trace lock");
1604 return -1;
1605 }
1606
1607 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1608 LTTV_LOCK,
1609 LTTV_INT);
1610 /* the value is left unset. The only presence of the attribute is necessary.
1611 */
1612
1613 return 0;
1614}
1615
1616/**
1617 * Unlock a trace.
1618 *
1619 * @param trace The trace to unlock.
1620 * @return 0 on success, -1 if cannot unlock (not locked ?).
1621 */
1622gint lttvwindowtraces_unlock(LttvTrace *trace)
1623{
1624 LttvAttribute *attribute = lttv_trace_attribute(trace);
1625 LttvAttributeType type;
1626 LttvAttributeValue value;
1627
1628 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1629 LTTV_LOCK,
1630 &value);
1631 /* Verify the presence of the lock. */
1632 if(type == LTTV_NONE) {
1633 g_critical("Cannot release trace lock");
1634 return -1;
1635 }
1636
1637 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1638 LTTV_LOCK);
1639
1640 return 0;
1641}
1642
1643/**
1644 * Verify if a trace is locked.
1645 *
1646 * @param trace The trace to verify.
1647 * @return TRUE if locked, FALSE is unlocked.
1648 */
1649gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1650{
1651 LttvAttribute *attribute = lttv_trace_attribute(trace);
1652 LttvAttributeType type;
1653 LttvAttributeValue value;
1654
1655 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1656 LTTV_LOCK,
1657 &value);
1658 /* The only presence of the attribute is necessary. */
1659 if(type == LTTV_NONE)
1660 return FALSE;
1661 else
1662 return TRUE;
1663}
e62a7964 1664
This page took 0.096011 seconds and 4 git commands to generate.