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