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