Add copyright notices and some comments about status and TODO
[lttv.git] / ltt / branches / poly / lttv / main / processTrace.c
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
19
20 #include <lttv/processTrace.h>
21 #include <ltt/event.h>
22 #include <ltt/facility.h>
23 #include <ltt/trace.h>
24 #include <ltt/type.h>
25
26 void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
27 {
28 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
29 }
30
31
32 void lttv_context_fini(LttvTracesetContext *self)
33 {
34 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
35 }
36
37
38 LttvTracesetContext *
39 lttv_context_new_traceset_context(LttvTracesetContext *self)
40 {
41 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
42 }
43
44
45
46
47 LttvTraceContext *
48 lttv_context_new_trace_context(LttvTracesetContext *self)
49 {
50 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
51 }
52
53
54 LttvTracefileContext *
55 lttv_context_new_tracefile_context(LttvTracesetContext *self)
56 {
57 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
58 }
59
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 ***************************************************************************/
72 static 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
105
106 static void
107 init(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
115 LttTime null_time = {0, 0};
116
117 nb_trace = lttv_traceset_number(ts);
118 self->ts = ts;
119 self->traces = g_new(LttvTraceContext *, nb_trace);
120 self->before = lttv_hooks_new();
121 self->after = lttv_hooks_new();
122 self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
123 self->ts_a = lttv_traceset_attribute(ts);
124 for(i = 0 ; i < nb_trace ; i++) {
125 tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
126 self->traces[i] = tc;
127
128 tc->ts_context = self;
129 tc->index = i;
130 tc->vt = lttv_traceset_get(ts, i);
131 tc->t = lttv_trace(tc->vt);
132 tc->check = lttv_hooks_new();
133 tc->before = lttv_hooks_new();
134 tc->after = lttv_hooks_new();
135 tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
136 tc->t_a = lttv_trace_attribute(tc->vt);
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;
140 tc->control_tracefiles = g_new(LttvTracefileContext *, nb_control);
141 tc->per_cpu_tracefiles = g_new(LttvTracefileContext *, nb_per_cpu);
142
143 for(j = 0 ; j < nb_tracefile ; j++) {
144 tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
145 if(j < nb_control) {
146 tc->control_tracefiles[j] = tfc;
147 tfc->control = TRUE;
148 tfc->index = j;
149 tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
150 }
151 else {
152 tc->per_cpu_tracefiles[j - nb_control] = tfc;
153 tfc->control = FALSE;
154 tfc->index = j - nb_control;
155 tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
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();
166 tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
167 }
168 }
169 lttv_process_traceset_seek_time(self, null_time);
170 /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
171 self->Time_Span = g_new(TimeInterval,1);
172 lttv_traceset_context_compute_time_span(self, self->Time_Span);
173 }
174
175
176 void 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
184 LttvTraceset *ts = self->ts;
185
186 g_free(self->Time_Span);
187
188 lttv_hooks_destroy(self->before);
189 lttv_hooks_destroy(self->after);
190 //FIXME : segfault
191 g_object_unref(self->a);
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);
201 g_object_unref(tc->a);
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);
219 g_object_unref(tfc->a);
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
230 void 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,
236 LttvHooks *check_tracefile,
237 LttvHooks *before_tracefile,
238 LttvHooks *after_tracefile,
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);
263 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
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 {
271 tfc = tc->per_cpu_tracefiles[j-nb_control];
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
284 void 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,
290 LttvHooks *check_tracefile,
291 LttvHooks *before_tracefile,
292 LttvHooks *after_tracefile,
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);
317 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
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 {
325 tfc = tc->per_cpu_tracefiles[j-nb_control];
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
337 void 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
347 void 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
357 void 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
373 void 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
389 void 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
401 void 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 }
407
408 static LttvTracesetContext *
409 new_traceset_context(LttvTracesetContext *self)
410 {
411 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
412 }
413
414
415 static LttvTraceContext *
416 new_trace_context(LttvTracesetContext *self)
417 {
418 return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
419 }
420
421
422 static LttvTracefileContext *
423 new_tracefile_context(LttvTracesetContext *self)
424 {
425 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
426 }
427
428
429 static void
430 traceset_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
436 static void
437 traceset_context_finalize (LttvTracesetContext *self)
438 {
439 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
440 ->finalize(G_OBJECT(self));
441 }
442
443
444 static void
445 traceset_context_class_init (LttvTracesetContextClass *klass)
446 {
447 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
448
449 gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
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
458 GType
459 lttv_traceset_context_get_type(void)
460 {
461 static GType type = 0;
462 if (type == 0) {
463 static const GTypeInfo info = {
464 sizeof (LttvTracesetContextClass),
465 NULL, /* base_init */
466 NULL, /* base_finalize */
467 (GClassInitFunc) traceset_context_class_init, /* class_init */
468 NULL, /* class_finalize */
469 NULL, /* class_data */
470 sizeof (LttvTracesetContext),
471 0, /* n_preallocs */
472 (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
473 };
474
475 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType",
476 &info, 0);
477 }
478 return type;
479 }
480
481
482 static void
483 trace_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
489 static void
490 trace_context_finalize (LttvTraceContext *self)
491 {
492 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
493 finalize(G_OBJECT(self));
494 }
495
496
497 static void
498 trace_context_class_init (LttvTraceContextClass *klass)
499 {
500 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
501
502 gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
503 }
504
505
506 GType
507 lttv_trace_context_get_type(void)
508 {
509 static GType type = 0;
510 if (type == 0) {
511 static const GTypeInfo info = {
512 sizeof (LttvTraceContextClass),
513 NULL, /* base_init */
514 NULL, /* base_finalize */
515 (GClassInitFunc) trace_context_class_init, /* class_init */
516 NULL, /* class_finalize */
517 NULL, /* class_data */
518 sizeof (LttvTraceContext),
519 0, /* n_preallocs */
520 (GInstanceInitFunc) trace_context_instance_init /* instance_init */
521 };
522
523 type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType",
524 &info, 0);
525 }
526 return type;
527 }
528
529
530 static void
531 tracefile_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
537 static void
538 tracefile_context_finalize (LttvTracefileContext *self)
539 {
540 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
541 ->finalize(G_OBJECT(self));
542 }
543
544
545 static void
546 tracefile_context_class_init (LttvTracefileContextClass *klass)
547 {
548 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
549
550 gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
551 }
552
553
554 GType
555 lttv_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;
575 }
576
577
578 gint compare_tracefile(gconstpointer a, gconstpointer b)
579 {
580 return ltt_time_compare(*((LttTime *)a), *((LttTime *)b));
581 }
582
583
584 gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
585 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
586 return TRUE;
587 }
588
589
590 void lttv_process_traceset(LttvTracesetContext *self, LttTime end,
591 unsigned maxNumEvents)
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
599 guint i, j, nbi, nbj, id, nb_control, nb_cpu;
600
601 LttTrace *trace;
602
603 LttvTraceContext *tc;
604
605 LttTracefile *tracefile;
606
607 LttvTracefileContext *tfc;
608
609 LttEvent *event;
610
611 unsigned count = 0;
612
613 LttTime previous_timestamp = {0, 0};
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
619 lttv_hooks_call(self->before, self);
620 nbi = lttv_traceset_number(self->ts);
621
622 for(i = 0 ; i < nbi ; i++) {
623 tc = self->traces[i];
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
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 }
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
663 while(TRUE) {
664 tfc = NULL;
665 g_tree_foreach(pqueue, get_first, &tfc);
666 if(tfc == NULL) break;
667
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. */
671
672 count++;
673 if(count > maxNumEvents){
674 if(tfc->timestamp.tv_sec == previous_timestamp.tv_sec &&
675 tfc->timestamp.tv_nsec == previous_timestamp.tv_nsec) {
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 }
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. */
693
694 tfc = g_tree_lookup(pqueue, &(tfc->timestamp));
695 g_tree_remove(pqueue, &(tfc->timestamp));
696
697 if(!lttv_hooks_call(tfc->check_event, tfc)) {
698 id = ltt_event_eventtype_id(tfc->e);
699 lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
700 lttv_hooks_call(tfc->before_event, tfc);
701 lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
702 lttv_hooks_call(tfc->after_event, tfc);
703 }
704
705 event = ltt_tracefile_read(tfc->tf);
706 if(event != NULL) {
707 tfc->e = event;
708 tfc->timestamp = ltt_event_time(event);
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);
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);
732 lttv_hooks_call(self->after, self);
733
734 /* Free the traces, tracefiles and pqueue */
735
736 g_ptr_array_free(tracefiles, TRUE);
737 g_ptr_array_free(traces, TRUE);
738 g_tree_destroy(pqueue);
739 }
740
741
742 void 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
765 void 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
779 static LttField *
780 find_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
805 void
806 lttv_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.060211 seconds and 4 git commands to generate.