Add copyright notices and some comments about status and TODO
[lttv.git] / ltt / branches / poly / lttv / main / processTrace.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
20#include <lttv/processTrace.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
ffd54a90 26void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
dc877563 27{
ffd54a90 28 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
dc877563 29}
30
31
32void lttv_context_fini(LttvTracesetContext *self)
33{
34 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
35}
36
37
38LttvTracesetContext *
39lttv_context_new_traceset_context(LttvTracesetContext *self)
40{
41 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
42}
43
44
45
46
47LttvTraceContext *
48lttv_context_new_trace_context(LttvTracesetContext *self)
49{
50 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
51}
52
53
54LttvTracefileContext *
55lttv_context_new_tracefile_context(LttvTracesetContext *self)
56{
c6bc9cb9 57 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
dc877563 58}
59
f7afe191 60/****************************************************************************
61 * lttv_traceset_context_compute_time_span
62 *
63 * Keep the Time_Span is sync with on the fly addition and removal of traces
64 * in a trace set. It must be called each time a trace is added/removed from
65 * the traceset. It could be more efficient to call it only once a bunch
66 * of traces are loaded, but the calculation is not long, so it's not
67 * critical.
68 *
69 * Author : Xang Xiu Yang
70 * Imported from gtkTraceSet.c by Mathieu Desnoyers
71 ***************************************************************************/
72static void lttv_traceset_context_compute_time_span(
73 LttvTracesetContext *self,
74 TimeInterval *Time_Span)
75{
76 LttvTraceset * traceset = self->ts;
77 int numTraces = lttv_traceset_number(traceset);
78 int i;
79 LttTime s, e;
80 LttvTraceContext *tc;
81 LttTrace * trace;
82
83 for(i=0; i<numTraces;i++){
84 tc = self->traces[i];
85 trace = tc->t;
86
87 ltt_trace_time_span_get(trace, &s, &e);
88
89 if(i==0){
90 Time_Span->startTime = s;
91 Time_Span->endTime = e;
92 }else{
93 if(s.tv_sec < Time_Span->startTime.tv_sec ||
94 (s.tv_sec == Time_Span->startTime.tv_sec
95 && s.tv_nsec < Time_Span->startTime.tv_nsec))
96 Time_Span->startTime = s;
97 if(e.tv_sec > Time_Span->endTime.tv_sec ||
98 (e.tv_sec == Time_Span->endTime.tv_sec &&
99 e.tv_nsec > Time_Span->endTime.tv_nsec))
100 Time_Span->endTime = e;
101 }
102 }
103}
104
dc877563 105
106static void
107init(LttvTracesetContext *self, LttvTraceset *ts)
108{
109 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
110
111 LttvTraceContext *tc;
112
113 LttvTracefileContext *tfc;
114
308711e5 115 LttTime null_time = {0, 0};
116
dc877563 117 nb_trace = lttv_traceset_number(ts);
118 self->ts = ts;
ffd54a90 119 self->traces = g_new(LttvTraceContext *, nb_trace);
dc877563 120 self->before = lttv_hooks_new();
121 self->after = lttv_hooks_new();
ffd54a90 122 self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
308711e5 123 self->ts_a = lttv_traceset_attribute(ts);
dc877563 124 for(i = 0 ; i < nb_trace ; i++) {
ffd54a90 125 tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
dc877563 126 self->traces[i] = tc;
127
128 tc->ts_context = self;
129 tc->index = i;
308711e5 130 tc->vt = lttv_traceset_get(ts, i);
131 tc->t = lttv_trace(tc->vt);
dc877563 132 tc->check = lttv_hooks_new();
133 tc->before = lttv_hooks_new();
134 tc->after = lttv_hooks_new();
ffd54a90 135 tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
308711e5 136 tc->t_a = lttv_trace_attribute(tc->vt);
dc877563 137 nb_control = ltt_trace_control_tracefile_number(tc->t);
138 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
139 nb_tracefile = nb_control + nb_per_cpu;
ffd54a90 140 tc->control_tracefiles = g_new(LttvTracefileContext *, nb_control);
141 tc->per_cpu_tracefiles = g_new(LttvTracefileContext *, nb_per_cpu);
dc877563 142
143 for(j = 0 ; j < nb_tracefile ; j++) {
ffd54a90 144 tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
dc877563 145 if(j < nb_control) {
146 tc->control_tracefiles[j] = tfc;
147 tfc->control = TRUE;
148 tfc->index = j;
ffd54a90 149 tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
dc877563 150 }
151 else {
152 tc->per_cpu_tracefiles[j - nb_control] = tfc;
153 tfc->control = FALSE;
154 tfc->index = j - nb_control;
ffd54a90 155 tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
dc877563 156 }
157 tfc->t_context = tc;
158 tfc->check = lttv_hooks_new();
159 tfc->before = lttv_hooks_new();
160 tfc->after = lttv_hooks_new();
161 tfc->check_event = lttv_hooks_new();
162 tfc->before_event = lttv_hooks_new();
163 tfc->before_event_by_id = lttv_hooks_by_id_new();
164 tfc->after_event = lttv_hooks_new();
165 tfc->after_event_by_id = lttv_hooks_by_id_new();
ffd54a90 166 tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
dc877563 167 }
168 }
308711e5 169 lttv_process_traceset_seek_time(self, null_time);
170 /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
f7afe191 171 self->Time_Span = g_new(TimeInterval,1);
172 lttv_traceset_context_compute_time_span(self, self->Time_Span);
dc877563 173}
174
175
176void fini(LttvTracesetContext *self)
177{
178 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
179
180 LttvTraceContext *tc;
181
182 LttvTracefileContext *tfc;
183
ffd54a90 184 LttvTraceset *ts = self->ts;
dc877563 185
f7afe191 186 g_free(self->Time_Span);
187
dc877563 188 lttv_hooks_destroy(self->before);
189 lttv_hooks_destroy(self->after);
f7afe191 190 //FIXME : segfault
2061e03d 191 g_object_unref(self->a);
dc877563 192
193 nb_trace = lttv_traceset_number(ts);
194
195 for(i = 0 ; i < nb_trace ; i++) {
196 tc = self->traces[i];
197
198 lttv_hooks_destroy(tc->check);
199 lttv_hooks_destroy(tc->before);
200 lttv_hooks_destroy(tc->after);
ffd54a90 201 g_object_unref(tc->a);
dc877563 202
203 nb_control = ltt_trace_control_tracefile_number(tc->t);
204 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
205 nb_tracefile = nb_control + nb_per_cpu;
206
207 for(j = 0 ; j < nb_tracefile ; j++) {
208 if(j < nb_control) tfc = tc->control_tracefiles[j];
209 else tfc = tc->per_cpu_tracefiles[j - nb_control];
210
211 lttv_hooks_destroy(tfc->check);
212 lttv_hooks_destroy(tfc->before);
213 lttv_hooks_destroy(tfc->after);
214 lttv_hooks_destroy(tfc->check_event);
215 lttv_hooks_destroy(tfc->before_event);
216 lttv_hooks_by_id_destroy(tfc->before_event_by_id);
217 lttv_hooks_destroy(tfc->after_event);
218 lttv_hooks_by_id_destroy(tfc->after_event_by_id);
ffd54a90 219 g_object_unref(tfc->a);
dc877563 220 g_object_unref(tfc);
221 }
222 g_free(tc->control_tracefiles);
223 g_free(tc->per_cpu_tracefiles);
224 g_object_unref(tc);
225 }
226 g_free(self->traces);
227}
228
229
230void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
231 LttvHooks *before_traceset,
232 LttvHooks *after_traceset,
233 LttvHooks *check_trace,
234 LttvHooks *before_trace,
235 LttvHooks *after_trace,
ffd54a90 236 LttvHooks *check_tracefile,
237 LttvHooks *before_tracefile,
238 LttvHooks *after_tracefile,
dc877563 239 LttvHooks *check_event,
240 LttvHooks *before_event,
241 LttvHooks *after_event)
242{
243 LttvTraceset *ts = self->ts;
244
245 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
246
247 LttvTraceContext *tc;
248
249 LttvTracefileContext *tfc;
250
251 void *hook_data;
252
253 lttv_hooks_add_list(self->before, before_traceset);
254 lttv_hooks_add_list(self->after, after_traceset);
255 nb_trace = lttv_traceset_number(ts);
256
257 for(i = 0 ; i < nb_trace ; i++) {
258 tc = self->traces[i];
259 lttv_hooks_add_list(tc->check, check_trace);
260 lttv_hooks_add_list(tc->before, before_trace);
261 lttv_hooks_add_list(tc->after, after_trace);
262 nb_control = ltt_trace_control_tracefile_number(tc->t);
d83f6739 263 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
dc877563 264 nb_tracefile = nb_control + nb_per_cpu;
265
266 for(j = 0 ; j < nb_tracefile ; j++) {
267 if(j < nb_control) {
268 tfc = tc->control_tracefiles[j];
269 }
270 else {
d83f6739 271 tfc = tc->per_cpu_tracefiles[j-nb_control];
dc877563 272 }
273 lttv_hooks_add_list(tfc->check, check_tracefile);
274 lttv_hooks_add_list(tfc->before, before_tracefile);
275 lttv_hooks_add_list(tfc->after, after_tracefile);
276 lttv_hooks_add_list(tfc->check_event, check_event);
277 lttv_hooks_add_list(tfc->before_event, before_event);
278 lttv_hooks_add_list(tfc->after_event, after_event);
279 }
280 }
281}
282
283
284void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
285 LttvHooks *before_traceset,
286 LttvHooks *after_traceset,
287 LttvHooks *check_trace,
288 LttvHooks *before_trace,
289 LttvHooks *after_trace,
ffd54a90 290 LttvHooks *check_tracefile,
291 LttvHooks *before_tracefile,
292 LttvHooks *after_tracefile,
dc877563 293 LttvHooks *check_event,
294 LttvHooks *before_event,
295 LttvHooks *after_event)
296{
297 LttvTraceset *ts = self->ts;
298
299 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
300
301 LttvTraceContext *tc;
302
303 LttvTracefileContext *tfc;
304
305 void *hook_data;
306
307 lttv_hooks_remove_list(self->before, before_traceset);
308 lttv_hooks_remove_list(self->after, after_traceset);
309 nb_trace = lttv_traceset_number(ts);
310
311 for(i = 0 ; i < nb_trace ; i++) {
312 tc = self->traces[i];
313 lttv_hooks_remove_list(tc->check, check_trace);
314 lttv_hooks_remove_list(tc->before, before_trace);
315 lttv_hooks_remove_list(tc->after, after_trace);
316 nb_control = ltt_trace_control_tracefile_number(tc->t);
d83f6739 317 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
dc877563 318 nb_tracefile = nb_control + nb_per_cpu;
319
320 for(j = 0 ; j < nb_tracefile ; j++) {
321 if(j < nb_control) {
322 tfc = tc->control_tracefiles[j];
323 }
324 else {
d83f6739 325 tfc = tc->per_cpu_tracefiles[j-nb_control];
dc877563 326 }
327 lttv_hooks_remove_list(tfc->check, check_tracefile);
328 lttv_hooks_remove_list(tfc->before, before_tracefile);
329 lttv_hooks_remove_list(tfc->after, after_tracefile);
330 lttv_hooks_remove_list(tfc->check_event, check_event);
331 lttv_hooks_remove_list(tfc->before_event, before_event);
332 lttv_hooks_remove_list(tfc->after_event, after_event);
333 }
334 }
335}
336
a8c0f09d 337void lttv_trace_context_add_hooks(LttvTraceContext *tc,
338 LttvHooks *check_trace,
339 LttvHooks *before_trace,
340 LttvHooks *after_trace)
341{
342 lttv_hooks_add_list(tc->check, check_trace);
343 lttv_hooks_add_list(tc->before, before_trace);
344 lttv_hooks_add_list(tc->after, after_trace);
345}
346
347void lttv_trace_context_remove_hooks(LttvTraceContext *tc,
348 LttvHooks *check_trace,
349 LttvHooks *before_trace,
350 LttvHooks *after_trace)
351{
352 lttv_hooks_remove_list(tc->check, check_trace);
353 lttv_hooks_remove_list(tc->before, before_trace);
354 lttv_hooks_remove_list(tc->after, after_trace);
355}
356
357void lttv_tracefile_context_add_hooks(LttvTracefileContext *tfc,
358 LttvHooks *check_tracefile,
359 LttvHooks *before_tracefile,
360 LttvHooks *after_tracefile,
361 LttvHooks *check_event,
362 LttvHooks *before_event,
363 LttvHooks *after_event)
364{
365 lttv_hooks_add_list(tfc->check, check_tracefile);
366 lttv_hooks_add_list(tfc->before, before_tracefile);
367 lttv_hooks_add_list(tfc->after, after_tracefile);
368 lttv_hooks_add_list(tfc->check_event, check_event);
369 lttv_hooks_add_list(tfc->before_event, before_event);
370 lttv_hooks_add_list(tfc->after_event, after_event);
371}
372
373void lttv_tracefile_context_remove_hooks(LttvTracefileContext *tfc,
374 LttvHooks *check_tracefile,
375 LttvHooks *before_tracefile,
376 LttvHooks *after_tracefile,
377 LttvHooks *check_event,
378 LttvHooks *before_event,
379 LttvHooks *after_event)
380{
381 lttv_hooks_remove_list(tfc->check, check_tracefile);
382 lttv_hooks_remove_list(tfc->before, before_tracefile);
383 lttv_hooks_remove_list(tfc->after, after_tracefile);
384 lttv_hooks_remove_list(tfc->check_event, check_event);
385 lttv_hooks_remove_list(tfc->before_event, before_event);
386 lttv_hooks_remove_list(tfc->after_event, after_event);
387}
388
389void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
390 unsigned i,
391 LttvHooks *before_event_by_id,
392 LttvHooks *after_event_by_id)
393{
394 LttvHooks * h;
395 h = lttv_hooks_by_id_find(tfc->before_event_by_id, i);
396 lttv_hooks_add_list(h, before_event_by_id);
397 h = lttv_hooks_by_id_find(tfc->after_event_by_id, i);
398 lttv_hooks_add_list(h, after_event_by_id);
399}
400
401void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
402 unsigned i)
403{
404 lttv_hooks_by_id_remove(tfc->before_event_by_id, i);
405 lttv_hooks_by_id_remove(tfc->after_event_by_id, i);
406}
dc877563 407
ba576a78 408static LttvTracesetContext *
dc877563 409new_traceset_context(LttvTracesetContext *self)
410{
ffd54a90 411 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
dc877563 412}
413
414
ba576a78 415static LttvTraceContext *
dc877563 416new_trace_context(LttvTracesetContext *self)
417{
ffd54a90 418 return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
dc877563 419}
420
421
ba576a78 422static LttvTracefileContext *
dc877563 423new_tracefile_context(LttvTracesetContext *self)
424{
ffd54a90 425 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
dc877563 426}
427
428
429static void
430traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
431{
432 /* Be careful of anything which would not work well with shallow copies */
433}
434
435
436static void
437traceset_context_finalize (LttvTracesetContext *self)
438{
b445142a 439 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
440 ->finalize(G_OBJECT(self));
dc877563 441}
442
443
444static void
445traceset_context_class_init (LttvTracesetContextClass *klass)
446{
447 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
448
ffd54a90 449 gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
dc877563 450 klass->init = init;
451 klass->fini = fini;
452 klass->new_traceset_context = new_traceset_context;
453 klass->new_trace_context = new_trace_context;
454 klass->new_tracefile_context = new_tracefile_context;
455}
456
457
458GType
ffd54a90 459lttv_traceset_context_get_type(void)
dc877563 460{
461 static GType type = 0;
462 if (type == 0) {
463 static const GTypeInfo info = {
ffd54a90 464 sizeof (LttvTracesetContextClass),
dc877563 465 NULL, /* base_init */
466 NULL, /* base_finalize */
ffd54a90 467 (GClassInitFunc) traceset_context_class_init, /* class_init */
dc877563 468 NULL, /* class_finalize */
469 NULL, /* class_data */
ffd54a90 470 sizeof (LttvTracesetContext),
dc877563 471 0, /* n_preallocs */
ffd54a90 472 (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
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 */
ffd54a90 520 (GInstanceInitFunc) trace_context_instance_init /* instance_init */
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 */
568 (GInstanceInitFunc) tracefile_context_instance_init /* instance_init */
569 };
570
571 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType",
572 &info, 0);
573 }
574 return type;
dc877563 575}
576
577
ffd54a90 578gint compare_tracefile(gconstpointer a, gconstpointer b)
dc877563 579{
308711e5 580 return ltt_time_compare(*((LttTime *)a), *((LttTime *)b));
dc877563 581}
582
583
584gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
585 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
586 return TRUE;
587}
588
589
308711e5 590void lttv_process_traceset(LttvTracesetContext *self, LttTime end,
591 unsigned maxNumEvents)
dc877563 592{
593 GPtrArray *traces = g_ptr_array_new();
594
595 GPtrArray *tracefiles = g_ptr_array_new();
596
597 GTree *pqueue = g_tree_new(compare_tracefile);
598
ffd54a90 599 guint i, j, nbi, nbj, id, nb_control, nb_cpu;
dc877563 600
601 LttTrace *trace;
602
603 LttvTraceContext *tc;
604
605 LttTracefile *tracefile;
606
607 LttvTracefileContext *tfc;
608
609 LttEvent *event;
308711e5 610
270e7cc5 611 unsigned count = 0;
308711e5 612
613 LttTime previous_timestamp = {0, 0};
dc877563 614
615 /* Call all before_traceset, before_trace, and before_tracefile hooks.
616 For all qualifying tracefiles, seek to the start time, create a context,
617 read one event and insert in the pqueue based on the event time. */
618
308711e5 619 lttv_hooks_call(self->before, self);
620 nbi = lttv_traceset_number(self->ts);
dc877563 621
622 for(i = 0 ; i < nbi ; i++) {
308711e5 623 tc = self->traces[i];
dc877563 624 trace = tc->t;
625
626 if(!lttv_hooks_call_check(tc->check, tc)) {
627 g_ptr_array_add(traces, tc);
628 lttv_hooks_call(tc->before, tc);
629 nb_control = ltt_trace_control_tracefile_number(trace);
630 nb_cpu = ltt_trace_per_cpu_tracefile_number(trace);
631 nbj = nb_control + nb_cpu;
632
633 for(j = 0 ; j < nbj ; j++) {
634 if(j < nb_control) {
635 tfc = tc->control_tracefiles[j];
636 }
637 else {
638 tfc = tc->per_cpu_tracefiles[j - nb_control];
639 }
640
641 tracefile = tfc->tf;
642
643 if(!lttv_hooks_call_check(tfc->check, tfc)) {
644 g_ptr_array_add(tracefiles, tfc);
645 lttv_hooks_call(tfc->before, tfc);
646
a8c0f09d 647 if(tfc->e != NULL) {
648 if(tfc->timestamp.tv_sec < end.tv_sec ||
649 (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec)){
650 g_tree_insert(pqueue, &(tfc->timestamp), tfc);
651 }
dc877563 652 }
653 }
654 }
655 }
656 }
657
658 /* Get the next event from the pqueue, call its hooks,
659 reinsert in the pqueue the following event from the same tracefile
660 unless the tracefile is finished or the event is later than the
661 start time. */
662
ffd54a90 663 while(TRUE) {
dc877563 664 tfc = NULL;
665 g_tree_foreach(pqueue, get_first, &tfc);
666 if(tfc == NULL) break;
667
308711e5 668 /* Have we reached the maximum number of events specified? However,
669 continue for all the events with the same time stamp (CHECK?). Then,
670 empty the queue and break from the loop. */
dc877563 671
270e7cc5 672 count++;
673 if(count > maxNumEvents){
308711e5 674 if(tfc->timestamp.tv_sec == previous_timestamp.tv_sec &&
675 tfc->timestamp.tv_nsec == previous_timestamp.tv_nsec) {
270e7cc5 676 count--;
677 }else{
678 while(TRUE){
679 tfc = NULL;
680 g_tree_foreach(pqueue, get_first, &tfc);
681 if(tfc == NULL) break;
682 g_tree_remove(pqueue, &(tfc->timestamp));
683 }
684 break;
685 }
686 }
308711e5 687 previous_timestamp = tfc->timestamp;
688
689
690 /* Get the tracefile with an event for the smallest time found. If two
691 or more tracefiles have events for the same time, hope that lookup
692 and remove are consistent. */
270e7cc5 693
ffd54a90 694 tfc = g_tree_lookup(pqueue, &(tfc->timestamp));
695 g_tree_remove(pqueue, &(tfc->timestamp));
dc877563 696
b445142a 697 if(!lttv_hooks_call(tfc->check_event, tfc)) {
cbe7c836 698 id = ltt_event_eventtype_id(tfc->e);
dc877563 699 lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
60b53e4f 700 lttv_hooks_call(tfc->before_event, tfc);
dc877563 701 lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
60b53e4f 702 lttv_hooks_call(tfc->after_event, tfc);
dc877563 703 }
704
705 event = ltt_tracefile_read(tfc->tf);
706 if(event != NULL) {
707 tfc->e = event;
ffd54a90 708 tfc->timestamp = ltt_event_time(event);
270e7cc5 709 if(tfc->timestamp.tv_sec < end.tv_sec ||
710 (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec))
711 g_tree_insert(pqueue, &(tfc->timestamp), tfc);
dc877563 712 }
713 }
714
715 /* Call all the after_tracefile, after_trace and after_traceset hooks. */
716
717 for(i = 0, j = 0 ; i < traces->len ; i++) {
718 tc = traces->pdata[i];
719 while(j < tracefiles->len) {
720 tfc = tracefiles->pdata[j];
721
722 if(tfc->t_context == tc) {
723 lttv_hooks_call(tfc->after, tfc);
724 j++;
725 }
726 else break;
727 }
728 lttv_hooks_call(tc->after, tc);
729 }
730
731 g_assert(j == tracefiles->len);
308711e5 732 lttv_hooks_call(self->after, self);
dc877563 733
734 /* Free the traces, tracefiles and pqueue */
735
736 g_ptr_array_free(tracefiles, TRUE);
737 g_ptr_array_free(traces, TRUE);
ffd54a90 738 g_tree_destroy(pqueue);
dc877563 739}
b445142a 740
308711e5 741
742void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
743{
744 guint i, nb_control, nb_per_cpu, nb_tracefile;
745
746 LttvTracefileContext *tfc;
747
748 LttEvent *event;
749
750 nb_control = ltt_trace_control_tracefile_number(self->t);
751 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->t);
752 nb_tracefile = nb_control + nb_per_cpu;
753 for(i = 0 ; i < nb_tracefile ; i++) {
754 if(i < nb_control) tfc = self->control_tracefiles[i];
755 else tfc = self->per_cpu_tracefiles[i - nb_control];
756
757 ltt_tracefile_seek_time(tfc->tf, start);
758 event = ltt_tracefile_read(tfc->tf);
759 tfc->e = event;
760 if(event != NULL) tfc->timestamp = ltt_event_time(event);
761 }
762}
763
764
765void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
766{
767 guint i, nb_trace;
768
769 LttvTraceContext *tc;
770
771 nb_trace = lttv_traceset_number(self->ts);
772 for(i = 0 ; i < nb_trace ; i++) {
773 tc = self->traces[i];
774 lttv_process_trace_seek_time(tc, start);
775 }
776}
777
778
b445142a 779static LttField *
780find_field(LttEventType *et, const char *field)
781{
782 LttType *t;
783
784 LttField *f;
785
786 guint i, nb;
787
788 char *name;
789
790 if(field == NULL) return NULL;
791
792 f = ltt_eventtype_field(et);
793 t = ltt_eventtype_type(et);
794 g_assert(ltt_type_class(t) == LTT_STRUCT);
795 nb = ltt_type_member_number(t);
796 for(i = 0 ; i < nb ; i++) {
797 ltt_type_member_type(t, i, &name);
798 if(strcmp(name, field) == 0) break;
799 }
800 g_assert(i < nb);
801 return ltt_field_member(f, i);
802}
803
804
805void
806lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type,
807 char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
808{
809 LttFacility *f;
810
811 LttEventType *et;
812
813 guint nb, pos, i;
814
815 char *name;
816
817 nb = ltt_trace_facility_find(t, facility, &pos);
818 if(nb < 1) g_error("No %s facility", facility);
819 f = ltt_trace_facility_get(t, pos);
820 et = ltt_facility_eventtype_get_by_name(f, event_type);
821 if(et == NULL) g_error("Event %s does not exist", event_type);
822
823 th->h = h;
824 th->id = ltt_eventtype_id(et);
825 th->f1 = find_field(et, field1);
826 th->f2 = find_field(et, field2);
827 th->f3 = find_field(et, field3);
828}
829
830
This page took 0.068057 seconds and 4 git commands to generate.