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