uninitialized variables checked. Also change two if/else if functions for switch
[lttv.git] / ltt / branches / poly / lttv / lttv / tracecontext.c
CommitLineData
9c312311 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
dc877563 19
d8f124de 20#include <lttv/tracecontext.h>
ffd54a90 21#include <ltt/event.h>
b445142a 22#include <ltt/facility.h>
a5dcde2f 23#include <ltt/trace.h>
24#include <ltt/type.h>
dc877563 25
8697a616 26
27
28
29gint 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
47struct _LttvTraceContextPosition {
2d262115 48 LttEventPosition **tf_pos; /* Position in each tracefile */
8697a616 49 guint nb_tracefile; /* Number of tracefiles (check) */
50};
51
52struct _LttvTracesetContextPosition {
2d262115 53 LttvTraceContextPosition *t_pos; /* Position in each trace */
8697a616 54 guint nb_trace; /* Number of traces (check) */
2d262115 55 LttTime timestamp; /* Current time at the saved position */
8697a616 56};
57
ffd54a90 58void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
dc877563 59{
ffd54a90 60 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
dc877563 61}
62
63
64void lttv_context_fini(LttvTracesetContext *self)
65{
66 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
67}
68
69
70LttvTracesetContext *
71lttv_context_new_traceset_context(LttvTracesetContext *self)
72{
73 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
74}
75
76
77
78
79LttvTraceContext *
80lttv_context_new_trace_context(LttvTracesetContext *self)
81{
82 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
83}
84
85
86LttvTracefileContext *
87lttv_context_new_tracefile_context(LttvTracesetContext *self)
88{
c6bc9cb9 89 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
dc877563 90}
91
f7afe191 92/****************************************************************************
93 * lttv_traceset_context_compute_time_span
94 *
8697a616 95 * Keep the time span is sync with on the fly addition and removal of traces
f7afe191 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
f7afe191 102 ***************************************************************************/
103static void lttv_traceset_context_compute_time_span(
104 LttvTracesetContext *self,
33f7a12c 105 TimeInterval *time_span)
f7afe191 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
33f7a12c 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;
912be9a5 118
f7afe191 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){
33f7a12c 126 time_span->start_time = s;
127 time_span->end_time = e;
f7afe191 128 }else{
33f7a12c 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;
f7afe191 137 }
138 }
139}
140
dc877563 141
142static void
143init(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
308711e5 151 LttTime null_time = {0, 0};
152
dc877563 153 nb_trace = lttv_traceset_number(ts);
154 self->ts = ts;
ffd54a90 155 self->traces = g_new(LttvTraceContext *, nb_trace);
ffd54a90 156 self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
308711e5 157 self->ts_a = lttv_traceset_attribute(ts);
dc877563 158 for(i = 0 ; i < nb_trace ; i++) {
ffd54a90 159 tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
dc877563 160 self->traces[i] = tc;
161
162 tc->ts_context = self;
163 tc->index = i;
308711e5 164 tc->vt = lttv_traceset_get(ts, i);
165 tc->t = lttv_trace(tc->vt);
ffd54a90 166 tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
308711e5 167 tc->t_a = lttv_trace_attribute(tc->vt);
dc877563 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;
dbb7bb09 171 tc->tracefiles = g_new(LttvTracefileContext *, nb_tracefile);
dc877563 172
173 for(j = 0 ; j < nb_tracefile ; j++) {
ffd54a90 174 tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
dbb7bb09 175 tc->tracefiles[j] = tfc;
176 tfc->index = j;
177
dc877563 178 if(j < nb_control) {
dc877563 179 tfc->control = TRUE;
ffd54a90 180 tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
dc877563 181 }
182 else {
dc877563 183 tfc->control = FALSE;
ffd54a90 184 tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
dc877563 185 }
186 tfc->t_context = tc;
d3e01c7a 187 tfc->e = ltt_event_new();
8697a616 188 tfc->event = lttv_hooks_new();
189 tfc->event_by_id = lttv_hooks_by_id_new();
ffd54a90 190 tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
dc877563 191 }
192 }
2d262115 193 self->pqueue = g_tree_new(compare_tracefile);
308711e5 194 lttv_process_traceset_seek_time(self, null_time);
33f7a12c 195 lttv_traceset_context_compute_time_span(self, &self->time_span);
8697a616 196
dc877563 197}
198
199
200void fini(LttvTracesetContext *self)
201{
dbb7bb09 202 guint i, j, nb_trace, nb_tracefile;
dc877563 203
204 LttvTraceContext *tc;
205
206 LttvTracefileContext *tfc;
207
ffd54a90 208 LttvTraceset *ts = self->ts;
dc877563 209
f7afe191 210 //FIXME : segfault
8697a616 211
212 g_tree_destroy(self->pqueue);
2061e03d 213 g_object_unref(self->a);
dc877563 214
215 nb_trace = lttv_traceset_number(ts);
216
217 for(i = 0 ; i < nb_trace ; i++) {
218 tc = self->traces[i];
219
ffd54a90 220 g_object_unref(tc->a);
dc877563 221
dbb7bb09 222 nb_tracefile = ltt_trace_control_tracefile_number(tc->t) +
223 ltt_trace_per_cpu_tracefile_number(tc->t);
dc877563 224
225 for(j = 0 ; j < nb_tracefile ; j++) {
dbb7bb09 226 tfc = tc->tracefiles[j];
d3e01c7a 227 ltt_event_destroy(tfc->e);
8697a616 228 lttv_hooks_destroy(tfc->event);
229 lttv_hooks_by_id_destroy(tfc->event_by_id);
ffd54a90 230 g_object_unref(tfc->a);
dc877563 231 g_object_unref(tfc);
232 }
dbb7bb09 233 g_free(tc->tracefiles);
dc877563 234 g_object_unref(tc);
235 }
236 g_free(self->traces);
237}
238
239
240void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
8697a616 241 LttvHooks *before_traceset,
dc877563 242 LttvHooks *before_trace,
ffd54a90 243 LttvHooks *before_tracefile,
8697a616 244 LttvHooks *event,
245 LttvHooksById *event_by_id)
dc877563 246{
247 LttvTraceset *ts = self->ts;
248
8697a616 249 guint i, nb_trace;
dc877563 250
251 LttvTraceContext *tc;
252
8697a616 253 lttv_hooks_call(before_traceset, self);
dc877563 254
dc877563 255 nb_trace = lttv_traceset_number(ts);
256
257 for(i = 0 ; i < nb_trace ; i++) {
258 tc = self->traces[i];
8697a616 259 lttv_trace_context_add_hooks(tc,
260 before_trace,
261 before_tracefile,
262 event,
263 event_by_id);
dc877563 264 }
265}
266
267
268void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
dc877563 269 LttvHooks *after_traceset,
dc877563 270 LttvHooks *after_trace,
ffd54a90 271 LttvHooks *after_tracefile,
8697a616 272 LttvHooks *event,
273 LttvHooksById *event_by_id)
dc877563 274{
8697a616 275
dc877563 276 LttvTraceset *ts = self->ts;
277
8697a616 278 guint i, nb_trace;
dc877563 279
280 LttvTraceContext *tc;
281
dc877563 282 nb_trace = lttv_traceset_number(ts);
283
284 for(i = 0 ; i < nb_trace ; i++) {
285 tc = self->traces[i];
8697a616 286 lttv_trace_context_remove_hooks(tc,
287 after_trace,
288 after_tracefile,
289 event,
290 event_by_id);
dc877563 291 }
8697a616 292
293 lttv_hooks_call(after_traceset, self);
294
295
dc877563 296}
297
8697a616 298void lttv_trace_context_add_hooks(LttvTraceContext *self,
299 LttvHooks *before_trace,
300 LttvHooks *before_tracefile,
301 LttvHooks *event,
302 LttvHooksById *event_by_id)
a8c0f09d 303{
8697a616 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 }
a8c0f09d 319}
320
8697a616 321
322
323void lttv_trace_context_remove_hooks(LttvTraceContext *self,
324 LttvHooks *after_trace,
325 LttvHooks *after_tracefile,
326 LttvHooks *event,
327 LttvHooksById *event_by_id)
a8c0f09d 328{
8697a616 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);
a8c0f09d 345}
346
8697a616 347void lttv_tracefile_context_add_hooks(LttvTracefileContext *self,
348 LttvHooks *before_tracefile,
349 LttvHooks *event,
350 LttvHooksById *event_by_id)
a8c0f09d 351{
8697a616 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
a8c0f09d 365}
366
8697a616 367void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self,
368 LttvHooks *after_tracefile,
369 LttvHooks *event,
370 LttvHooksById *event_by_id)
a8c0f09d 371{
8697a616 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);
a8c0f09d 385}
386
8697a616 387
388
a8c0f09d 389void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
390 unsigned i,
8697a616 391 LttvHooks *event_by_id)
a8c0f09d 392{
393 LttvHooks * h;
8697a616 394 h = lttv_hooks_by_id_find(tfc->event_by_id, i);
395 lttv_hooks_add_list(h, event_by_id);
a8c0f09d 396}
397
398void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
399 unsigned i)
400{
8697a616 401 lttv_hooks_by_id_remove(tfc->event_by_id, i);
a8c0f09d 402}
dc877563 403
ba576a78 404static LttvTracesetContext *
dc877563 405new_traceset_context(LttvTracesetContext *self)
406{
ffd54a90 407 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
dc877563 408}
409
410
ba576a78 411static LttvTraceContext *
dc877563 412new_trace_context(LttvTracesetContext *self)
413{
ffd54a90 414 return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
dc877563 415}
416
417
ba576a78 418static LttvTracefileContext *
dc877563 419new_tracefile_context(LttvTracesetContext *self)
420{
ffd54a90 421 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
dc877563 422}
423
424
425static void
426traceset_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
432static void
433traceset_context_finalize (LttvTracesetContext *self)
434{
b445142a 435 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
436 ->finalize(G_OBJECT(self));
dc877563 437}
438
439
440static void
441traceset_context_class_init (LttvTracesetContextClass *klass)
442{
443 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
444
ffd54a90 445 gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
dc877563 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
454GType
ffd54a90 455lttv_traceset_context_get_type(void)
dc877563 456{
457 static GType type = 0;
458 if (type == 0) {
459 static const GTypeInfo info = {
ffd54a90 460 sizeof (LttvTracesetContextClass),
dc877563 461 NULL, /* base_init */
462 NULL, /* base_finalize */
ffd54a90 463 (GClassInitFunc) traceset_context_class_init, /* class_init */
dc877563 464 NULL, /* class_finalize */
465 NULL, /* class_data */
ffd54a90 466 sizeof (LttvTracesetContext),
dc877563 467 0, /* n_preallocs */
ffd54a90 468 (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
dc877563 469 };
470
ffd54a90 471 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType",
dc877563 472 &info, 0);
473 }
474 return type;
475}
476
477
478static void
479trace_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
485static void
486trace_context_finalize (LttvTraceContext *self)
487{
b445142a 488 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
489 finalize(G_OBJECT(self));
dc877563 490}
491
492
493static void
494trace_context_class_init (LttvTraceContextClass *klass)
495{
496 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
497
ffd54a90 498 gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
dc877563 499}
500
501
502GType
ffd54a90 503lttv_trace_context_get_type(void)
dc877563 504{
505 static GType type = 0;
506 if (type == 0) {
507 static const GTypeInfo info = {
ffd54a90 508 sizeof (LttvTraceContextClass),
dc877563 509 NULL, /* base_init */
510 NULL, /* base_finalize */
ffd54a90 511 (GClassInitFunc) trace_context_class_init, /* class_init */
dc877563 512 NULL, /* class_finalize */
513 NULL, /* class_data */
c6bc9cb9 514 sizeof (LttvTraceContext),
dc877563 515 0, /* n_preallocs */
ffd54a90 516 (GInstanceInitFunc) trace_context_instance_init /* instance_init */
dc877563 517 };
518
ffd54a90 519 type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType",
dc877563 520 &info, 0);
521 }
522 return type;
523}
524
525
526static void
527tracefile_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
533static void
534tracefile_context_finalize (LttvTracefileContext *self)
535{
b445142a 536 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
537 ->finalize(G_OBJECT(self));
dc877563 538}
539
540
541static void
542tracefile_context_class_init (LttvTracefileContextClass *klass)
543{
544 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
545
ffd54a90 546 gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
547}
548
549
550GType
551lttv_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;
dc877563 571}
572
573
dc877563 574
575gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
576 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
577 return TRUE;
578}
579
580
8b0bbe19 581/* Put all the tracefiles at the tracefile context position */
582void 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
dc877563 619
8697a616 620void 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{
dc877563 627
8697a616 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
2a2fa4f0 637}
638
8697a616 639/* Note : a _middle must be preceded from a _seek or another middle */
640guint lttv_process_traceset_middle(LttvTracesetContext *self,
641 LttTime end,
b8eccacd 642 guint nb_events,
8697a616 643 const LttvTracesetContextPosition *end_position)
2a2fa4f0 644{
645 GTree *pqueue = self->pqueue;
646
647 guint id;
648
2a2fa4f0 649 LttvTracefileContext *tfc;
650
2a2fa4f0 651 unsigned count = 0;
652
a54f091a 653 gboolean last_ret = FALSE; /* return value of the last hook list called */
654
dc877563 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
8697a616 658 end time. */
dc877563 659
ffd54a90 660 while(TRUE) {
dc877563 661 tfc = NULL;
662 g_tree_foreach(pqueue, get_first, &tfc);
33f7a12c 663 /* End of traceset : tfc is NULL */
a43d67ba 664 if(tfc == NULL)
665 {
a43d67ba 666 return count;
667 }
dc877563 668
8697a616 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
a54f091a 677 if(last_ret == TRUE ||
678 count >= nb_events ||
8b0bbe19 679 (end_position!=NULL&&lttv_traceset_context_ctx_pos_compare(self,
680 end_position) == 0)||
8697a616 681 ltt_time_compare(tfc->timestamp, end) >= 0)
a43d67ba 682 {
a43d67ba 683 return count;
684 }
2a2fa4f0 685
308711e5 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. */
270e7cc5 689
f95bc830 690 g_tree_remove(pqueue, tfc);
2a2fa4f0 691 count++;
dc877563 692
8697a616 693 id = ltt_event_eventtype_id(tfc->e);
a54f091a 694 last_ret = lttv_hooks_call_merge(tfc->event, tfc,
8697a616 695 lttv_hooks_by_id_get(tfc->event_by_id, id), tfc);
dc877563 696
d3e01c7a 697 if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) {
698 tfc->timestamp = ltt_event_time(tfc->e);
33f7a12c 699 g_tree_insert(pqueue, tfc, tfc);
dc877563 700 }
701 }
2a2fa4f0 702}
703
704
8697a616 705void 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)
2a2fa4f0 711{
8697a616 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}
2a2fa4f0 721
8697a616 722void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
723{
724 guint i, nb_tracefile;
2a2fa4f0 725
726 LttvTracefileContext *tfc;
727
a5ba1787 728 GTree *pqueue = self->ts_context->pqueue;
729
8697a616 730 nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
731 ltt_trace_per_cpu_tracefile_number(self->t);
dc877563 732
8697a616 733 for(i = 0 ; i < nb_tracefile ; i++) {
734 tfc = self->tracefiles[i];
735 ltt_tracefile_seek_time(tfc->tf, start);
a5ba1787 736 g_tree_remove(pqueue, tfc);
d3e01c7a 737 if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) {
738 tfc->timestamp = ltt_event_time(tfc->e);
a5ba1787 739 g_tree_insert(pqueue, tfc, tfc);
8697a616 740 }
741 }
742}
dc877563 743
2a2fa4f0 744
8697a616 745void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
746{
747 guint i, nb_trace;
2a2fa4f0 748
8697a616 749 LttvTraceContext *tc;
2a2fa4f0 750
8697a616 751 LttvTracefileContext *tfc;
dc877563 752
8697a616 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 }
dc877563 758}
b445142a 759
308711e5 760
a5ba1787 761gboolean 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);
d3e01c7a 772 if(ltt_tracefile_read(tfc->tf, tfc->e) != NULL) {
773 tfc->timestamp = ltt_event_time(tfc->e);
a5ba1787 774 g_tree_insert(pqueue, tfc, tfc);
775 }
776
777
778}
779
8697a616 780gboolean lttv_process_trace_seek_position(LttvTraceContext *self,
781 const LttvTraceContextPosition *pos)
308711e5 782{
dbb7bb09 783 guint i, nb_tracefile;
308711e5 784
785 LttvTracefileContext *tfc;
786
787 LttEvent *event;
788
dbb7bb09 789 nb_tracefile = ltt_trace_control_tracefile_number(self->t) +
790 ltt_trace_per_cpu_tracefile_number(self->t);
308711e5 791
8697a616 792 if(nb_tracefile != pos->nb_tracefile)
793 return FALSE; /* Error */
794
dbb7bb09 795 for(i = 0 ; i < nb_tracefile ; i++) {
796 tfc = self->tracefiles[i];
a5ba1787 797 lttv_process_tracefile_seek_position(tfc, pos->tf_pos[i]);
308711e5 798 }
8697a616 799
800 return TRUE;
308711e5 801}
802
803
8697a616 804
805gboolean lttv_process_traceset_seek_position(LttvTracesetContext *self,
806 const LttvTracesetContextPosition *pos)
308711e5 807{
808 guint i, nb_trace;
8697a616 809 gboolean sum_ret = TRUE;
308711e5 810
811 LttvTraceContext *tc;
812
8697a616 813 LttvTracefileContext *tfc;
814
308711e5 815 nb_trace = lttv_traceset_number(self->ts);
8697a616 816
817 if(nb_trace != pos->nb_trace)
818 return FALSE; /* Error */
819
308711e5 820 for(i = 0 ; i < nb_trace ; i++) {
821 tc = self->traces[i];
8697a616 822 sum_ret = sum_ret && lttv_process_trace_seek_position(tc, &pos->t_pos[i]);
308711e5 823 }
8697a616 824
825 return sum_ret;
308711e5 826}
827
828
8697a616 829
b445142a 830static LttField *
831find_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
856void
857lttv_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
8b0bbe19 882LttvTracesetContextPosition *lttv_traceset_context_position_new()
5e2c04a2 883{
884 return g_new(LttvTracesetContextPosition,1);
885}
886
887
8697a616 888void 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
2d262115 900 LttTime timestamp = self->time_span.end_time;
901
8697a616 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++) {
8697a616 913 tfc = tc->tracefiles[iter_tracefile];
914 event = tfc->e;
4d39be09 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 }
2d262115 923 if(ltt_time_compare(tfc->timestamp, timestamp) < 0)
924 timestamp = tfc->timestamp;
8697a616 925 }
926 }
2d262115 927 pos->timestamp = timestamp;
8697a616 928}
929
930void 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++) {
4d39be09 941 if(pos->t_pos[iter_trace].tf_pos[iter_tracefile] != NULL)
942 g_free(pos->t_pos[iter_trace].tf_pos[iter_tracefile]);
8697a616 943 }
944 g_free(pos->t_pos[iter_trace].tf_pos);
945 }
946 g_free(pos->t_pos);
947
948}
949
5e2c04a2 950void 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();
4d39be09 967 if(src->t_pos[iter_trace].tf_pos[iter_tracefile] != NULL)
968 ltt_event_position_copy(
5e2c04a2 969 dest->t_pos[iter_trace].tf_pos[iter_tracefile],
970 src->t_pos[iter_trace].tf_pos[iter_tracefile]);
4d39be09 971 else
972 dest->t_pos[iter_trace].tf_pos[iter_tracefile] = NULL;
5e2c04a2 973 }
974 }
975
976 dest->timestamp = src->timestamp;
977}
978
8697a616 979gint 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
1020gint 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
2d262115 1052LttTime lttv_traceset_context_position_get_time(
1053 const LttvTracesetContextPosition *pos)
1054{
1055 return pos->timestamp;
1056}
1057
1058
1059LttvTracefileContext *lttv_traceset_context_get_current_tfc(LttvTracesetContext *self)
1060{
1061 GTree *pqueue = self->pqueue;
b56b5fec 1062 LttvTracefileContext *tfc = NULL;
2d262115 1063
1064 g_tree_foreach(pqueue, get_first, &tfc);
1065
1066 return tfc;
1067}
This page took 0.075592 seconds and 4 git commands to generate.