1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
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;
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.
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,
20 #include <lttv/processTrace.h>
21 #include <ltt/event.h>
22 #include <ltt/facility.h>
23 #include <ltt/trace.h>
26 void lttv_context_init(LttvTracesetContext
*self
, LttvTraceset
*ts
)
28 LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->init(self
, ts
);
32 void lttv_context_fini(LttvTracesetContext
*self
)
34 LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->fini(self
);
39 lttv_context_new_traceset_context(LttvTracesetContext
*self
)
41 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_traceset_context(self
);
48 lttv_context_new_trace_context(LttvTracesetContext
*self
)
50 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_trace_context(self
);
54 LttvTracefileContext
*
55 lttv_context_new_tracefile_context(LttvTracesetContext
*self
)
57 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_tracefile_context(self
);
60 /****************************************************************************
61 * lttv_traceset_context_compute_time_span
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
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
)
76 LttvTraceset
* traceset
= self
->ts
;
77 int numTraces
= lttv_traceset_number(traceset
);
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;
88 for(i
=0; i
<numTraces
;i
++){
92 ltt_trace_time_span_get(trace
, &s
, &e
);
95 Time_Span
->startTime
= s
;
96 Time_Span
->endTime
= e
;
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
;
112 init(LttvTracesetContext
*self
, LttvTraceset
*ts
)
114 guint i
, j
, nb_trace
, nb_control
, nb_per_cpu
, nb_tracefile
;
116 LttvTraceContext
*tc
;
118 LttvTracefileContext
*tfc
;
120 LttTime null_time
= {0, 0};
122 nb_trace
= lttv_traceset_number(ts
);
124 self
->traces
= g_new(LttvTraceContext
*, nb_trace
);
125 self
->before
= lttv_hooks_new();
126 self
->after
= lttv_hooks_new();
127 self
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
128 self
->ts_a
= lttv_traceset_attribute(ts
);
129 for(i
= 0 ; i
< nb_trace
; i
++) {
130 tc
= LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_trace_context(self
);
131 self
->traces
[i
] = tc
;
133 tc
->ts_context
= self
;
135 tc
->vt
= lttv_traceset_get(ts
, i
);
136 tc
->t
= lttv_trace(tc
->vt
);
137 tc
->check
= lttv_hooks_new();
138 tc
->before
= lttv_hooks_new();
139 tc
->after
= lttv_hooks_new();
140 tc
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
141 tc
->t_a
= lttv_trace_attribute(tc
->vt
);
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
;
145 tc
->tracefiles
= g_new(LttvTracefileContext
*, nb_tracefile
);
147 for(j
= 0 ; j
< nb_tracefile
; j
++) {
148 tfc
= LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_tracefile_context(self
);
149 tc
->tracefiles
[j
] = tfc
;
154 tfc
->tf
= ltt_trace_control_tracefile_get(tc
->t
, j
);
157 tfc
->control
= FALSE
;
158 tfc
->tf
= ltt_trace_per_cpu_tracefile_get(tc
->t
, j
- nb_control
);
161 tfc
->check
= lttv_hooks_new();
162 tfc
->before
= lttv_hooks_new();
163 tfc
->after
= lttv_hooks_new();
164 tfc
->check_event
= lttv_hooks_new();
165 tfc
->before_event
= lttv_hooks_new();
166 tfc
->before_event_by_id
= lttv_hooks_by_id_new();
167 tfc
->after_event
= lttv_hooks_new();
168 tfc
->after_event_by_id
= lttv_hooks_by_id_new();
169 tfc
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
172 lttv_process_traceset_seek_time(self
, null_time
);
173 /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
174 self
->Time_Span
= g_new(TimeInterval
,1);
175 lttv_traceset_context_compute_time_span(self
, self
->Time_Span
);
179 void fini(LttvTracesetContext
*self
)
181 guint i
, j
, nb_trace
, nb_tracefile
;
183 LttvTraceContext
*tc
;
185 LttvTracefileContext
*tfc
;
187 LttvTraceset
*ts
= self
->ts
;
189 g_free(self
->Time_Span
);
191 lttv_hooks_destroy(self
->before
);
192 lttv_hooks_destroy(self
->after
);
194 g_object_unref(self
->a
);
196 nb_trace
= lttv_traceset_number(ts
);
198 for(i
= 0 ; i
< nb_trace
; i
++) {
199 tc
= self
->traces
[i
];
201 lttv_hooks_destroy(tc
->check
);
202 lttv_hooks_destroy(tc
->before
);
203 lttv_hooks_destroy(tc
->after
);
204 g_object_unref(tc
->a
);
206 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
207 ltt_trace_per_cpu_tracefile_number(tc
->t
);
209 for(j
= 0 ; j
< nb_tracefile
; j
++) {
210 tfc
= tc
->tracefiles
[j
];
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
);
222 g_free(tc
->tracefiles
);
225 g_free(self
->traces
);
229 void lttv_traceset_context_add_hooks(LttvTracesetContext
*self
,
230 LttvHooks
*before_traceset
,
231 LttvHooks
*after_traceset
,
232 LttvHooks
*check_trace
,
233 LttvHooks
*before_trace
,
234 LttvHooks
*after_trace
,
235 LttvHooks
*check_tracefile
,
236 LttvHooks
*before_tracefile
,
237 LttvHooks
*after_tracefile
,
238 LttvHooks
*check_event
,
239 LttvHooks
*before_event
,
240 LttvHooks
*after_event
)
242 LttvTraceset
*ts
= self
->ts
;
244 guint i
, j
, nb_trace
, nb_tracefile
;
246 LttvTraceContext
*tc
;
248 LttvTracefileContext
*tfc
;
252 lttv_hooks_add_list(self
->before
, before_traceset
);
253 lttv_hooks_add_list(self
->after
, after_traceset
);
254 nb_trace
= lttv_traceset_number(ts
);
256 for(i
= 0 ; i
< nb_trace
; i
++) {
257 tc
= self
->traces
[i
];
258 lttv_hooks_add_list(tc
->check
, check_trace
);
259 lttv_hooks_add_list(tc
->before
, before_trace
);
260 lttv_hooks_add_list(tc
->after
, after_trace
);
261 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
262 ltt_trace_per_cpu_tracefile_number(tc
->t
);
264 for(j
= 0 ; j
< nb_tracefile
; j
++) {
265 tfc
= tc
->tracefiles
[j
];
266 lttv_hooks_add_list(tfc
->check
, check_tracefile
);
267 lttv_hooks_add_list(tfc
->before
, before_tracefile
);
268 lttv_hooks_add_list(tfc
->after
, after_tracefile
);
269 lttv_hooks_add_list(tfc
->check_event
, check_event
);
270 lttv_hooks_add_list(tfc
->before_event
, before_event
);
271 lttv_hooks_add_list(tfc
->after_event
, after_event
);
277 void lttv_traceset_context_remove_hooks(LttvTracesetContext
*self
,
278 LttvHooks
*before_traceset
,
279 LttvHooks
*after_traceset
,
280 LttvHooks
*check_trace
,
281 LttvHooks
*before_trace
,
282 LttvHooks
*after_trace
,
283 LttvHooks
*check_tracefile
,
284 LttvHooks
*before_tracefile
,
285 LttvHooks
*after_tracefile
,
286 LttvHooks
*check_event
,
287 LttvHooks
*before_event
,
288 LttvHooks
*after_event
)
290 LttvTraceset
*ts
= self
->ts
;
292 guint i
, j
, nb_trace
, nb_tracefile
;
294 LttvTraceContext
*tc
;
296 LttvTracefileContext
*tfc
;
300 lttv_hooks_remove_list(self
->before
, before_traceset
);
301 lttv_hooks_remove_list(self
->after
, after_traceset
);
302 nb_trace
= lttv_traceset_number(ts
);
304 for(i
= 0 ; i
< nb_trace
; i
++) {
305 tc
= self
->traces
[i
];
306 lttv_hooks_remove_list(tc
->check
, check_trace
);
307 lttv_hooks_remove_list(tc
->before
, before_trace
);
308 lttv_hooks_remove_list(tc
->after
, after_trace
);
309 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
310 ltt_trace_per_cpu_tracefile_number(tc
->t
);
312 for(j
= 0 ; j
< nb_tracefile
; j
++) {
313 tfc
= tc
->tracefiles
[j
];
314 lttv_hooks_remove_list(tfc
->check
, check_tracefile
);
315 lttv_hooks_remove_list(tfc
->before
, before_tracefile
);
316 lttv_hooks_remove_list(tfc
->after
, after_tracefile
);
317 lttv_hooks_remove_list(tfc
->check_event
, check_event
);
318 lttv_hooks_remove_list(tfc
->before_event
, before_event
);
319 lttv_hooks_remove_list(tfc
->after_event
, after_event
);
324 void lttv_trace_context_add_hooks(LttvTraceContext
*tc
,
325 LttvHooks
*check_trace
,
326 LttvHooks
*before_trace
,
327 LttvHooks
*after_trace
)
329 lttv_hooks_add_list(tc
->check
, check_trace
);
330 lttv_hooks_add_list(tc
->before
, before_trace
);
331 lttv_hooks_add_list(tc
->after
, after_trace
);
334 void lttv_trace_context_remove_hooks(LttvTraceContext
*tc
,
335 LttvHooks
*check_trace
,
336 LttvHooks
*before_trace
,
337 LttvHooks
*after_trace
)
339 lttv_hooks_remove_list(tc
->check
, check_trace
);
340 lttv_hooks_remove_list(tc
->before
, before_trace
);
341 lttv_hooks_remove_list(tc
->after
, after_trace
);
344 void lttv_tracefile_context_add_hooks(LttvTracefileContext
*tfc
,
345 LttvHooks
*check_tracefile
,
346 LttvHooks
*before_tracefile
,
347 LttvHooks
*after_tracefile
,
348 LttvHooks
*check_event
,
349 LttvHooks
*before_event
,
350 LttvHooks
*after_event
)
352 lttv_hooks_add_list(tfc
->check
, check_tracefile
);
353 lttv_hooks_add_list(tfc
->before
, before_tracefile
);
354 lttv_hooks_add_list(tfc
->after
, after_tracefile
);
355 lttv_hooks_add_list(tfc
->check_event
, check_event
);
356 lttv_hooks_add_list(tfc
->before_event
, before_event
);
357 lttv_hooks_add_list(tfc
->after_event
, after_event
);
360 void lttv_tracefile_context_remove_hooks(LttvTracefileContext
*tfc
,
361 LttvHooks
*check_tracefile
,
362 LttvHooks
*before_tracefile
,
363 LttvHooks
*after_tracefile
,
364 LttvHooks
*check_event
,
365 LttvHooks
*before_event
,
366 LttvHooks
*after_event
)
368 lttv_hooks_remove_list(tfc
->check
, check_tracefile
);
369 lttv_hooks_remove_list(tfc
->before
, before_tracefile
);
370 lttv_hooks_remove_list(tfc
->after
, after_tracefile
);
371 lttv_hooks_remove_list(tfc
->check_event
, check_event
);
372 lttv_hooks_remove_list(tfc
->before_event
, before_event
);
373 lttv_hooks_remove_list(tfc
->after_event
, after_event
);
376 void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext
*tfc
,
378 LttvHooks
*before_event_by_id
,
379 LttvHooks
*after_event_by_id
)
382 h
= lttv_hooks_by_id_find(tfc
->before_event_by_id
, i
);
383 lttv_hooks_add_list(h
, before_event_by_id
);
384 h
= lttv_hooks_by_id_find(tfc
->after_event_by_id
, i
);
385 lttv_hooks_add_list(h
, after_event_by_id
);
388 void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext
*tfc
,
391 lttv_hooks_by_id_remove(tfc
->before_event_by_id
, i
);
392 lttv_hooks_by_id_remove(tfc
->after_event_by_id
, i
);
395 static LttvTracesetContext
*
396 new_traceset_context(LttvTracesetContext
*self
)
398 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE
, NULL
);
402 static LttvTraceContext
*
403 new_trace_context(LttvTracesetContext
*self
)
405 return g_object_new(LTTV_TRACE_CONTEXT_TYPE
, NULL
);
409 static LttvTracefileContext
*
410 new_tracefile_context(LttvTracesetContext
*self
)
412 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE
, NULL
);
417 traceset_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
419 /* Be careful of anything which would not work well with shallow copies */
424 traceset_context_finalize (LttvTracesetContext
*self
)
426 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE
)))
427 ->finalize(G_OBJECT(self
));
432 traceset_context_class_init (LttvTracesetContextClass
*klass
)
434 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
436 gobject_class
->finalize
= (void (*)(GObject
*self
))traceset_context_finalize
;
439 klass
->new_traceset_context
= new_traceset_context
;
440 klass
->new_trace_context
= new_trace_context
;
441 klass
->new_tracefile_context
= new_tracefile_context
;
446 lttv_traceset_context_get_type(void)
448 static GType type
= 0;
450 static const GTypeInfo info
= {
451 sizeof (LttvTracesetContextClass
),
452 NULL
, /* base_init */
453 NULL
, /* base_finalize */
454 (GClassInitFunc
) traceset_context_class_init
, /* class_init */
455 NULL
, /* class_finalize */
456 NULL
, /* class_data */
457 sizeof (LttvTracesetContext
),
459 (GInstanceInitFunc
) traceset_context_instance_init
/* instance_init */
462 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracesetContextType",
470 trace_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
472 /* Be careful of anything which would not work well with shallow copies */
477 trace_context_finalize (LttvTraceContext
*self
)
479 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE
)))->
480 finalize(G_OBJECT(self
));
485 trace_context_class_init (LttvTraceContextClass
*klass
)
487 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
489 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_context_finalize
;
494 lttv_trace_context_get_type(void)
496 static GType type
= 0;
498 static const GTypeInfo info
= {
499 sizeof (LttvTraceContextClass
),
500 NULL
, /* base_init */
501 NULL
, /* base_finalize */
502 (GClassInitFunc
) trace_context_class_init
, /* class_init */
503 NULL
, /* class_finalize */
504 NULL
, /* class_data */
505 sizeof (LttvTraceContext
),
507 (GInstanceInitFunc
) trace_context_instance_init
/* instance_init */
510 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTraceContextType",
518 tracefile_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
520 /* Be careful of anything which would not work well with shallow copies */
525 tracefile_context_finalize (LttvTracefileContext
*self
)
527 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE
)))
528 ->finalize(G_OBJECT(self
));
533 tracefile_context_class_init (LttvTracefileContextClass
*klass
)
535 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
537 gobject_class
->finalize
= (void (*)(GObject
*self
))tracefile_context_finalize
;
542 lttv_tracefile_context_get_type(void)
544 static GType type
= 0;
546 static const GTypeInfo info
= {
547 sizeof (LttvTracefileContextClass
),
548 NULL
, /* base_init */
549 NULL
, /* base_finalize */
550 (GClassInitFunc
) tracefile_context_class_init
, /* class_init */
551 NULL
, /* class_finalize */
552 NULL
, /* class_data */
553 sizeof (LttvTracefileContext
),
555 (GInstanceInitFunc
) tracefile_context_instance_init
/* instance_init */
558 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracefileContextType",
565 gint
compare_tracefile(gconstpointer a
, gconstpointer b
)
567 return ltt_time_compare(*((LttTime
*)a
), *((LttTime
*)b
));
571 gboolean
get_first(gpointer key
, gpointer value
, gpointer user_data
) {
572 *((LttvTracefileContext
**)user_data
) = (LttvTracefileContext
*)value
;
577 void lttv_process_traceset_begin(LttvTracesetContext
*self
, LttTime end
)
579 guint i
, j
, nbi
, nb_tracefile
;
581 LttvTraceContext
*tc
;
583 LttvTracefileContext
*tfc
;
585 /* Call all before_traceset, before_trace, and before_tracefile hooks.
586 For all qualifying tracefiles, seek to the start time, create a context,
587 read one event and insert in the pqueue based on the event time. */
589 lttv_hooks_call(self
->before
, self
);
590 nbi
= lttv_traceset_number(self
->ts
);
591 self
->pqueue
= g_tree_new(compare_tracefile
);
593 for(i
= 0 ; i
< nbi
; i
++) {
594 tc
= self
->traces
[i
];
596 if(!lttv_hooks_call_check(tc
->check
, tc
)) {
597 lttv_hooks_call(tc
->before
, tc
);
598 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
599 ltt_trace_per_cpu_tracefile_number(tc
->t
);
601 for(j
= 0 ; j
< nb_tracefile
; j
++) {
602 tfc
= tc
->tracefiles
[j
];
604 if(!lttv_hooks_call_check(tfc
->check
, tfc
)) {
605 lttv_hooks_call(tfc
->before
, tfc
);
608 if(tfc
->timestamp
.tv_sec
< end
.tv_sec
||
609 (tfc
->timestamp
.tv_sec
== end
.tv_sec
&&
610 tfc
->timestamp
.tv_nsec
<= end
.tv_nsec
)) {
611 g_tree_insert(self
->pqueue
, &(tfc
->timestamp
), tfc
);
621 guint
lttv_process_traceset_middle(LttvTracesetContext
*self
, LttTime end
,
624 GTree
*pqueue
= self
->pqueue
;
628 LttvTraceContext
*tc
;
630 LttvTracefileContext
*tfc
;
636 LttTime previous_timestamp
= {0, 0};
638 /* Get the next event from the pqueue, call its hooks,
639 reinsert in the pqueue the following event from the same tracefile
640 unless the tracefile is finished or the event is later than the
645 g_tree_foreach(pqueue
, get_first
, &tfc
);
646 if(tfc
== NULL
) return count
;
648 /* Have we reached the maximum number of events specified? However,
649 continue for all the events with the same time stamp (CHECK?). Then,
650 empty the queue and break from the loop. */
652 if(count
>= nb_events
&&
653 ltt_time_compare(tfc
->timestamp
, previous_timestamp
) != 0)
656 previous_timestamp
= tfc
->timestamp
;
659 /* Get the tracefile with an event for the smallest time found. If two
660 or more tracefiles have events for the same time, hope that lookup
661 and remove are consistent. */
663 tfc
= g_tree_lookup(pqueue
, &(tfc
->timestamp
));
664 g_tree_remove(pqueue
, &(tfc
->timestamp
));
667 if(!lttv_hooks_call(tfc
->check_event
, tfc
)) {
668 id
= ltt_event_eventtype_id(tfc
->e
);
669 lttv_hooks_call(lttv_hooks_by_id_get(tfc
->before_event_by_id
, id
), tfc
);
670 lttv_hooks_call(tfc
->before_event
, tfc
);
671 lttv_hooks_call(lttv_hooks_by_id_get(tfc
->after_event_by_id
, id
), tfc
);
672 lttv_hooks_call(tfc
->after_event
, tfc
);
675 event
= ltt_tracefile_read(tfc
->tf
);
678 tfc
->timestamp
= ltt_event_time(event
);
679 if(tfc
->timestamp
.tv_sec
< end
.tv_sec
||
680 (tfc
->timestamp
.tv_sec
== end
.tv_sec
&& tfc
->timestamp
.tv_nsec
<= end
.tv_nsec
))
681 g_tree_insert(pqueue
, &(tfc
->timestamp
), tfc
);
687 void lttv_process_traceset_end(LttvTracesetContext
*self
)
689 guint i
, j
, nbi
, nb_tracefile
;
691 LttvTraceContext
*tc
;
693 LttvTracefileContext
*tfc
;
695 /* Call all after_traceset, after_trace, and after_tracefile hooks. */
697 nbi
= lttv_traceset_number(self
->ts
);
699 for(i
= 0 ; i
< nbi
; i
++) {
700 tc
= self
->traces
[i
];
702 /* The check hooks are called again to avoid memorizing the results
703 obtained at the beginning. CHECK if it poses a problem */
705 if(!lttv_hooks_call_check(tc
->check
, tc
)) {
706 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
707 ltt_trace_per_cpu_tracefile_number(tc
->t
);
709 for(j
= 0 ; j
< nb_tracefile
; j
++) {
710 tfc
= tc
->tracefiles
[j
];
712 if(!lttv_hooks_call_check(tfc
->check
, tfc
)) {
713 lttv_hooks_call(tfc
->after
, tfc
);
716 lttv_hooks_call(tc
->after
, tc
);
719 lttv_hooks_call(self
->after
, self
);
721 /* Empty and free the pqueue */
725 g_tree_foreach(self
->pqueue
, get_first
, &tfc
);
726 if(tfc
== NULL
) break;
727 g_tree_remove(self
->pqueue
, &(tfc
->timestamp
));
729 g_tree_destroy(self
->pqueue
);
733 void lttv_process_traceset(LttvTracesetContext
*self
, LttTime end
,
736 lttv_process_traceset_begin(self
, end
);
737 lttv_process_traceset_middle(self
, end
, nb_events
);
738 lttv_process_traceset_end(self
);
742 void lttv_process_trace_seek_time(LttvTraceContext
*self
, LttTime start
)
744 guint i
, nb_tracefile
;
746 LttvTracefileContext
*tfc
;
750 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
751 ltt_trace_per_cpu_tracefile_number(self
->t
);
753 for(i
= 0 ; i
< nb_tracefile
; i
++) {
754 tfc
= self
->tracefiles
[i
];
755 ltt_tracefile_seek_time(tfc
->tf
, start
);
756 event
= ltt_tracefile_read(tfc
->tf
);
758 if(event
!= NULL
) tfc
->timestamp
= ltt_event_time(event
);
763 void lttv_process_traceset_seek_time(LttvTracesetContext
*self
, LttTime start
)
767 LttvTraceContext
*tc
;
769 nb_trace
= lttv_traceset_number(self
->ts
);
770 for(i
= 0 ; i
< nb_trace
; i
++) {
771 tc
= self
->traces
[i
];
772 lttv_process_trace_seek_time(tc
, start
);
778 find_field(LttEventType
*et
, const char *field
)
788 if(field
== NULL
) return NULL
;
790 f
= ltt_eventtype_field(et
);
791 t
= ltt_eventtype_type(et
);
792 g_assert(ltt_type_class(t
) == LTT_STRUCT
);
793 nb
= ltt_type_member_number(t
);
794 for(i
= 0 ; i
< nb
; i
++) {
795 ltt_type_member_type(t
, i
, &name
);
796 if(strcmp(name
, field
) == 0) break;
799 return ltt_field_member(f
, i
);
804 lttv_trace_find_hook(LttTrace
*t
, char *facility
, char *event_type
,
805 char *field1
, char *field2
, char *field3
, LttvHook h
, LttvTraceHook
*th
)
815 nb
= ltt_trace_facility_find(t
, facility
, &pos
);
816 if(nb
< 1) g_error("No %s facility", facility
);
817 f
= ltt_trace_facility_get(t
, pos
);
818 et
= ltt_facility_eventtype_get_by_name(f
, event_type
);
819 if(et
== NULL
) g_error("Event %s does not exist", event_type
);
822 th
->id
= ltt_eventtype_id(et
);
823 th
->f1
= find_field(et
, field1
);
824 th
->f2
= find_field(et
, field2
);
825 th
->f3
= find_field(et
, field3
);