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