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