put print fields in print.c
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / lttvwindowtraces.c
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
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <string.h>
31
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>
40 #include <lttvwindow/lttvwindow.h> // for CHUNK_NUM_EVENTS
41
42
43 typedef 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
50 typedef 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
61 /* Prototypes */
62 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace);
63
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
71 LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
72 {
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;
79 g_assert(trace_v != NULL);
80
81 trace = lttv_trace(trace_v);
82 g_assert(trace != NULL);
83 name = g_quark_to_string(ltt_trace_name(trace));
84
85 if(strcmp(name, path) == 0) {
86 /* Found */
87 return trace_v;
88 }
89 }
90
91 return NULL;
92 }
93
94 /* Get a trace by its number identifier */
95
96 LttvTrace *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
119 guint 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
134 void lttvwindowtraces_add_trace(LttvTrace *trace)
135 {
136 LttvAttribute *g_attribute = lttv_global_attributes();
137 LttvAttribute *attribute;
138 LttvAttributeValue value;
139 guint num;
140 struct stat buf;
141 gchar attribute_path[PATH_MAX];
142
143 if(stat(g_quark_to_string(ltt_trace_name(lttv_trace(trace))), &buf)) {
144 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
145 g_quark_to_string(ltt_trace_name(lttv_trace(trace))));
146 return;
147 }
148 g_assert(
149 snprintf(attribute_path, PATH_MAX, "%llu:%llu", buf.st_dev, buf.st_ino) >= 0);
150
151 g_assert(attribute =
152 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
153 LTTV_TRACES)));
154
155 value = lttv_attribute_add(attribute,
156 g_quark_from_string(attribute_path),
157 LTTV_POINTER);
158
159 *(value.v_pointer) = (gpointer)trace;
160
161 /* create new traceset and tracesetcontext */
162 LttvTraceset *ts;
163 LttvTracesetStats *tss;
164 //LttvTracesetContextPosition *sync_position;
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));
180 tss = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
181 *(value.v_pointer) = tss;
182
183 lttv_context_init(LTTV_TRACESET_CONTEXT(tss), ts);
184 #if 0
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 #endif //0
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
209 }
210
211 /* Remove a trace from the global attributes */
212
213 void 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
229 /* Remove and background computation that could be in progress */
230 g_idle_remove_by_data(trace_v);
231
232 if(trace_v == trace) {
233 /* Found */
234 LttvAttribute *l_attribute;
235
236 /* destroy traceset and tracesetcontext */
237 LttvTraceset *ts;
238 LttvTracesetStats *tss;
239 //LttvTracesetContextPosition *sync_position;
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 #if 0
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 lttv_traceset_context_position_destroy(sync_position);
268
269 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
270 LTTV_COMPUTATION_SYNC_POSITION);
271
272 #endif //0
273 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(l_attribute),
274 LTTV_COMPUTATION_TRACESET_CONTEXT,
275 LTTV_POINTER,
276 &value));
277 tss = (LttvTracesetStats*)*(value.v_pointer);
278
279 lttv_context_fini(LTTV_TRACESET_CONTEXT(tss));
280 g_object_unref(tss);
281 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
282 LTTV_COMPUTATION_TRACESET_CONTEXT);
283 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(l_attribute),
284 LTTV_COMPUTATION_TRACESET);
285 /* Destroy the traceset and the trace also */
286 lttv_traceset_destroy(ts);
287
288 /* finally, remove the global attribute */
289 lttv_attribute_remove(attribute, i);
290
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
307 void lttvwindowtraces_background_request_queue
308 (LttvTrace *trace, gchar *module_name)
309 {
310 BackgroundRequest *bg_req;
311 LttvAttribute *attribute = lttv_trace_attribute(trace);
312 LttvAttribute *g_attribute = lttv_global_attributes();
313 LttvAttribute *module_attribute;
314 LttvAttributeValue value;
315 LttvAttributeType type;
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);
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
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);
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);
351 /* FIXME : show message in status bar, need context and message id */
352 g_info("Background computation started for trace %p", trace);
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
372 void 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
413 void 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 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
432 LTTV_COMPUTATION_TRACESET_CONTEXT,
433 LTTV_POINTER,
434 &value));
435 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
436
437 bg_notify = g_new(BackgroundNotify,1);
438
439 bg_notify->owner = owner;
440 bg_notify->trace = trace;
441 bg_notify->notify_time = notify_time;
442 if(notify_position != NULL) {
443 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
444 lttv_traceset_context_position_copy(bg_notify->notify_position,
445 notify_position);
446 } else {
447 bg_notify->notify_position = NULL;
448 }
449
450 bg_notify->notify = lttv_hooks_new();
451 lttv_hooks_add_list(bg_notify->notify, notify);
452
453 *slist = g_slist_append(*slist, bg_notify);
454 }
455
456 /**
457 * Register a callback to be called when requested data is passed in the current
458 * background processing.
459 *
460 * @param owner owner of the background notification
461 * @param trace the trace computed
462 * @param notify_time time when notification hooks must be called
463 * @param notify_position position when notification hooks must be called
464 * @param notify Hook to call when the notify position is passed
465 */
466
467 void lttvwindowtraces_background_notify_current
468 (gpointer owner,
469 LttvTrace *trace,
470 LttTime notify_time,
471 const LttvTracesetContextPosition *notify_position,
472 const LttvHooks *notify)
473 {
474 BackgroundNotify *bg_notify;
475 LttvAttribute *attribute = lttv_trace_attribute(trace);
476 LttvAttributeValue value;
477 GSList **slist;
478
479 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
480 LTTV_NOTIFY_CURRENT,
481 LTTV_POINTER,
482 &value));
483 slist = (GSList**)(value.v_pointer);
484
485 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
486 LTTV_COMPUTATION_TRACESET_CONTEXT,
487 LTTV_POINTER,
488 &value));
489 LttvTracesetContext *tsc = (LttvTracesetContext*)(value.v_pointer);
490
491
492 bg_notify = g_new(BackgroundNotify,1);
493
494 bg_notify->owner = owner;
495 bg_notify->trace = trace;
496 bg_notify->notify_time = notify_time;
497 if(notify_position!= NULL) {
498 bg_notify->notify_position = lttv_traceset_context_position_new(tsc);
499 lttv_traceset_context_position_copy(bg_notify->notify_position,
500 notify_position);
501 } else {
502 bg_notify->notify_position = NULL;
503 }
504 bg_notify->notify = lttv_hooks_new();
505 lttv_hooks_add_list(bg_notify->notify, notify);
506
507 *slist = g_slist_append(*slist, bg_notify);
508 }
509
510
511 static void notify_request_free(BackgroundNotify *notify_req)
512 {
513 if(notify_req == NULL) return;
514
515 if(notify_req->notify_position != NULL)
516 lttv_traceset_context_position_destroy(notify_req->notify_position);
517 if(notify_req->notify != NULL)
518 lttv_hooks_destroy(notify_req->notify);
519 g_free(notify_req);
520 }
521
522 /**
523 * Removes all the notifications requests from a specific viewer.
524 *
525 * @param owner owner of the background notification
526 */
527
528 void lttvwindowtraces_background_notify_remove(gpointer owner)
529 {
530 guint i;
531
532 for(i=0;i<lttvwindowtraces_get_number();i++) {
533 LttvAttribute *attribute;
534 LttvAttributeValue value;
535 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
536 GSList **slist;
537 GSList *iter = NULL;
538
539 g_assert(trace_v != NULL);
540
541 attribute = lttv_trace_attribute(trace_v);
542
543 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
544 LTTV_NOTIFY_QUEUE,
545 LTTV_POINTER,
546 &value));
547 slist = (GSList**)(value.v_pointer);
548
549 for(iter=*slist;iter!=NULL;) {
550
551 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
552
553 if(bg_notify->owner == owner) {
554 GSList *rem_iter = iter;
555 iter=g_slist_next(iter);
556 notify_request_free(bg_notify);
557 *slist = g_slist_remove_link(*slist, rem_iter);
558 } else {
559 iter=g_slist_next(iter);
560 }
561 }
562
563 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
564 LTTV_NOTIFY_CURRENT,
565 LTTV_POINTER,
566 &value));
567 slist = (GSList**)(value.v_pointer);
568
569 for(iter=*slist;iter!=NULL;) {
570
571 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
572
573 if(bg_notify->owner == owner) {
574 GSList *rem_iter = iter;
575 iter=g_slist_next(iter);
576 notify_request_free(bg_notify);
577 *slist = g_slist_remove_link(*slist, rem_iter);
578 } else {
579 iter=g_slist_next(iter);
580 }
581 }
582 }
583 }
584
585
586 /* Background processing helper functions */
587
588 void lttvwindowtraces_add_computation_hooks(LttvAttributeName module_name,
589 LttvTracesetContext *tsc,
590 LttvHooks *hook_adder)
591 {
592 LttvAttribute *g_attribute = lttv_global_attributes();
593 LttvAttribute *module_attribute;
594 LttvAttributeType type;
595 LttvAttributeValue value;
596
597
598 g_assert(module_attribute =
599 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
600 LTTV_COMPUTATION)));
601
602 g_assert(module_attribute =
603 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
604 LTTV_IATTRIBUTE(module_attribute),
605 module_name)));
606
607 /* Call the module's hook adder */
608 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
609 LTTV_HOOK_ADDER,
610 &value);
611 if(type == LTTV_POINTER) {
612 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
613 if(hook_adder != NULL)
614 lttv_hooks_add_list(hook_adder, (LttvHooks*)*(value.v_pointer));
615 }
616 }
617
618 void lttvwindowtraces_remove_computation_hooks(LttvAttributeName module_name,
619 LttvTracesetContext *tsc,
620 LttvHooks *hook_remover)
621 {
622 LttvAttribute *g_attribute = lttv_global_attributes();
623 LttvAttribute *module_attribute;
624 LttvAttributeType type;
625 LttvAttributeValue value;
626
627 g_assert(module_attribute =
628 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
629 LTTV_COMPUTATION)));
630
631 g_assert(module_attribute =
632 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
633 LTTV_IATTRIBUTE(module_attribute),
634 module_name)));
635
636 /* Call the module's hook remover */
637 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
638 LTTV_HOOK_REMOVER,
639 &value);
640 if(type == LTTV_POINTER) {
641 //lttv_hooks_call((LttvHooks*)*(value.v_pointer), (gpointer)tss);
642 if(hook_remover != NULL)
643 lttv_hooks_add_list(hook_remover, (LttvHooks*)*(value.v_pointer));
644 }
645 }
646
647 void lttvwindowtraces_call_before_chunk(LttvAttributeName module_name,
648 LttvTracesetContext *tsc)
649 {
650 LttvAttribute *g_attribute = lttv_global_attributes();
651 LttvAttribute *module_attribute;
652 LttvAttributeType type;
653 LttvAttributeValue value;
654 LttvHooks *before_chunk_traceset=NULL;
655 LttvHooks *before_chunk_trace=NULL;
656 LttvHooks *before_chunk_tracefile=NULL;
657 LttvHooks *event_hook=NULL;
658 LttvHooksById *event_hook_by_id=NULL;
659 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
660
661
662 g_assert(module_attribute =
663 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
664 LTTV_COMPUTATION)));
665
666 g_assert(module_attribute =
667 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
668 LTTV_IATTRIBUTE(module_attribute),
669 module_name)));
670
671 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
672 LTTV_BEFORE_CHUNK_TRACESET,
673 &value);
674 if(type == LTTV_POINTER) {
675 before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
676 }
677
678 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
679 LTTV_BEFORE_CHUNK_TRACE,
680 &value);
681 if(type == LTTV_POINTER) {
682 before_chunk_trace = (LttvHooks*)*(value.v_pointer);
683 }
684
685 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
686 LTTV_BEFORE_CHUNK_TRACEFILE,
687 &value);
688 if(type == LTTV_POINTER) {
689 before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
690 }
691
692 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
693 LTTV_EVENT_HOOK,
694 &value);
695 if(type == LTTV_POINTER) {
696 event_hook = (LttvHooks*)*(value.v_pointer);
697 }
698
699 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
700 LTTV_EVENT_HOOK_BY_ID,
701 &value);
702 if(type == LTTV_POINTER) {
703 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
704 }
705
706 lttv_process_traceset_begin(tsc,
707 before_chunk_traceset,
708 before_chunk_trace,
709 before_chunk_tracefile,
710 event_hook,
711 event_hook_by_id);
712 }
713
714
715
716 void lttvwindowtraces_call_after_chunk(LttvAttributeName module_name,
717 LttvTracesetContext *tsc)
718 {
719 LttvAttribute *g_attribute = lttv_global_attributes();
720 LttvAttribute *module_attribute;
721 LttvAttributeType type;
722 LttvAttributeValue value;
723 LttvHooks *after_chunk_traceset=NULL;
724 LttvHooks *after_chunk_trace=NULL;
725 LttvHooks *after_chunk_tracefile=NULL;
726 LttvHooks *event_hook=NULL;
727 LttvHooksById *event_hook_by_id=NULL;
728 LttvTracesetStats *tss = LTTV_TRACESET_STATS(tsc);
729
730 g_assert(module_attribute =
731 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
732 LTTV_COMPUTATION)));
733
734 g_assert(module_attribute =
735 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
736 LTTV_IATTRIBUTE(module_attribute),
737 module_name)));
738
739 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
740 LTTV_AFTER_CHUNK_TRACESET,
741 &value);
742 if(type == LTTV_POINTER) {
743 after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
744 }
745
746 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
747 LTTV_AFTER_CHUNK_TRACE,
748 &value);
749 if(type == LTTV_POINTER) {
750 after_chunk_trace = (LttvHooks*)*(value.v_pointer);
751 }
752
753 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
754 LTTV_AFTER_CHUNK_TRACEFILE,
755 &value);
756 if(type == LTTV_POINTER) {
757 after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
758 }
759
760 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
761 LTTV_EVENT_HOOK,
762 &value);
763 if(type == LTTV_POINTER) {
764 event_hook = (LttvHooks*)*(value.v_pointer);
765 }
766
767 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
768 LTTV_EVENT_HOOK_BY_ID,
769 &value);
770 if(type == LTTV_POINTER) {
771 event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
772 }
773
774 lttv_process_traceset_end(tsc,
775 after_chunk_traceset,
776 after_chunk_trace,
777 after_chunk_tracefile,
778 event_hook,
779 event_hook_by_id);
780
781 }
782
783
784 void lttvwindowtraces_set_in_progress(LttvAttributeName module_name,
785 LttvTrace *trace)
786 {
787 LttvAttribute *attribute = lttv_trace_attribute(trace);
788 LttvAttributeValue value;
789
790 g_assert(attribute =
791 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
792 module_name)));
793
794 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
795 LTTV_IN_PROGRESS,
796 LTTV_INT);
797 /* the value is left unset. The only presence of the attribute is necessary.
798 */
799 }
800
801 void lttvwindowtraces_unset_in_progress(LttvAttributeName module_name,
802 LttvTrace *trace)
803 {
804 LttvAttribute *attribute = lttv_trace_attribute(trace);
805
806 g_assert(attribute =
807 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
808 module_name)));
809
810 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
811 LTTV_IN_PROGRESS);
812 }
813
814 gboolean lttvwindowtraces_get_in_progress(LttvAttributeName module_name,
815 LttvTrace *trace)
816 {
817 LttvAttribute *attribute = lttv_trace_attribute(trace);
818 LttvAttributeType type;
819 LttvAttributeValue value;
820
821 g_assert(attribute =
822 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
823 module_name)));
824
825 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
826 LTTV_IN_PROGRESS,
827 &value);
828 /* The only presence of the attribute is necessary. */
829 if(type == LTTV_NONE)
830 return FALSE;
831 else
832 return TRUE;
833 }
834
835 void lttvwindowtraces_set_ready(LttvAttributeName module_name,
836 LttvTrace *trace)
837 {
838 LttvAttribute *attribute = lttv_trace_attribute(trace);
839 LttvAttributeValue value;
840
841 g_assert(attribute =
842 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
843 module_name)));
844
845 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
846 LTTV_READY,
847 LTTV_INT);
848 /* the value is left unset. The only presence of the attribute is necessary.
849 */
850 }
851
852 void lttvwindowtraces_unset_ready(LttvAttributeName module_name,
853 LttvTrace *trace)
854 {
855 LttvAttribute *attribute = lttv_trace_attribute(trace);
856
857 g_assert(attribute =
858 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
859 module_name)));
860
861 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
862 LTTV_READY);
863 }
864
865 gboolean lttvwindowtraces_get_ready(LttvAttributeName module_name,
866 LttvTrace *trace)
867 {
868 LttvAttribute *attribute = lttv_trace_attribute(trace);
869 LttvAttributeType type;
870 LttvAttributeValue value;
871
872 g_assert(attribute =
873 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
874 module_name)));
875
876 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
877 LTTV_READY,
878 &value);
879 /* The only presence of the attribute is necessary. */
880 if(type == LTTV_NONE)
881 return FALSE;
882 else
883 return TRUE;
884 }
885
886
887 /* lttvwindowtraces_process_pending_requests
888 *
889 * This internal function gets called by g_idle, taking care of the pending
890 * requests.
891 *
892 */
893
894
895 gboolean lttvwindowtraces_process_pending_requests(LttvTrace *trace)
896 {
897 LttvTracesetContext *tsc;
898 LttvTracesetStats *tss;
899 LttvTraceset *ts;
900 //LttvTracesetContextPosition *sync_position;
901 LttvAttribute *attribute;
902 LttvAttribute *g_attribute = lttv_global_attributes();
903 GSList **list_out, **list_in, **notify_in, **notify_out;
904 LttvAttributeValue value;
905 LttvAttributeType type;
906 gboolean ret_val;
907
908 if(trace == NULL)
909 return FALSE;
910
911 attribute = lttv_trace_attribute(trace);
912
913 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
914 LTTV_REQUESTS_QUEUE,
915 &value);
916 g_assert(type == LTTV_POINTER);
917 list_out = (GSList**)(value.v_pointer);
918
919 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
920 LTTV_REQUESTS_CURRENT,
921 &value);
922 g_assert(type == LTTV_POINTER);
923 list_in = (GSList**)(value.v_pointer);
924
925 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
926 LTTV_NOTIFY_QUEUE,
927 &value);
928 g_assert(type == LTTV_POINTER);
929 notify_out = (GSList**)(value.v_pointer);
930
931 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
932 LTTV_NOTIFY_CURRENT,
933 &value);
934 g_assert(type == LTTV_POINTER);
935 notify_in = (GSList**)(value.v_pointer);
936
937 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
938 LTTV_COMPUTATION_TRACESET,
939 &value);
940 g_assert(type == LTTV_POINTER);
941 ts = (LttvTraceset*)*(value.v_pointer);
942
943 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
944 LTTV_COMPUTATION_TRACESET_CONTEXT,
945 &value);
946 g_assert(type == LTTV_POINTER);
947 tsc = (LttvTracesetContext*)*(value.v_pointer);
948 tss = (LttvTracesetStats*)*(value.v_pointer);
949 g_assert(LTTV_IS_TRACESET_CONTEXT(tsc));
950 g_assert(LTTV_IS_TRACESET_STATS(tss));
951 #if 0
952 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
953 LTTV_COMPUTATION_SYNC_POSITION,
954 &value);
955 g_assert(type == LTTV_POINTER);
956 sync_position = (LttvTracesetContextPosition*)*(value.v_pointer);
957 #endif //0
958 /* There is no events requests pending : we should never have been called! */
959 g_assert(g_slist_length(*list_out) != 0 || g_slist_length(*list_in) != 0);
960 /* 0.1 Lock traces */
961 {
962 guint iter_trace=0;
963
964 for(iter_trace=0;
965 iter_trace<lttv_traceset_number(tsc->ts);
966 iter_trace++) {
967 LttvTrace *trace_v = lttv_traceset_get(tsc->ts,iter_trace);
968
969 if(lttvwindowtraces_lock(trace_v) != 0)
970 return TRUE; /* Cannot get trace lock, try later */
971
972 }
973 }
974 /* 0.2 Sync tracefiles */
975 //g_assert(lttv_process_traceset_seek_position(tsc, sync_position) == 0);
976 lttv_process_traceset_synchronize_tracefiles(tsc);
977 /* 1. Before processing */
978 {
979 /* if list_in is empty */
980 if(g_slist_length(*list_in) == 0) {
981
982 {
983 /* - Add all requests in list_out to list_in, empty list_out */
984 GSList *iter = *list_out;
985
986 while(iter != NULL) {
987 gboolean remove = FALSE;
988 gboolean free_data = FALSE;
989
990 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
991
992 remove = TRUE;
993 free_data = FALSE;
994 *list_in = g_slist_append(*list_in, bg_req);
995
996 /* Go to next */
997 if(remove)
998 {
999 GSList *remove_iter = iter;
1000
1001 iter = g_slist_next(iter);
1002 if(free_data) g_free(remove_iter->data);
1003 *list_out = g_slist_remove_link(*list_out, remove_iter);
1004 } else { // not remove
1005 iter = g_slist_next(iter);
1006 }
1007 }
1008 }
1009
1010 {
1011 GSList *iter = *list_in;
1012 /* - for each request in list_in */
1013 while(iter != NULL) {
1014
1015 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1016 /* - set hooks'in_progress flag to TRUE */
1017 lttvwindowtraces_set_in_progress(bg_req->module_name,
1018 bg_req->trace);
1019
1020 /* - call before request hook */
1021 /* Get before request hook */
1022 LttvAttribute *module_attribute;
1023
1024 g_assert(module_attribute =
1025 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1026 LTTV_IATTRIBUTE(g_attribute),
1027 LTTV_COMPUTATION)));
1028
1029 g_assert(module_attribute =
1030 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1031 LTTV_IATTRIBUTE(module_attribute),
1032 bg_req->module_name)));
1033
1034 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1035 LTTV_BEFORE_REQUEST,
1036 &value);
1037 g_assert(type == LTTV_POINTER);
1038 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1039
1040 if(before_request != NULL) lttv_hooks_call(before_request, tsc);
1041
1042 iter = g_slist_next(iter);
1043 }
1044 }
1045
1046 /* - seek trace to start */
1047 {
1048 LttTime start = { 0, 0};
1049 lttv_process_traceset_seek_time(tsc, start);
1050 }
1051
1052 /* - Move all notifications from notify_out to notify_in. */
1053 {
1054 GSList *iter = *notify_out;
1055 g_assert(g_slist_length(*notify_in) == 0);
1056
1057 while(iter != NULL) {
1058 gboolean remove = FALSE;
1059 gboolean free_data = FALSE;
1060
1061 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1062
1063 remove = TRUE;
1064 free_data = FALSE;
1065 *notify_in = g_slist_append(*notify_in, notify_req);
1066
1067 /* Go to next */
1068 if(remove)
1069 {
1070 GSList *remove_iter = iter;
1071
1072 iter = g_slist_next(iter);
1073 if(free_data)
1074 notify_request_free((BackgroundNotify*)remove_iter->data);
1075 *notify_out = g_slist_remove_link(*notify_out, remove_iter);
1076 } else { // not remove
1077 iter = g_slist_next(iter);
1078 }
1079 }
1080 }
1081 {
1082 GSList *iter = *list_in;
1083 LttvHooks *hook_adder = lttv_hooks_new();
1084 /* - for each request in list_in */
1085 while(iter != NULL) {
1086
1087 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1088 /*- add hooks to context*/
1089 lttvwindowtraces_add_computation_hooks(bg_req->module_name,
1090 tsc,
1091 hook_adder);
1092 iter = g_slist_next(iter);
1093 }
1094 lttv_hooks_call(hook_adder,tsc);
1095 lttv_hooks_destroy(hook_adder);
1096 }
1097
1098
1099 }
1100
1101 {
1102 GSList *iter = *list_in;
1103 /* - for each request in list_in */
1104 while(iter != NULL) {
1105
1106 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1107 /*- Call before chunk hooks for list_in*/
1108 lttvwindowtraces_call_before_chunk(bg_req->module_name,
1109 tsc);
1110 iter = g_slist_next(iter);
1111 }
1112 }
1113
1114 }
1115 /* 2. call process traceset middle for a chunk */
1116 {
1117 /*(assert list_in is not empty! : should not even be called in that case)*/
1118 LttTime end = ltt_time_infinite;
1119 g_assert(g_slist_length(*list_in) != 0);
1120
1121 lttv_process_traceset_middle(tsc, end, CHUNK_NUM_EVENTS, NULL);
1122 }
1123
1124 /* 3. After the chunk */
1125 {
1126 /* 3.1 call after_chunk hooks for list_in */
1127 {
1128 GSList *iter = *list_in;
1129 /* - for each request in list_in */
1130 while(iter != NULL) {
1131
1132 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1133 /* - Call after chunk hooks for list_in */
1134 lttvwindowtraces_call_after_chunk(bg_req->module_name,
1135 tsc);
1136 iter = g_slist_next(iter);
1137 }
1138 }
1139
1140 /* 3.2 for each notify_in */
1141 {
1142 GSList *iter = *notify_in;
1143 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1144
1145 while(iter != NULL) {
1146 gboolean remove = FALSE;
1147 gboolean free_data = FALSE;
1148
1149 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1150
1151 /* - if current time >= notify time, call notify and remove from
1152 * notify_in.
1153 * - if current position >= notify position, call notify and remove
1154 * from notify_in.
1155 */
1156 if( (tfc != NULL &&
1157 ltt_time_compare(notify_req->notify_time, tfc->timestamp) <= 0)
1158 ||
1159 (notify_req->notify_position != NULL &&
1160 lttv_traceset_context_ctx_pos_compare(tsc,
1161 notify_req->notify_position) >= 0)
1162 ) {
1163
1164 lttv_hooks_call(notify_req->notify, notify_req);
1165
1166 remove = TRUE;
1167 free_data = TRUE;
1168 }
1169
1170 /* Go to next */
1171 if(remove)
1172 {
1173 GSList *remove_iter = iter;
1174
1175 iter = g_slist_next(iter);
1176 if(free_data)
1177 notify_request_free((BackgroundNotify*)remove_iter->data);
1178 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1179 } else { // not remove
1180 iter = g_slist_next(iter);
1181 }
1182 }
1183 }
1184
1185 {
1186 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
1187 /* 3.3 if end of trace reached */
1188 if(tfc != NULL)
1189 g_debug("Current time : %lu sec, %lu nsec",
1190 tfc->timestamp.tv_sec, tfc->timestamp.tv_nsec);
1191 if(tfc == NULL || ltt_time_compare(tfc->timestamp,
1192 tsc->time_span.end_time) > 0) {
1193
1194 {
1195 GSList *iter = *list_in;
1196 LttvHooks *hook_remover = lttv_hooks_new();
1197 /* - for each request in list_in */
1198 while(iter != NULL) {
1199
1200 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1201 /* - remove hooks from context */
1202 lttvwindowtraces_remove_computation_hooks(bg_req->module_name,
1203 tsc,
1204 hook_remover);
1205 iter = g_slist_next(iter);
1206 }
1207 lttv_hooks_call(hook_remover,tsc);
1208 lttv_hooks_destroy(hook_remover);
1209 }
1210
1211 /* - for each request in list_in */
1212 {
1213 GSList *iter = *list_in;
1214
1215 while(iter != NULL) {
1216 gboolean remove = FALSE;
1217 gboolean free_data = FALSE;
1218
1219 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1220
1221 /* - set hooks'in_progress flag to FALSE */
1222 lttvwindowtraces_unset_in_progress(bg_req->module_name,
1223 bg_req->trace);
1224 /* - set hooks'ready flag to TRUE */
1225 lttvwindowtraces_set_ready(bg_req->module_name,
1226 bg_req->trace);
1227 /* - call after request hook */
1228 /* Get after request hook */
1229 LttvAttribute *module_attribute;
1230
1231 g_assert(module_attribute =
1232 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1233 LTTV_IATTRIBUTE(g_attribute),
1234 LTTV_COMPUTATION)));
1235
1236 g_assert(module_attribute =
1237 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(
1238 LTTV_IATTRIBUTE(module_attribute),
1239 bg_req->module_name)));
1240
1241 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(module_attribute),
1242 LTTV_AFTER_REQUEST,
1243 &value);
1244 g_assert(type == LTTV_POINTER);
1245 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1246
1247 if(after_request != NULL) lttv_hooks_call(after_request, tsc);
1248 /* - remove request */
1249 remove = TRUE;
1250 free_data = TRUE;
1251
1252 /* Go to next */
1253 if(remove)
1254 {
1255 GSList *remove_iter = iter;
1256
1257 iter = g_slist_next(iter);
1258 if(free_data) g_free(remove_iter->data);
1259 *list_in = g_slist_remove_link(*list_in, remove_iter);
1260 } else { // not remove
1261 iter = g_slist_next(iter);
1262 }
1263 }
1264 }
1265
1266 /* - for each notifications in notify_in */
1267 {
1268 GSList *iter = *notify_in;
1269
1270 while(iter != NULL) {
1271 gboolean remove = FALSE;
1272 gboolean free_data = FALSE;
1273
1274 BackgroundNotify *notify_req = (BackgroundNotify*)iter->data;
1275
1276 /* - call notify and remove from notify_in */
1277 lttv_hooks_call(notify_req->notify, notify_req);
1278 remove = TRUE;
1279 free_data = TRUE;
1280
1281 /* Go to next */
1282 if(remove)
1283 {
1284 GSList *remove_iter = iter;
1285
1286 iter = g_slist_next(iter);
1287 if(free_data)
1288 notify_request_free((BackgroundNotify*)remove_iter->data);
1289 *notify_in = g_slist_remove_link(*notify_in, remove_iter);
1290 } else { // not remove
1291 iter = g_slist_next(iter);
1292 }
1293 }
1294 }
1295 {
1296 /* - reset the context */
1297 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->fini(tsc);
1298 LTTV_TRACESET_CONTEXT_GET_CLASS(tsc)->init(tsc,ts);
1299 }
1300 /* - if list_out is empty */
1301 if(g_slist_length(*list_out) == 0) {
1302 /* - return FALSE (scheduler stopped) */
1303 g_debug("Background computation scheduler stopped");
1304 g_info("Background computation finished for trace %p", trace);
1305 /* FIXME : remove status bar info, need context id and message id */
1306 ret_val = FALSE;
1307 } else {
1308 ret_val = TRUE;
1309 }
1310 } else {
1311 /* 3.4 else, end of trace not reached */
1312 /* - return TRUE (scheduler still registered) */
1313 g_debug("Background computation left");
1314 ret_val = TRUE;
1315 }
1316 }
1317 }
1318 /* 4. Unlock traces */
1319 {
1320 lttv_process_traceset_get_sync_data(tsc);
1321 //lttv_traceset_context_position_save(tsc, sync_position);
1322 guint iter_trace;
1323
1324 for(iter_trace=0;
1325 iter_trace<lttv_traceset_number(tsc->ts);
1326 iter_trace++) {
1327 LttvTrace *trace_v = lttv_traceset_get(tsc->ts, iter_trace);
1328
1329 lttvwindowtraces_unlock(trace_v);
1330 }
1331 }
1332 return ret_val;
1333 }
1334
1335
1336
1337 /**
1338 * Register the background computation hooks for a specific module. It adds the
1339 * computation hooks to the global attrubutes, under "computation/module name".
1340 *
1341 * @param module_name A GQuark : the name of the module which computes the
1342 * information.
1343 */
1344 void lttvwindowtraces_register_computation_hooks(LttvAttributeName module_name,
1345 LttvHooks *before_chunk_traceset,
1346 LttvHooks *before_chunk_trace,
1347 LttvHooks *before_chunk_tracefile,
1348 LttvHooks *after_chunk_traceset,
1349 LttvHooks *after_chunk_trace,
1350 LttvHooks *after_chunk_tracefile,
1351 LttvHooks *before_request,
1352 LttvHooks *after_request,
1353 LttvHooks *event_hook,
1354 LttvHooksById *event_hook_by_id,
1355 LttvHooks *hook_adder,
1356 LttvHooks *hook_remover)
1357 {
1358 LttvAttribute *g_attribute = lttv_global_attributes();
1359 LttvAttribute *attribute;
1360 LttvAttributeValue value;
1361
1362 g_assert(attribute =
1363 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1364 LTTV_COMPUTATION)));
1365
1366 g_assert(attribute =
1367 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1368 module_name)));
1369
1370 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1371 LTTV_BEFORE_CHUNK_TRACESET,
1372 LTTV_POINTER,
1373 &value));
1374 *(value.v_pointer) = before_chunk_traceset;
1375
1376 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1377 LTTV_BEFORE_CHUNK_TRACE,
1378 LTTV_POINTER,
1379 &value));
1380 *(value.v_pointer) = before_chunk_trace;
1381
1382 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1383 LTTV_BEFORE_CHUNK_TRACEFILE,
1384 LTTV_POINTER,
1385 &value));
1386 *(value.v_pointer) = before_chunk_tracefile;
1387
1388 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1389 LTTV_AFTER_CHUNK_TRACESET,
1390 LTTV_POINTER,
1391 &value));
1392 *(value.v_pointer) = after_chunk_traceset;
1393
1394 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1395 LTTV_AFTER_CHUNK_TRACE,
1396 LTTV_POINTER,
1397 &value));
1398 *(value.v_pointer) = after_chunk_trace;
1399
1400 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1401 LTTV_AFTER_CHUNK_TRACEFILE,
1402 LTTV_POINTER,
1403 &value));
1404 *(value.v_pointer) = after_chunk_tracefile;
1405
1406 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1407 LTTV_BEFORE_REQUEST,
1408 LTTV_POINTER,
1409 &value));
1410 *(value.v_pointer) = before_request;
1411
1412 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1413 LTTV_AFTER_REQUEST,
1414 LTTV_POINTER,
1415 &value));
1416 *(value.v_pointer) = after_request;
1417
1418 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1419 LTTV_EVENT_HOOK,
1420 LTTV_POINTER,
1421 &value));
1422 *(value.v_pointer) = event_hook;
1423
1424 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1425 LTTV_EVENT_HOOK_BY_ID,
1426 LTTV_POINTER,
1427 &value));
1428 *(value.v_pointer) = event_hook_by_id;
1429
1430 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1431 LTTV_HOOK_ADDER,
1432 LTTV_POINTER,
1433 &value));
1434 *(value.v_pointer) = hook_adder;
1435
1436 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1437 LTTV_HOOK_REMOVER,
1438 LTTV_POINTER,
1439 &value));
1440 *(value.v_pointer) = hook_remover;
1441
1442 }
1443
1444
1445 /**
1446 * It removes all the requests than can be currently processed by the
1447 * background computation algorithm for all the traces (list_in and list_out).
1448 *
1449 * Leaves the flag to in_progress or none.. depending if current or queue
1450 *
1451 * @param module_name A GQuark : the name of the module which computes the
1452 * information.
1453 */
1454 void lttvwindowtraces_unregister_requests(LttvAttributeName module_name)
1455 {
1456 guint i;
1457
1458 for(i=0;i<lttvwindowtraces_get_number();i++) {
1459 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
1460 g_assert(trace_v != NULL);
1461 LttTrace *trace;
1462 LttvAttribute *attribute = lttv_trace_attribute(trace_v);
1463 LttvAttributeValue value;
1464 GSList **queue, **current;
1465 GSList *iter;
1466
1467 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1468 LTTV_REQUESTS_QUEUE,
1469 LTTV_POINTER,
1470 &value));
1471 queue = (GSList**)(value.v_pointer);
1472
1473 iter = *queue;
1474 while(iter != NULL) {
1475 gboolean remove = FALSE;
1476 gboolean free_data = FALSE;
1477
1478 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1479
1480 if(bg_req->module_name == module_name) {
1481 remove = TRUE;
1482 free_data = TRUE;
1483 }
1484
1485 /* Go to next */
1486 if(remove)
1487 {
1488 GSList *remove_iter = iter;
1489
1490 iter = g_slist_next(iter);
1491 if(free_data) g_free(remove_iter->data);
1492 *queue = g_slist_remove_link(*queue, remove_iter);
1493 } else { // not remove
1494 iter = g_slist_next(iter);
1495 }
1496 }
1497
1498
1499 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1500 LTTV_REQUESTS_CURRENT,
1501 LTTV_POINTER,
1502 &value));
1503 current = (GSList**)(value.v_pointer);
1504
1505 iter = *current;
1506 while(iter != NULL) {
1507 gboolean remove = FALSE;
1508 gboolean free_data = FALSE;
1509
1510 BackgroundRequest *bg_req = (BackgroundRequest*)iter->data;
1511
1512 if(bg_req->module_name == module_name) {
1513 remove = TRUE;
1514 free_data = TRUE;
1515 }
1516
1517 /* Go to next */
1518 if(remove)
1519 {
1520 GSList *remove_iter = iter;
1521
1522 iter = g_slist_next(iter);
1523 if(free_data) g_free(remove_iter->data);
1524 *current = g_slist_remove_link(*current, remove_iter);
1525 } else { // not remove
1526 iter = g_slist_next(iter);
1527 }
1528 }
1529 }
1530 }
1531
1532
1533 /**
1534 * Unregister the background computation hooks for a specific module.
1535 *
1536 * It also removes all the requests than can be currently processed by the
1537 * background computation algorithm for all the traces (list_in and list_out).
1538 *
1539 * @param module_name A GQuark : the name of the module which computes the
1540 * information.
1541 */
1542
1543 void lttvwindowtraces_unregister_computation_hooks
1544 (LttvAttributeName module_name)
1545 {
1546 LttvAttribute *g_attribute = lttv_global_attributes();
1547 LttvAttribute *attribute;
1548 LttvAttributeValue value;
1549
1550 g_assert(attribute =
1551 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1552 LTTV_COMPUTATION)));
1553 g_assert(attribute =
1554 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(attribute),
1555 module_name)));
1556
1557
1558 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1559 LTTV_BEFORE_CHUNK_TRACESET,
1560 LTTV_POINTER,
1561 &value));
1562 LttvHooks *before_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1563 if(before_chunk_traceset != NULL)
1564 lttv_hooks_destroy(before_chunk_traceset);
1565
1566 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1567 LTTV_BEFORE_CHUNK_TRACE,
1568 LTTV_POINTER,
1569 &value));
1570 LttvHooks *before_chunk_trace = (LttvHooks*)*(value.v_pointer);
1571 if(before_chunk_trace != NULL)
1572 lttv_hooks_destroy(before_chunk_trace);
1573
1574 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1575 LTTV_BEFORE_CHUNK_TRACEFILE,
1576 LTTV_POINTER,
1577 &value));
1578 LttvHooks *before_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1579 if(before_chunk_tracefile != NULL)
1580 lttv_hooks_destroy(before_chunk_tracefile);
1581
1582 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1583 LTTV_AFTER_CHUNK_TRACESET,
1584 LTTV_POINTER,
1585 &value));
1586 LttvHooks *after_chunk_traceset = (LttvHooks*)*(value.v_pointer);
1587 if(after_chunk_traceset != NULL)
1588 lttv_hooks_destroy(after_chunk_traceset);
1589
1590 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1591 LTTV_AFTER_CHUNK_TRACE,
1592 LTTV_POINTER,
1593 &value));
1594 LttvHooks *after_chunk_trace = (LttvHooks*)*(value.v_pointer);
1595 if(after_chunk_trace != NULL)
1596 lttv_hooks_destroy(after_chunk_trace);
1597
1598 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1599 LTTV_AFTER_CHUNK_TRACEFILE,
1600 LTTV_POINTER,
1601 &value));
1602 LttvHooks *after_chunk_tracefile = (LttvHooks*)*(value.v_pointer);
1603 if(after_chunk_tracefile != NULL)
1604 lttv_hooks_destroy(after_chunk_tracefile);
1605
1606 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1607 LTTV_BEFORE_REQUEST,
1608 LTTV_POINTER,
1609 &value));
1610 LttvHooks *before_request = (LttvHooks*)*(value.v_pointer);
1611 if(before_request != NULL)
1612 lttv_hooks_destroy(before_request);
1613
1614 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1615 LTTV_AFTER_REQUEST,
1616 LTTV_POINTER,
1617 &value));
1618 LttvHooks *after_request = (LttvHooks*)*(value.v_pointer);
1619 if(after_request != NULL)
1620 lttv_hooks_destroy(after_request);
1621
1622 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1623 LTTV_EVENT_HOOK,
1624 LTTV_POINTER,
1625 &value));
1626 LttvHooks *event_hook = (LttvHooks*)*(value.v_pointer);
1627 if(event_hook != NULL)
1628 lttv_hooks_destroy(event_hook);
1629
1630 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1631 LTTV_EVENT_HOOK_BY_ID,
1632 LTTV_POINTER,
1633 &value));
1634 LttvHooksById *event_hook_by_id = (LttvHooksById*)*(value.v_pointer);
1635 if(event_hook_by_id != NULL)
1636 lttv_hooks_by_id_destroy(event_hook_by_id);
1637
1638 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1639 LTTV_HOOK_ADDER,
1640 LTTV_POINTER,
1641 &value));
1642 LttvHooks *hook_adder = (LttvHooks*)*(value.v_pointer);
1643 if(hook_adder != NULL)
1644 lttv_hooks_destroy(hook_adder);
1645
1646 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
1647 LTTV_HOOK_REMOVER,
1648 LTTV_POINTER,
1649 &value));
1650 LttvHooks *hook_remover = (LttvHooks*)*(value.v_pointer);
1651 if(hook_remover != NULL)
1652 lttv_hooks_destroy(hook_remover);
1653
1654
1655 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1656 LTTV_EVENT_HOOK_BY_ID);
1657 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1658 LTTV_EVENT_HOOK);
1659
1660 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1661 LTTV_AFTER_REQUEST);
1662 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1663 LTTV_BEFORE_REQUEST);
1664
1665 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1666 LTTV_AFTER_CHUNK_TRACEFILE);
1667 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1668 LTTV_AFTER_CHUNK_TRACE);
1669 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1670 LTTV_AFTER_CHUNK_TRACESET);
1671
1672 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1673 LTTV_BEFORE_CHUNK_TRACEFILE);
1674 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1675 LTTV_BEFORE_CHUNK_TRACE);
1676 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1677 LTTV_BEFORE_CHUNK_TRACESET);
1678 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1679 LTTV_HOOK_ADDER);
1680 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1681 LTTV_HOOK_REMOVER);
1682
1683 /* finally, remove module name */
1684 g_assert(attribute =
1685 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
1686 LTTV_COMPUTATION)));
1687 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1688 module_name);
1689
1690 }
1691
1692 /**
1693 * Lock a trace so no other instance can use it.
1694 *
1695 * @param trace The trace to lock.
1696 * @return 0 on success, -1 if cannot get lock.
1697 */
1698 gint lttvwindowtraces_lock(LttvTrace *trace)
1699 {
1700 LttvAttribute *attribute = lttv_trace_attribute(trace);
1701 LttvAttributeValue value;
1702 LttvAttributeType type;
1703
1704 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1705 LTTV_LOCK,
1706 &value);
1707 /* Verify the absence of the lock. */
1708 if(type != LTTV_NONE) {
1709 g_critical("Cannot take trace lock");
1710 return -1;
1711 }
1712
1713 value = lttv_iattribute_add(LTTV_IATTRIBUTE(attribute),
1714 LTTV_LOCK,
1715 LTTV_INT);
1716 /* the value is left unset. The only presence of the attribute is necessary.
1717 */
1718
1719 return 0;
1720 }
1721
1722 /**
1723 * Unlock a trace.
1724 *
1725 * @param trace The trace to unlock.
1726 * @return 0 on success, -1 if cannot unlock (not locked ?).
1727 */
1728 gint lttvwindowtraces_unlock(LttvTrace *trace)
1729 {
1730 LttvAttribute *attribute = lttv_trace_attribute(trace);
1731 LttvAttributeType type;
1732 LttvAttributeValue value;
1733
1734 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1735 LTTV_LOCK,
1736 &value);
1737 /* Verify the presence of the lock. */
1738 if(type == LTTV_NONE) {
1739 g_critical("Cannot release trace lock");
1740 return -1;
1741 }
1742
1743 lttv_iattribute_remove_by_name(LTTV_IATTRIBUTE(attribute),
1744 LTTV_LOCK);
1745
1746 return 0;
1747 }
1748
1749 /**
1750 * Verify if a trace is locked.
1751 *
1752 * @param trace The trace to verify.
1753 * @return TRUE if locked, FALSE is unlocked.
1754 */
1755 gint lttvwindowtraces_get_lock_state(LttvTrace *trace)
1756 {
1757 LttvAttribute *attribute = lttv_trace_attribute(trace);
1758 LttvAttributeType type;
1759 LttvAttributeValue value;
1760
1761 type = lttv_iattribute_get_by_name(LTTV_IATTRIBUTE(attribute),
1762 LTTV_LOCK,
1763 &value);
1764 /* The only presence of the attribute is necessary. */
1765 if(type == LTTV_NONE)
1766 return FALSE;
1767 else
1768 return TRUE;
1769 }
1770
This page took 0.070223 seconds and 4 git commands to generate.