uninitialized variables checked. Also change two if/else if functions for switch
[lttv.git] / ltt / branches / poly / lttv / lttv / tracecontext.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
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
20 #include <lttv/tracecontext.h>
21 #include <ltt/event.h>
22 #include <ltt/facility.h>
23 #include <ltt/trace.h>
24 #include <ltt/type.h>
25
26
27
28
29 gint compare_tracefile(gconstpointer a, gconstpointer b)
30 {
31 gint comparison;
32
33 LttvTracefileContext *trace_a = (LttvTracefileContext *)a;
34
35 LttvTracefileContext *trace_b = (LttvTracefileContext *)b;
36
37 if(trace_a == trace_b) return 0;
38 comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp);
39 if(comparison != 0) return comparison;
40 if(trace_a->index < trace_b->index) return -1;
41 else if(trace_a->index > trace_b->index) return 1;
42 if(trace_a->t_context->index < trace_b->t_context->index) return -1;
43 else if(trace_a->t_context->index > trace_b->t_context->index) return 1;
44 g_assert(FALSE);
45 }
46
47 struct _LttvTraceContextPosition {
48 LttEventPosition **tf_pos; /* Position in each tracefile */
49 guint nb_tracefile; /* Number of tracefiles (check) */
50 };
51
52 struct _LttvTracesetContextPosition {
53 LttvTraceContextPosition *t_pos; /* Position in each trace */
54 guint nb_trace; /* Number of traces (check) */
55 LttTime timestamp; /* Current time at the saved position */
56 };
57
58 void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
59 {
60 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
61 }
62
63
64 void lttv_context_fini(LttvTracesetContext *self)
65 {
66 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
67 }
68
69
70 LttvTracesetContext *
71 lttv_context_new_traceset_context(LttvTracesetContext *self)
72 {
73 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
74 }
75
76
77
78
79 LttvTraceContext *
80 lttv_context_new_trace_context(LttvTracesetContext *self)
81 {
82 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
83 }
84
85
86 LttvTracefileContext *
87 lttv_context_new_tracefile_context(LttvTracesetContext *self)
88 {
89 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
90 }
91
92 /****************************************************************************
93 * lttv_traceset_context_compute_time_span
94 *
95 * Keep the time span is sync with on the fly addition and removal of traces
96 * in a trace set. It must be called each time a trace is added/removed from
97 * the traceset. It could be more efficient to call it only once a bunch
98 * of traces are loaded, but the calculation is not long, so it's not
99 * critical.
100 *
101 * Author : Xang Xiu Yang
102 ***************************************************************************/
103 static void lttv_traceset_context_compute_time_span(
104 LttvTracesetContext *self,
105 TimeInterval *time_span)
106 {
107 LttvTraceset * traceset = self->ts;
108 int numTraces = lttv_traceset_number(traceset);
109 int i;
110 LttTime s, e;
111 LttvTraceContext *tc;
112 LttTrace * trace;
113
114 time_span->start_time.tv_sec = 0;
115 time_span->start_time.tv_nsec = 0;
116 time_span->end_time.tv_sec = 0;
117 time_span->end_time.tv_nsec = 0;
118
119 for(i=0; i<numTraces;i++){
120 tc = self->traces[i];
121 trace = tc->t;
122
123 ltt_trace_time_span_get(trace, &s, &e);
124
125 if(i==0){
126 time_span->start_time = s;
127 time_span->end_time = e;
128 }else{
129 if(s.tv_sec < time_span->start_time.tv_sec
130 || (s.tv_sec == time_span->start_time.tv_sec
131 && s.tv_nsec < time_span->start_time.tv_nsec))
132 time_span->start_time = s;
133 if(e.tv_sec > time_span->end_time.tv_sec
134 || (e.tv_sec == time_span->end_time.tv_sec
135 && e.tv_nsec > time_span->end_time.tv_nsec))
136 time_span->end_time = e;
137 }
138 }
139 }
140
141
142 static void
143 init(LttvTracesetContext *self, LttvTraceset *ts)
144 {
145 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
146
147 LttvTraceContext *tc;
148
149 LttvTracefileContext *tfc;
150
151 LttTime null_time = {0, 0};
152
153 nb_trace = lttv_traceset_number(ts);
154 self->ts = ts;
155 self->traces = g_new(LttvTraceContext *, nb_trace);
156 self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
157 self->ts_a = lttv_traceset_attribute(ts);
158 for(i = 0 ; i < nb_trace ; i++) {
159 tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
160 self->traces[i] = tc;
161
162 tc->ts_context = self;
163 tc->index = i;
164 tc->vt = lttv_traceset_get(ts, i);
165 tc->t = lttv_trace(tc->vt);
166 tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
167 tc->t_a = lttv_trace_attribute(tc->vt);
168 nb_control = ltt_trace_control_tracefile_number(tc->t);
169 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
170 nb_tracefile = nb_control + nb_per_cpu;
171 tc->tracefiles = g_new(LttvTracefileContext *, nb_tracefile);
172
173 for(j = 0 ; j < nb_tracefile ; j++) {
174 tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
175 tc->tracefiles[j] = tfc;
176 tfc->index = j;
177
178 if(j < nb_control) {
179 tfc->control = TRUE;
180 tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
181 }
182 else {
183 tfc->control = FALSE;
184 tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
185 }
186 tfc->t_context = tc;
187 tfc->e = ltt_event_new();
188 tfc->event = lttv_hooks_new();
189 tfc->event_by_id = lttv_hooks_by_id_new();
190 tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
191 }
192 }
193 self->pqueue = g_tree_new(compare_tracefile);
194 lttv_process_traceset_seek_time(self, null_time);
195 lttv_traceset_context_compute_time_span(self, &self->time_span);
196
197 }
198
199
200 void fini(LttvTracesetContext *self)
201 {
202 guint i, j, nb_trace, nb_tracefile;
203
204 LttvTraceContext *tc;
205
206 LttvTracefileContext *tfc;
207
208 LttvTraceset *ts = self->ts;
209
210 //FIXME : segfault
211
212 g_tree_destroy(self->pqueue);
213 g_object_unref(self->a);
214
215 nb_trace = lttv_traceset_number(ts);
216
217 for(i = 0 ; i < nb_trace ; i++) {
218 tc = self->traces[i];
219
220 g_object_unref(tc->a);
221
222 nb_tracefile = ltt_trace_control_tracefile_number(tc->t) +
223 ltt_trace_per_cpu_tracefile_number(tc->t);
224
225 for(j = 0 ; j < nb_tracefile ; j++) {
226 tfc = tc->tracefiles[j];
227 ltt_event_destroy(tfc->e);
228 lttv_hooks_destroy(tfc->event);
229 lttv_hooks_by_id_destroy(tfc->event_by_id);
230 g_object_unref(tfc->a);
231 g_object_unref(tfc);
232 }
233 g_free(tc->tracefiles);
234 g_object_unref(tc);
235 }
236 g_free(self->traces);
237 }
238
239
240 void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
241 LttvHooks *before_traceset,
242 LttvHooks *before_trace,
243 LttvHooks *before_tracefile,
244 LttvHooks *event,
245 LttvHooksById *event_by_id)
246 {
247 LttvTraceset *ts = self->ts;
248
249 guint i, nb_trace;
250
251 LttvTraceContext *tc;
252
253 lttv_hooks_call(before_traceset, self);
254
255 nb_trace = lttv_traceset_number(ts);
256
257 for(i = 0 ; i < nb_trace ; i++) {
258 tc = self->traces[i];
259 lttv_trace_context_add_hooks(tc,
260 before_trace,
261 before_tracefile,
262 event,
263 event_by_id);
264 }
265 }
266
267
268 void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
269 LttvHooks *after_traceset,
270 LttvHooks *after_trace,
271 LttvHooks *after_tracefile,
272 LttvHooks *event,
273 LttvHooksById *event_by_id)
274 {
275
276 LttvTraceset *ts = self->ts;
277
278 guint i, nb_trace;
279
280 LttvTraceContext *tc;
281
282 nb_trace = lttv_traceset_number(ts);
283
284 for(i = 0 ; i < nb_trace ; i++) {
285 tc = self->traces[i];
286 lttv_trace_context_remove_hooks(tc,
287 after_trace,
288 after_tracefile,
289 event,
290 event_by_id);
291 }
292
293 lttv_hooks_call(after_traceset, self);
294
295
296 }
297
298 void lttv_trace_context_add_hooks(LttvTraceContext *self,
299 LttvHooks *before_trace,
300 LttvHooks *before_tracefile,
301 LttvHooks *event,
302 LttvHooksById *event_by_id)
303 {
304 guint i, nb_tracefile;
305
306 LttvTracefileContext *tfc;
307
308 lttv_hooks_call(before_trace, self);
309 nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
310 ltt_trace_per_cpu_tracefile_number(self->t);
311
312 for(i = 0 ; i < nb_tracefile ; i++) {
313 tfc = self->tracefiles[i];
314 lttv_tracefile_context_add_hooks(tfc,
315 before_tracefile,
316 event,
317 event_by_id);
318 }
319 }
320
321
322
323 void lttv_trace_context_remove_hooks(LttvTraceContext *self,
324 LttvHooks *after_trace,
325 LttvHooks *after_tracefile,
326 LttvHooks *event,
327 LttvHooksById *event_by_id)
328 {
329 guint i, nb_tracefile;
330
331 LttvTracefileContext *tfc;
332
333 nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
334 ltt_trace_per_cpu_tracefile_number(self->t);
335
336 for(i = 0 ; i < nb_tracefile ; i++) {
337 tfc = self->tracefiles[i];
338 lttv_tracefile_context_remove_hooks(tfc,
339 after_tracefile,
340 event,
341 event_by_id);
342 }
343
344 lttv_hooks_call(after_trace, self);
345 }
346
347 void lttv_tracefile_context_add_hooks(LttvTracefileContext *self,
348 LttvHooks *before_tracefile,
349 LttvHooks *event,
350 LttvHooksById *event_by_id)
351 {
352 guint i;
353
354 LttvHooks *hook;
355
356 lttv_hooks_call(before_tracefile, self);
357 lttv_hooks_add_list(self->event, event);
358 if(event_by_id != NULL)
359 for(i = 0; i < lttv_hooks_by_id_max_id(event_by_id); i++) {
360 hook = lttv_hooks_by_id_get(self->event_by_id, i);
361 if(hook != NULL)
362 lttv_hooks_remove_list(hook, lttv_hooks_by_id_get(event_by_id, i));
363 }
364
365 }
366
367 void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self,
368 LttvHooks *after_tracefile,
369 LttvHooks *event,
370 LttvHooksById *event_by_id)
371 {
372 guint i;
373
374 LttvHooks *hook;
375
376
377 lttv_hooks_remove_list(self->event, event);
378 if(event_by_id != NULL)
379 for(i = 0; i < lttv_hooks_by_id_max_id(event_by_id); i++) {
380 hook = lttv_hooks_by_id_find(self->event_by_id, i);
381 lttv_hooks_add_list(hook, lttv_hooks_by_id_get(event_by_id, i));
382 }
383
384 lttv_hooks_call(after_tracefile, self);
385 }
386
387
388
389 void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
390 unsigned i,
391 LttvHooks *event_by_id)
392 {
393 LttvHooks * h;
394 h = lttv_hooks_by_id_find(tfc->event_by_id, i);
395 lttv_hooks_add_list(h, event_by_id);
396 }
397
398 void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
399 unsigned i)
400 {
401 lttv_hooks_by_id_remove(tfc->event_by_id, i);
402 }
403
404 static LttvTracesetContext *
405 new_traceset_context(LttvTracesetContext *self)
406 {
407 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
408 }
409
410
411 static LttvTraceContext *
412 new_trace_context(LttvTracesetContext *self)
413 {
414 return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
415 }
416
417
418 static LttvTracefileContext *
419 new_tracefile_context(LttvTracesetContext *self)
420 {
421 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
422 }
423
424
425 static void
426 traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
427 {
428 /* Be careful of anything which would not work well with shallow copies */
429 }
430
431
432 static void
433 traceset_context_finalize (LttvTracesetContext *self)
434 {
435 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
436 ->finalize(G_OBJECT(self));
437 }
438
439
440 static void
441 traceset_context_class_init (LttvTracesetContextClass *klass)
442 {
443 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
444
445 gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
446 klass->init = init;
447 klass->fini = fini;
448 klass->new_traceset_context = new_traceset_context;
449 klass->new_trace_context = new_trace_context;
450 klass->new_tracefile_context = new_tracefile_context;
451 }
452
453
454 GType
455 lttv_traceset_context_get_type(void)
456 {
457 static GType type = 0;
458 if (type == 0) {
459 static const GTypeInfo info = {
460 sizeof (LttvTracesetContextClass),
461 NULL, /* base_init */
462 NULL, /* base_finalize */
463 (GClassInitFunc) traceset_context_class_init, /* class_init */
464 NULL, /* class_finalize */
465 NULL, /* class_data */
466 sizeof (LttvTracesetContext),
467 0, /* n_preallocs */
468 (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
469 };
470
471 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType",
472 &info, 0);
473 }
474 return type;
475 }
476
477
478 static void
479 trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
480 {
481 /* Be careful of anything which would not work well with shallow copies */
482 }
483
484
485 static void
486 trace_context_finalize (LttvTraceContext *self)
487 {
488 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
489 finalize(G_OBJECT(self));
490 }
491
492
493 static void
494 trace_context_class_init (LttvTraceContextClass *klass)
495 {
496 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
497
498 gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
499 }
500
501
502 GType
503 lttv_trace_context_get_type(void)
504 {
505 static GType type = 0;
506 if (type == 0) {
507 static const GTypeInfo info = {
508 sizeof (LttvTraceContextClass),
509 NULL, /* base_init */
510 NULL, /* base_finalize */
511 (GClassInitFunc) trace_context_class_init, /* class_init */
512 NULL, /* class_finalize */
513 NULL, /* class_data */
514 sizeof (LttvTraceContext),
515 0, /* n_preallocs */
516 (GInstanceInitFunc) trace_context_instance_init /* instance_init */
517 };
518
519 type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType",
520 &info, 0);
521 }
522 return type;
523 }
524
525
526 static void
527 tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
528 {
529 /* Be careful of anything which would not work well with shallow copies */
530 }
531
532
533 static void
534 tracefile_context_finalize (LttvTracefileContext *self)
535 {
536 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
537 ->finalize(G_OBJECT(self));
538 }
539
540
541 static void
542 tracefile_context_class_init (LttvTracefileContextClass *klass)
543 {
544 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
545
546 gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
547 }
548
549
550 GType
551 lttv_tracefile_context_get_type(void)
552 {
553 static GType type = 0;
554 if (type == 0) {
555 static const GTypeInfo info = {
556 sizeof (LttvTracefileContextClass),
557 NULL, /* base_init */
558 NULL, /* base_finalize */
559 (GClassInitFunc) tracefile_context_class_init, /* class_init */
560 NULL, /* class_finalize */
561 NULL, /* class_data */
562 sizeof (LttvTracefileContext),
563 0, /* n_preallocs */
564 (GInstanceInitFunc) tracefile_context_instance_init /* instance_init */
565 };
566
567 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType",
568 &info, 0);
569 }
570 return type;
571 }
572
573
574
575 gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
576 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
577 return TRUE;
578 }
579
580
581 /* Put all the tracefiles at the tracefile context position */
582 void lttv_process_traceset_synchronize_tracefiles(LttvTracesetContext *self)
583 {
584 guint iter_trace, nb_trace;
585
586 LttvTraceContext *tc;
587
588 nb_trace = lttv_traceset_number(self->ts);
589
590 for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
591 tc = self->traces[iter_trace];
592 {
593 /* each trace */
594 guint iter_tf, nb_tracefile;
595
596 LttvTracefileContext *tfc;
597
598 nb_tracefile = ltt_trace_control_tracefile_number(tc->t) +
599 ltt_trace_per_cpu_tracefile_number(tc->t);
600
601 for(iter_tf = 0 ; iter_tf < nb_tracefile ; iter_tf++) {
602 tfc = tc->tracefiles[iter_tf];
603 {
604 /* each tracefile */
605 //ltt_tracefile_copy(tfc->tf_sync_data, tfc->tf);
606 LttEventPosition *ep = ltt_event_position_new();
607
608 ltt_event_position(tfc->e, ep);
609
610 ltt_tracefile_seek_position(tfc->tf, ep);
611 g_free(ep);
612 }
613 }
614 }
615 }
616 }
617
618
619
620 void lttv_process_traceset_begin(LttvTracesetContext *self,
621 LttvHooks *before_traceset,
622 LttvHooks *before_trace,
623 LttvHooks *before_tracefile,
624 LttvHooks *event,
625 LttvHooksById *event_by_id)
626 {
627
628 /* simply add hooks in context. _before hooks are called by add_hooks. */
629 /* It calls all before_traceset, before_trace, and before_tracefile hooks. */
630 lttv_traceset_context_add_hooks(self,
631 before_traceset,
632 before_trace,
633 before_tracefile,
634 event,
635 event_by_id);
636
637 }
638
639 /* Note : a _middle must be preceded from a _seek or another middle */
640 guint lttv_process_traceset_middle(LttvTracesetContext *self,
641 LttTime end,
642 guint nb_events,
643 const LttvTracesetContextPosition *end_position)
644 {
645 GTree *pqueue = self->pqueue;
646
647 guint id;
648
649 LttvTracefileContext *tfc;
650
651 unsigned count = 0;
652
653 gboolean last_ret = FALSE; /* return value of the last hook list called */
654
655 /* Get the next event from the pqueue, call its hooks,
656 reinsert in the pqueue the following event from the same tracefile
657 unless the tracefile is finished or the event is later than the
658 end time. */
659
660 while(TRUE) {
661 tfc = NULL;
662 g_tree_foreach(pqueue, get_first, &tfc);
663 /* End of traceset : tfc is NULL */
664 if(tfc == NULL)
665 {
666 return count;
667 }
668
669 /* Have we reached :
670 * - the maximum number of events specified?
671 * - the end position ?
672 * - the end time ?
673 * then the read is finished. We leave the queue in the same state and
674 * break the loop.
675 */
676
677 if(last_ret == TRUE ||
678 count >= nb_events ||
679 (end_position!=NULL&&lttv_traceset_context_ctx_pos_compare(self,
680 end_position) == 0)||
681 ltt_time_compare(tfc->timestamp, end) >= 0)
682 {
683 return count;
684 }
685
686 /* Get the tracefile with an event for the smallest time found. If two
687 or more tracefiles have events for the same time, hope that lookup
688 and remove are consistent. */
689
690 g_tree_remove(pqueue, tfc);
691 count++;
692
693 id = ltt_event_eventtype_id(tfc->e);
694 last_ret = lttv_hooks_call_merge(tfc->event, tfc,
695 lttv_hooks_by_id_get(tfc->event_by_id, id), tfc);
696
697 if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) {
698 tfc->timestamp = ltt_event_time(tfc->e);
699 g_tree_insert(pqueue, tfc, tfc);
700 }
701 }
702 }
703
704
705 void lttv_process_traceset_end(LttvTracesetContext *self,
706 LttvHooks *after_traceset,
707 LttvHooks *after_trace,
708 LttvHooks *after_tracefile,
709 LttvHooks *event,
710 LttvHooksById *event_by_id)
711 {
712 /* Remove hooks from context. _after hooks are called by remove_hooks. */
713 /* It calls all after_traceset, after_trace, and after_tracefile hooks. */
714 lttv_traceset_context_remove_hooks(self,
715 after_traceset,
716 after_trace,
717 after_tracefile,
718 event,
719 event_by_id);
720 }
721
722 void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
723 {
724 guint i, nb_tracefile;
725
726 LttvTracefileContext *tfc;
727
728 GTree *pqueue = self->ts_context->pqueue;
729
730 nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
731 ltt_trace_per_cpu_tracefile_number(self->t);
732
733 for(i = 0 ; i < nb_tracefile ; i++) {
734 tfc = self->tracefiles[i];
735 ltt_tracefile_seek_time(tfc->tf, start);
736 g_tree_remove(pqueue, tfc);
737 if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) {
738 tfc->timestamp = ltt_event_time(tfc->e);
739 g_tree_insert(pqueue, tfc, tfc);
740 }
741 }
742 }
743
744
745 void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
746 {
747 guint i, nb_trace;
748
749 LttvTraceContext *tc;
750
751 LttvTracefileContext *tfc;
752
753 nb_trace = lttv_traceset_number(self->ts);
754 for(i = 0 ; i < nb_trace ; i++) {
755 tc = self->traces[i];
756 lttv_process_trace_seek_time(tc, start);
757 }
758 }
759
760
761 gboolean lttv_process_tracefile_seek_position(LttvTracefileContext *self,
762 const LttEventPosition *pos)
763 {
764 LttvTracefileContext *tfc = self;
765
766 LttEvent *event;
767
768 GTree *pqueue = self->t_context->ts_context->pqueue;
769
770 ltt_tracefile_seek_position(tfc->tf, pos);
771 g_tree_remove(pqueue, tfc);
772 if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) {
773 tfc->timestamp = ltt_event_time(tfc->e);
774 g_tree_insert(pqueue, tfc, tfc);
775 }
776
777
778 }
779
780 gboolean lttv_process_trace_seek_position(LttvTraceContext *self,
781 const LttvTraceContextPosition *pos)
782 {
783 guint i, nb_tracefile;
784
785 LttvTracefileContext *tfc;
786
787 LttEvent *event;
788
789 nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
790 ltt_trace_per_cpu_tracefile_number(self->t);
791
792 if(nb_tracefile != pos->nb_tracefile)
793 return FALSE; /* Error */
794
795 for(i = 0 ; i < nb_tracefile ; i++) {
796 tfc = self->tracefiles[i];
797 lttv_process_tracefile_seek_position(tfc, pos->tf_pos[i]);
798 }
799
800 return TRUE;
801 }
802
803
804
805 gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self,
806 const LttvTracesetContextPosition *pos)
807 {
808 guint i, nb_trace;
809 gboolean sum_ret = TRUE;
810
811 LttvTraceContext *tc;
812
813 LttvTracefileContext *tfc;
814
815 nb_trace = lttv_traceset_number(self->ts);
816
817 if(nb_trace != pos->nb_trace)
818 return FALSE; /* Error */
819
820 for(i = 0 ; i < nb_trace ; i++) {
821 tc = self->traces[i];
822 sum_ret = sum_ret && lttv_process_trace_seek_position(tc, &pos->t_pos[i]);
823 }
824
825 return sum_ret;
826 }
827
828
829
830 static LttField *
831 find_field(LttEventType *et, const char *field)
832 {
833 LttType *t;
834
835 LttField *f;
836
837 guint i, nb;
838
839 char *name;
840
841 if(field == NULL) return NULL;
842
843 f = ltt_eventtype_field(et);
844 t = ltt_eventtype_type(et);
845 g_assert(ltt_type_class(t) == LTT_STRUCT);
846 nb = ltt_type_member_number(t);
847 for(i = 0 ; i < nb ; i++) {
848 ltt_type_member_type(t, i, &name);
849 if(strcmp(name, field) == 0) break;
850 }
851 g_assert(i < nb);
852 return ltt_field_member(f, i);
853 }
854
855
856 void
857 lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type,
858 char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
859 {
860 LttFacility *f;
861
862 LttEventType *et;
863
864 guint nb, pos, i;
865
866 char *name;
867
868 nb = ltt_trace_facility_find(t, facility, &pos);
869 if(nb < 1) g_error("No %s facility", facility);
870 f = ltt_trace_facility_get(t, pos);
871 et = ltt_facility_eventtype_get_by_name(f, event_type);
872 if(et == NULL) g_error("Event %s does not exist", event_type);
873
874 th->h = h;
875 th->id = ltt_eventtype_id(et);
876 th->f1 = find_field(et, field1);
877 th->f2 = find_field(et, field2);
878 th->f3 = find_field(et, field3);
879 }
880
881
882 LttvTracesetContextPosition *lttv_traceset_context_position_new()
883 {
884 return g_new(LttvTracesetContextPosition,1);
885 }
886
887
888 void lttv_traceset_context_position_save(const LttvTracesetContext *self,
889 LttvTracesetContextPosition *pos)
890 {
891 guint nb_trace, nb_tracefile;
892 guint iter_trace, iter_tracefile;
893
894 LttvTraceContext *tc;
895
896 LttvTracefileContext *tfc;
897
898 LttEvent *event;
899
900 LttTime timestamp = self->time_span.end_time;
901
902 pos->nb_trace = nb_trace = lttv_traceset_number(self->ts);
903 pos->t_pos = g_new(LttvTraceContextPosition, nb_trace);
904
905 for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
906 tc = self->traces[iter_trace];
907 pos->t_pos[iter_trace].nb_tracefile = nb_tracefile =
908 ltt_trace_control_tracefile_number(tc->t) +
909 ltt_trace_per_cpu_tracefile_number(tc->t);
910
911 pos->t_pos[iter_trace].tf_pos = g_new(LttEventPosition*, nb_tracefile);
912 for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
913 tfc = tc->tracefiles[iter_tracefile];
914 event = tfc->e;
915 if(event!=NULL) {
916 pos->t_pos[iter_trace].tf_pos[iter_tracefile]
917 = ltt_event_position_new();
918 ltt_event_position(event,
919 pos->t_pos[iter_trace].tf_pos[iter_tracefile]);
920 } else {
921 pos->t_pos[iter_trace].tf_pos[iter_tracefile] = NULL;
922 }
923 if(ltt_time_compare(tfc->timestamp, timestamp) < 0)
924 timestamp = tfc->timestamp;
925 }
926 }
927 pos->timestamp = timestamp;
928 }
929
930 void lttv_traceset_context_position_destroy(LttvTracesetContextPosition *pos)
931 {
932 guint nb_trace, nb_tracefile;
933 guint iter_trace, iter_tracefile;
934
935 nb_trace = pos->nb_trace;
936
937 for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
938 for(iter_tracefile = 0; iter_tracefile <
939 pos->t_pos[iter_trace].nb_tracefile;
940 iter_tracefile++) {
941 if(pos->t_pos[iter_trace].tf_pos[iter_tracefile] != NULL)
942 g_free(pos->t_pos[iter_trace].tf_pos[iter_tracefile]);
943 }
944 g_free(pos->t_pos[iter_trace].tf_pos);
945 }
946 g_free(pos->t_pos);
947
948 }
949
950 void lttv_traceset_context_position_copy(LttvTracesetContextPosition *dest,
951 const LttvTracesetContextPosition *src)
952 {
953 guint nb_trace, nb_tracefile;
954 guint iter_trace, iter_tracefile;
955
956 nb_trace = dest->nb_trace = src->nb_trace;
957 dest->t_pos = g_new(LttvTraceContextPosition, nb_trace);
958
959 for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
960
961 nb_tracefile = dest->t_pos[iter_trace].nb_tracefile =
962 src->t_pos[iter_trace].nb_tracefile;
963
964 for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
965 dest->t_pos[iter_trace].tf_pos[iter_tracefile] =
966 ltt_event_position_new();
967 if(src->t_pos[iter_trace].tf_pos[iter_tracefile] != NULL)
968 ltt_event_position_copy(
969 dest->t_pos[iter_trace].tf_pos[iter_tracefile],
970 src->t_pos[iter_trace].tf_pos[iter_tracefile]);
971 else
972 dest->t_pos[iter_trace].tf_pos[iter_tracefile] = NULL;
973 }
974 }
975
976 dest->timestamp = src->timestamp;
977 }
978
979 gint lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext *self,
980 const LttvTracesetContextPosition *pos)
981 {
982 guint nb_trace, nb_tracefile;
983 guint iter_trace, iter_tracefile;
984 gint ret;
985
986 LttvTraceContext *tc;
987
988 LttvTracefileContext *tfc;
989
990 LttEvent *event;
991
992 nb_trace = lttv_traceset_number(self->ts);
993
994 if(pos->nb_trace != nb_trace)
995 g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match.");
996
997 for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
998 tc = self->traces[iter_trace];
999 nb_tracefile = ltt_trace_control_tracefile_number(tc->t) +
1000 ltt_trace_per_cpu_tracefile_number(tc->t);
1001
1002 if(pos->t_pos[iter_trace].nb_tracefile != nb_tracefile)
1003 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
1004
1005 for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
1006 tfc = tc->tracefiles[iter_tracefile];
1007 event = tfc->e;
1008 if(
1009 ret =
1010 ltt_event_event_position_compare(event,
1011 pos->t_pos[iter_trace].tf_pos[iter_tracefile])
1012 != 0)
1013 return ret;
1014 }
1015 }
1016 return 0;
1017 }
1018
1019
1020 gint lttv_traceset_context_pos_pos_compare(
1021 const LttvTracesetContextPosition *pos1,
1022 const LttvTracesetContextPosition *pos2)
1023 {
1024 guint nb_trace, nb_tracefile;
1025 guint iter_trace, iter_tracefile;
1026
1027 gint ret;
1028
1029 nb_trace = pos1->nb_trace;
1030 if(nb_trace != pos2->nb_trace)
1031 g_error("lttv_traceset_context_pos_pos_compare : nb_trace does not match.");
1032
1033 for(iter_trace = 0 ; iter_trace < nb_trace ; iter_trace++) {
1034
1035 nb_tracefile = pos1->t_pos[iter_trace].nb_tracefile;
1036 if(nb_tracefile != pos2->t_pos[iter_trace].nb_tracefile)
1037 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
1038
1039 for(iter_tracefile = 0; iter_tracefile < nb_tracefile; iter_tracefile++) {
1040 if(ret =
1041 ltt_event_position_compare(
1042 pos1->t_pos[iter_trace].tf_pos[iter_tracefile],
1043 pos2->t_pos[iter_trace].tf_pos[iter_tracefile])
1044 != 0)
1045 return ret;
1046 }
1047 }
1048 return 0;
1049 }
1050
1051
1052 LttTime lttv_traceset_context_position_get_time(
1053 const LttvTracesetContextPosition *pos)
1054 {
1055 return pos->timestamp;
1056 }
1057
1058
1059 LttvTracefileContext *lttv_traceset_context_get_current_tfc(LttvTracesetContext *self)
1060 {
1061 GTree *pqueue = self->pqueue;
1062 LttvTracefileContext *tfc = NULL;
1063
1064 g_tree_foreach(pqueue, get_first, &tfc);
1065
1066 return tfc;
1067 }
This page took 0.053147 seconds and 5 git commands to generate.