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