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