Use g_info and g_debug properly.
[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
912be9a5 83 Time_Span->startTime.tv_sec = 0;
84 Time_Span->startTime.tv_nsec = 0;
85 Time_Span->endTime.tv_sec = 0;
86 Time_Span->endTime.tv_nsec = 0;
87
f7afe191 88 for(i=0; i<numTraces;i++){
89 tc = self->traces[i];
90 trace = tc->t;
91
92 ltt_trace_time_span_get(trace, &s, &e);
93
94 if(i==0){
95 Time_Span->startTime = s;
96 Time_Span->endTime = e;
97 }else{
98 if(s.tv_sec < Time_Span->startTime.tv_sec ||
99 (s.tv_sec == Time_Span->startTime.tv_sec
100 && s.tv_nsec < Time_Span->startTime.tv_nsec))
101 Time_Span->startTime = s;
102 if(e.tv_sec > Time_Span->endTime.tv_sec ||
103 (e.tv_sec == Time_Span->endTime.tv_sec &&
104 e.tv_nsec > Time_Span->endTime.tv_nsec))
105 Time_Span->endTime = e;
106 }
107 }
108}
109
dc877563 110
111static void
112init(LttvTracesetContext *self, LttvTraceset *ts)
113{
114 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
115
116 LttvTraceContext *tc;
117
118 LttvTracefileContext *tfc;
119
308711e5 120 LttTime null_time = {0, 0};
121
dc877563 122 nb_trace = lttv_traceset_number(ts);
123 self->ts = ts;
ffd54a90 124 self->traces = g_new(LttvTraceContext *, nb_trace);
dc877563 125 self->before = lttv_hooks_new();
126 self->after = lttv_hooks_new();
ffd54a90 127 self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
308711e5 128 self->ts_a = lttv_traceset_attribute(ts);
dc877563 129 for(i = 0 ; i < nb_trace ; i++) {
ffd54a90 130 tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
dc877563 131 self->traces[i] = tc;
132
133 tc->ts_context = self;
134 tc->index = i;
308711e5 135 tc->vt = lttv_traceset_get(ts, i);
136 tc->t = lttv_trace(tc->vt);
dc877563 137 tc->check = lttv_hooks_new();
138 tc->before = lttv_hooks_new();
139 tc->after = lttv_hooks_new();
ffd54a90 140 tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
308711e5 141 tc->t_a = lttv_trace_attribute(tc->vt);
dc877563 142 nb_control = ltt_trace_control_tracefile_number(tc->t);
143 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
144 nb_tracefile = nb_control + nb_per_cpu;
ffd54a90 145 tc->control_tracefiles = g_new(LttvTracefileContext *, nb_control);
146 tc->per_cpu_tracefiles = g_new(LttvTracefileContext *, nb_per_cpu);
dc877563 147
148 for(j = 0 ; j < nb_tracefile ; j++) {
ffd54a90 149 tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
dc877563 150 if(j < nb_control) {
151 tc->control_tracefiles[j] = tfc;
152 tfc->control = TRUE;
153 tfc->index = j;
ffd54a90 154 tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
dc877563 155 }
156 else {
157 tc->per_cpu_tracefiles[j - nb_control] = tfc;
158 tfc->control = FALSE;
159 tfc->index = j - nb_control;
ffd54a90 160 tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
dc877563 161 }
162 tfc->t_context = tc;
163 tfc->check = lttv_hooks_new();
164 tfc->before = lttv_hooks_new();
165 tfc->after = lttv_hooks_new();
166 tfc->check_event = lttv_hooks_new();
167 tfc->before_event = lttv_hooks_new();
168 tfc->before_event_by_id = lttv_hooks_by_id_new();
169 tfc->after_event = lttv_hooks_new();
170 tfc->after_event_by_id = lttv_hooks_by_id_new();
ffd54a90 171 tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
dc877563 172 }
173 }
308711e5 174 lttv_process_traceset_seek_time(self, null_time);
175 /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
f7afe191 176 self->Time_Span = g_new(TimeInterval,1);
177 lttv_traceset_context_compute_time_span(self, self->Time_Span);
dc877563 178}
179
180
181void fini(LttvTracesetContext *self)
182{
183 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
184
185 LttvTraceContext *tc;
186
187 LttvTracefileContext *tfc;
188
ffd54a90 189 LttvTraceset *ts = self->ts;
dc877563 190
f7afe191 191 g_free(self->Time_Span);
192
dc877563 193 lttv_hooks_destroy(self->before);
194 lttv_hooks_destroy(self->after);
f7afe191 195 //FIXME : segfault
2061e03d 196 g_object_unref(self->a);
dc877563 197
198 nb_trace = lttv_traceset_number(ts);
199
200 for(i = 0 ; i < nb_trace ; i++) {
201 tc = self->traces[i];
202
203 lttv_hooks_destroy(tc->check);
204 lttv_hooks_destroy(tc->before);
205 lttv_hooks_destroy(tc->after);
ffd54a90 206 g_object_unref(tc->a);
dc877563 207
208 nb_control = ltt_trace_control_tracefile_number(tc->t);
209 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
210 nb_tracefile = nb_control + nb_per_cpu;
211
212 for(j = 0 ; j < nb_tracefile ; j++) {
213 if(j < nb_control) tfc = tc->control_tracefiles[j];
214 else tfc = tc->per_cpu_tracefiles[j - nb_control];
215
216 lttv_hooks_destroy(tfc->check);
217 lttv_hooks_destroy(tfc->before);
218 lttv_hooks_destroy(tfc->after);
219 lttv_hooks_destroy(tfc->check_event);
220 lttv_hooks_destroy(tfc->before_event);
221 lttv_hooks_by_id_destroy(tfc->before_event_by_id);
222 lttv_hooks_destroy(tfc->after_event);
223 lttv_hooks_by_id_destroy(tfc->after_event_by_id);
ffd54a90 224 g_object_unref(tfc->a);
dc877563 225 g_object_unref(tfc);
226 }
227 g_free(tc->control_tracefiles);
228 g_free(tc->per_cpu_tracefiles);
229 g_object_unref(tc);
230 }
231 g_free(self->traces);
232}
233
234
235void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
236 LttvHooks *before_traceset,
237 LttvHooks *after_traceset,
238 LttvHooks *check_trace,
239 LttvHooks *before_trace,
240 LttvHooks *after_trace,
ffd54a90 241 LttvHooks *check_tracefile,
242 LttvHooks *before_tracefile,
243 LttvHooks *after_tracefile,
dc877563 244 LttvHooks *check_event,
245 LttvHooks *before_event,
246 LttvHooks *after_event)
247{
248 LttvTraceset *ts = self->ts;
249
250 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
251
252 LttvTraceContext *tc;
253
254 LttvTracefileContext *tfc;
255
256 void *hook_data;
257
258 lttv_hooks_add_list(self->before, before_traceset);
259 lttv_hooks_add_list(self->after, after_traceset);
260 nb_trace = lttv_traceset_number(ts);
261
262 for(i = 0 ; i < nb_trace ; i++) {
263 tc = self->traces[i];
264 lttv_hooks_add_list(tc->check, check_trace);
265 lttv_hooks_add_list(tc->before, before_trace);
266 lttv_hooks_add_list(tc->after, after_trace);
267 nb_control = ltt_trace_control_tracefile_number(tc->t);
d83f6739 268 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
dc877563 269 nb_tracefile = nb_control + nb_per_cpu;
270
271 for(j = 0 ; j < nb_tracefile ; j++) {
272 if(j < nb_control) {
273 tfc = tc->control_tracefiles[j];
274 }
275 else {
d83f6739 276 tfc = tc->per_cpu_tracefiles[j-nb_control];
dc877563 277 }
278 lttv_hooks_add_list(tfc->check, check_tracefile);
279 lttv_hooks_add_list(tfc->before, before_tracefile);
280 lttv_hooks_add_list(tfc->after, after_tracefile);
281 lttv_hooks_add_list(tfc->check_event, check_event);
282 lttv_hooks_add_list(tfc->before_event, before_event);
283 lttv_hooks_add_list(tfc->after_event, after_event);
284 }
285 }
286}
287
288
289void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
290 LttvHooks *before_traceset,
291 LttvHooks *after_traceset,
292 LttvHooks *check_trace,
293 LttvHooks *before_trace,
294 LttvHooks *after_trace,
ffd54a90 295 LttvHooks *check_tracefile,
296 LttvHooks *before_tracefile,
297 LttvHooks *after_tracefile,
dc877563 298 LttvHooks *check_event,
299 LttvHooks *before_event,
300 LttvHooks *after_event)
301{
302 LttvTraceset *ts = self->ts;
303
304 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
305
306 LttvTraceContext *tc;
307
308 LttvTracefileContext *tfc;
309
310 void *hook_data;
311
312 lttv_hooks_remove_list(self->before, before_traceset);
313 lttv_hooks_remove_list(self->after, after_traceset);
314 nb_trace = lttv_traceset_number(ts);
315
316 for(i = 0 ; i < nb_trace ; i++) {
317 tc = self->traces[i];
318 lttv_hooks_remove_list(tc->check, check_trace);
319 lttv_hooks_remove_list(tc->before, before_trace);
320 lttv_hooks_remove_list(tc->after, after_trace);
321 nb_control = ltt_trace_control_tracefile_number(tc->t);
d83f6739 322 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
dc877563 323 nb_tracefile = nb_control + nb_per_cpu;
324
325 for(j = 0 ; j < nb_tracefile ; j++) {
326 if(j < nb_control) {
327 tfc = tc->control_tracefiles[j];
328 }
329 else {
d83f6739 330 tfc = tc->per_cpu_tracefiles[j-nb_control];
dc877563 331 }
332 lttv_hooks_remove_list(tfc->check, check_tracefile);
333 lttv_hooks_remove_list(tfc->before, before_tracefile);
334 lttv_hooks_remove_list(tfc->after, after_tracefile);
335 lttv_hooks_remove_list(tfc->check_event, check_event);
336 lttv_hooks_remove_list(tfc->before_event, before_event);
337 lttv_hooks_remove_list(tfc->after_event, after_event);
338 }
339 }
340}
341
a8c0f09d 342void lttv_trace_context_add_hooks(LttvTraceContext *tc,
343 LttvHooks *check_trace,
344 LttvHooks *before_trace,
345 LttvHooks *after_trace)
346{
347 lttv_hooks_add_list(tc->check, check_trace);
348 lttv_hooks_add_list(tc->before, before_trace);
349 lttv_hooks_add_list(tc->after, after_trace);
350}
351
352void lttv_trace_context_remove_hooks(LttvTraceContext *tc,
353 LttvHooks *check_trace,
354 LttvHooks *before_trace,
355 LttvHooks *after_trace)
356{
357 lttv_hooks_remove_list(tc->check, check_trace);
358 lttv_hooks_remove_list(tc->before, before_trace);
359 lttv_hooks_remove_list(tc->after, after_trace);
360}
361
362void lttv_tracefile_context_add_hooks(LttvTracefileContext *tfc,
363 LttvHooks *check_tracefile,
364 LttvHooks *before_tracefile,
365 LttvHooks *after_tracefile,
366 LttvHooks *check_event,
367 LttvHooks *before_event,
368 LttvHooks *after_event)
369{
370 lttv_hooks_add_list(tfc->check, check_tracefile);
371 lttv_hooks_add_list(tfc->before, before_tracefile);
372 lttv_hooks_add_list(tfc->after, after_tracefile);
373 lttv_hooks_add_list(tfc->check_event, check_event);
374 lttv_hooks_add_list(tfc->before_event, before_event);
375 lttv_hooks_add_list(tfc->after_event, after_event);
376}
377
378void lttv_tracefile_context_remove_hooks(LttvTracefileContext *tfc,
379 LttvHooks *check_tracefile,
380 LttvHooks *before_tracefile,
381 LttvHooks *after_tracefile,
382 LttvHooks *check_event,
383 LttvHooks *before_event,
384 LttvHooks *after_event)
385{
386 lttv_hooks_remove_list(tfc->check, check_tracefile);
387 lttv_hooks_remove_list(tfc->before, before_tracefile);
388 lttv_hooks_remove_list(tfc->after, after_tracefile);
389 lttv_hooks_remove_list(tfc->check_event, check_event);
390 lttv_hooks_remove_list(tfc->before_event, before_event);
391 lttv_hooks_remove_list(tfc->after_event, after_event);
392}
393
394void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc,
395 unsigned i,
396 LttvHooks *before_event_by_id,
397 LttvHooks *after_event_by_id)
398{
399 LttvHooks * h;
400 h = lttv_hooks_by_id_find(tfc->before_event_by_id, i);
401 lttv_hooks_add_list(h, before_event_by_id);
402 h = lttv_hooks_by_id_find(tfc->after_event_by_id, i);
403 lttv_hooks_add_list(h, after_event_by_id);
404}
405
406void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc,
407 unsigned i)
408{
409 lttv_hooks_by_id_remove(tfc->before_event_by_id, i);
410 lttv_hooks_by_id_remove(tfc->after_event_by_id, i);
411}
dc877563 412
ba576a78 413static LttvTracesetContext *
dc877563 414new_traceset_context(LttvTracesetContext *self)
415{
ffd54a90 416 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
dc877563 417}
418
419
ba576a78 420static LttvTraceContext *
dc877563 421new_trace_context(LttvTracesetContext *self)
422{
ffd54a90 423 return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
dc877563 424}
425
426
ba576a78 427static LttvTracefileContext *
dc877563 428new_tracefile_context(LttvTracesetContext *self)
429{
ffd54a90 430 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
dc877563 431}
432
433
434static void
435traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
436{
437 /* Be careful of anything which would not work well with shallow copies */
438}
439
440
441static void
442traceset_context_finalize (LttvTracesetContext *self)
443{
b445142a 444 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
445 ->finalize(G_OBJECT(self));
dc877563 446}
447
448
449static void
450traceset_context_class_init (LttvTracesetContextClass *klass)
451{
452 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
453
ffd54a90 454 gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
dc877563 455 klass->init = init;
456 klass->fini = fini;
457 klass->new_traceset_context = new_traceset_context;
458 klass->new_trace_context = new_trace_context;
459 klass->new_tracefile_context = new_tracefile_context;
460}
461
462
463GType
ffd54a90 464lttv_traceset_context_get_type(void)
dc877563 465{
466 static GType type = 0;
467 if (type == 0) {
468 static const GTypeInfo info = {
ffd54a90 469 sizeof (LttvTracesetContextClass),
dc877563 470 NULL, /* base_init */
471 NULL, /* base_finalize */
ffd54a90 472 (GClassInitFunc) traceset_context_class_init, /* class_init */
dc877563 473 NULL, /* class_finalize */
474 NULL, /* class_data */
ffd54a90 475 sizeof (LttvTracesetContext),
dc877563 476 0, /* n_preallocs */
ffd54a90 477 (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
dc877563 478 };
479
ffd54a90 480 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType",
dc877563 481 &info, 0);
482 }
483 return type;
484}
485
486
487static void
488trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
489{
490 /* Be careful of anything which would not work well with shallow copies */
491}
492
493
494static void
495trace_context_finalize (LttvTraceContext *self)
496{
b445142a 497 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
498 finalize(G_OBJECT(self));
dc877563 499}
500
501
502static void
503trace_context_class_init (LttvTraceContextClass *klass)
504{
505 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
506
ffd54a90 507 gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
dc877563 508}
509
510
511GType
ffd54a90 512lttv_trace_context_get_type(void)
dc877563 513{
514 static GType type = 0;
515 if (type == 0) {
516 static const GTypeInfo info = {
ffd54a90 517 sizeof (LttvTraceContextClass),
dc877563 518 NULL, /* base_init */
519 NULL, /* base_finalize */
ffd54a90 520 (GClassInitFunc) trace_context_class_init, /* class_init */
dc877563 521 NULL, /* class_finalize */
522 NULL, /* class_data */
c6bc9cb9 523 sizeof (LttvTraceContext),
dc877563 524 0, /* n_preallocs */
ffd54a90 525 (GInstanceInitFunc) trace_context_instance_init /* instance_init */
dc877563 526 };
527
ffd54a90 528 type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType",
dc877563 529 &info, 0);
530 }
531 return type;
532}
533
534
535static void
536tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
537{
538 /* Be careful of anything which would not work well with shallow copies */
539}
540
541
542static void
543tracefile_context_finalize (LttvTracefileContext *self)
544{
b445142a 545 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
546 ->finalize(G_OBJECT(self));
dc877563 547}
548
549
550static void
551tracefile_context_class_init (LttvTracefileContextClass *klass)
552{
553 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
554
ffd54a90 555 gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
556}
557
558
559GType
560lttv_tracefile_context_get_type(void)
561{
562 static GType type = 0;
563 if (type == 0) {
564 static const GTypeInfo info = {
565 sizeof (LttvTracefileContextClass),
566 NULL, /* base_init */
567 NULL, /* base_finalize */
568 (GClassInitFunc) tracefile_context_class_init, /* class_init */
569 NULL, /* class_finalize */
570 NULL, /* class_data */
571 sizeof (LttvTracefileContext),
572 0, /* n_preallocs */
573 (GInstanceInitFunc) tracefile_context_instance_init /* instance_init */
574 };
575
576 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType",
577 &info, 0);
578 }
579 return type;
dc877563 580}
581
582
ffd54a90 583gint compare_tracefile(gconstpointer a, gconstpointer b)
dc877563 584{
308711e5 585 return ltt_time_compare(*((LttTime *)a), *((LttTime *)b));
dc877563 586}
587
588
589gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
590 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
591 return TRUE;
592}
593
594
2a2fa4f0 595void lttv_process_traceset_begin(LttvTracesetContext *self, LttTime end)
dc877563 596{
2a2fa4f0 597 guint i, j, nbi, nbj, nb_control, nb_cpu;
dc877563 598
599 LttvTraceContext *tc;
600
dc877563 601 LttvTracefileContext *tfc;
602
dc877563 603 /* Call all before_traceset, before_trace, and before_tracefile hooks.
604 For all qualifying tracefiles, seek to the start time, create a context,
605 read one event and insert in the pqueue based on the event time. */
606
308711e5 607 lttv_hooks_call(self->before, self);
608 nbi = lttv_traceset_number(self->ts);
2a2fa4f0 609 self->pqueue = g_tree_new(compare_tracefile);
dc877563 610
611 for(i = 0 ; i < nbi ; i++) {
308711e5 612 tc = self->traces[i];
dc877563 613
614 if(!lttv_hooks_call_check(tc->check, tc)) {
dc877563 615 lttv_hooks_call(tc->before, tc);
2a2fa4f0 616 nb_control = ltt_trace_control_tracefile_number(tc->t);
617 nb_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
dc877563 618 nbj = nb_control + nb_cpu;
619
620 for(j = 0 ; j < nbj ; j++) {
621 if(j < nb_control) {
622 tfc = tc->control_tracefiles[j];
623 }
624 else {
625 tfc = tc->per_cpu_tracefiles[j - nb_control];
626 }
627
dc877563 628 if(!lttv_hooks_call_check(tfc->check, tfc)) {
dc877563 629 lttv_hooks_call(tfc->before, tfc);
630
a8c0f09d 631 if(tfc->e != NULL) {
632 if(tfc->timestamp.tv_sec < end.tv_sec ||
633 (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec)){
2a2fa4f0 634 g_tree_insert(self->pqueue, &(tfc->timestamp), tfc);
a8c0f09d 635 }
dc877563 636 }
637 }
638 }
639 }
640 }
2a2fa4f0 641}
642
643
644guint lttv_process_traceset_middle(LttvTracesetContext *self, LttTime end,
645 unsigned nb_events)
646{
647 GTree *pqueue = self->pqueue;
648
649 guint id;
650
651 LttvTraceContext *tc;
652
653 LttvTracefileContext *tfc;
654
655 LttEvent *event;
656
657 unsigned count = 0;
658
659 LttTime previous_timestamp = {0, 0};
dc877563 660
661 /* Get the next event from the pqueue, call its hooks,
662 reinsert in the pqueue the following event from the same tracefile
663 unless the tracefile is finished or the event is later than the
664 start time. */
665
ffd54a90 666 while(TRUE) {
dc877563 667 tfc = NULL;
668 g_tree_foreach(pqueue, get_first, &tfc);
2a2fa4f0 669 if(tfc == NULL) return count;
dc877563 670
308711e5 671 /* Have we reached the maximum number of events specified? However,
672 continue for all the events with the same time stamp (CHECK?). Then,
673 empty the queue and break from the loop. */
dc877563 674
2a2fa4f0 675 if(count >= nb_events &&
676 ltt_time_compare(tfc->timestamp, previous_timestamp) != 0)
677 return count;
678
308711e5 679 previous_timestamp = tfc->timestamp;
680
681
682 /* Get the tracefile with an event for the smallest time found. If two
683 or more tracefiles have events for the same time, hope that lookup
684 and remove are consistent. */
270e7cc5 685
ffd54a90 686 tfc = g_tree_lookup(pqueue, &(tfc->timestamp));
687 g_tree_remove(pqueue, &(tfc->timestamp));
2a2fa4f0 688 count++;
dc877563 689
b445142a 690 if(!lttv_hooks_call(tfc->check_event, tfc)) {
cbe7c836 691 id = ltt_event_eventtype_id(tfc->e);
dc877563 692 lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
60b53e4f 693 lttv_hooks_call(tfc->before_event, tfc);
dc877563 694 lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
60b53e4f 695 lttv_hooks_call(tfc->after_event, tfc);
dc877563 696 }
697
698 event = ltt_tracefile_read(tfc->tf);
699 if(event != NULL) {
700 tfc->e = event;
ffd54a90 701 tfc->timestamp = ltt_event_time(event);
270e7cc5 702 if(tfc->timestamp.tv_sec < end.tv_sec ||
703 (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec))
704 g_tree_insert(pqueue, &(tfc->timestamp), tfc);
dc877563 705 }
706 }
2a2fa4f0 707}
708
709
710void lttv_process_traceset_end(LttvTracesetContext *self)
711{
712 guint i, j, nbi, nbj, nb_control, nb_cpu;
713
714 LttvTraceContext *tc;
715
716 LttvTracefileContext *tfc;
717
718 /* Call all after_traceset, after_trace, and after_tracefile hooks. */
dc877563 719
2a2fa4f0 720 nbi = lttv_traceset_number(self->ts);
dc877563 721
2a2fa4f0 722 for(i = 0 ; i < nbi ; i++) {
723 tc = self->traces[i];
dc877563 724
2a2fa4f0 725 /* The check hooks are called again to avoid memorizing the results
726 obtained at the beginning. CHECK if it poses a problem */
727
728 if(!lttv_hooks_call_check(tc->check, tc)) {
729 nb_control = ltt_trace_control_tracefile_number(tc->t);
730 nb_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
731 nbj = nb_control + nb_cpu;
732
733 for(j = 0 ; j < nbj ; j++) {
734 if(j < nb_control) {
735 tfc = tc->control_tracefiles[j];
736 }
737 else {
738 tfc = tc->per_cpu_tracefiles[j - nb_control];
739 }
740
741 if(!lttv_hooks_call_check(tfc->check, tfc)) {
742 lttv_hooks_call(tfc->after, tfc);
743 }
dc877563 744 }
2a2fa4f0 745 lttv_hooks_call(tc->after, tc);
dc877563 746 }
dc877563 747 }
308711e5 748 lttv_hooks_call(self->after, self);
dc877563 749
2a2fa4f0 750 /* Empty and free the pqueue */
dc877563 751
2a2fa4f0 752 while(TRUE){
753 tfc = NULL;
754 g_tree_foreach(self->pqueue, get_first, &tfc);
755 if(tfc == NULL) break;
756 g_tree_remove(self->pqueue, &(tfc->timestamp));
757 }
758 g_tree_destroy(self->pqueue);
759}
760
761
762void lttv_process_traceset(LttvTracesetContext *self, LttTime end,
763 unsigned nb_events)
764{
765 lttv_process_traceset_begin(self, end);
766 lttv_process_traceset_middle(self, end, nb_events);
767 lttv_process_traceset_end(self);
dc877563 768}
b445142a 769
308711e5 770
771void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
772{
773 guint i, nb_control, nb_per_cpu, nb_tracefile;
774
775 LttvTracefileContext *tfc;
776
777 LttEvent *event;
778
779 nb_control = ltt_trace_control_tracefile_number(self->t);
780 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->t);
781 nb_tracefile = nb_control + nb_per_cpu;
782 for(i = 0 ; i < nb_tracefile ; i++) {
783 if(i < nb_control) tfc = self->control_tracefiles[i];
784 else tfc = self->per_cpu_tracefiles[i - nb_control];
785
786 ltt_tracefile_seek_time(tfc->tf, start);
787 event = ltt_tracefile_read(tfc->tf);
788 tfc->e = event;
789 if(event != NULL) tfc->timestamp = ltt_event_time(event);
790 }
791}
792
793
794void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
795{
796 guint i, nb_trace;
797
798 LttvTraceContext *tc;
799
800 nb_trace = lttv_traceset_number(self->ts);
801 for(i = 0 ; i < nb_trace ; i++) {
802 tc = self->traces[i];
803 lttv_process_trace_seek_time(tc, start);
804 }
805}
806
807
b445142a 808static LttField *
809find_field(LttEventType *et, const char *field)
810{
811 LttType *t;
812
813 LttField *f;
814
815 guint i, nb;
816
817 char *name;
818
819 if(field == NULL) return NULL;
820
821 f = ltt_eventtype_field(et);
822 t = ltt_eventtype_type(et);
823 g_assert(ltt_type_class(t) == LTT_STRUCT);
824 nb = ltt_type_member_number(t);
825 for(i = 0 ; i < nb ; i++) {
826 ltt_type_member_type(t, i, &name);
827 if(strcmp(name, field) == 0) break;
828 }
829 g_assert(i < nb);
830 return ltt_field_member(f, i);
831}
832
833
834void
835lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type,
836 char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
837{
838 LttFacility *f;
839
840 LttEventType *et;
841
842 guint nb, pos, i;
843
844 char *name;
845
846 nb = ltt_trace_facility_find(t, facility, &pos);
847 if(nb < 1) g_error("No %s facility", facility);
848 f = ltt_trace_facility_get(t, pos);
849 et = ltt_facility_eventtype_get_by_name(f, event_type);
850 if(et == NULL) g_error("Event %s does not exist", event_type);
851
852 th->h = h;
853 th->id = ltt_eventtype_id(et);
854 th->f1 = find_field(et, field1);
855 th->f2 = find_field(et, field2);
856 th->f3 = find_field(et, field3);
857}
858
859
This page took 0.059968 seconds and 4 git commands to generate.