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/tracecontext.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
);
180 void fini(LttvTracesetContext
*self
)
182 guint i
, j
, nb_trace
, nb_tracefile
;
184 LttvTraceContext
*tc
;
186 LttvTracefileContext
*tfc
;
188 LttvTraceset
*ts
= self
->ts
;
190 g_free(self
->Time_Span
);
192 lttv_hooks_destroy(self
->before
);
193 lttv_hooks_destroy(self
->after
);
195 g_object_unref(self
->a
);
197 nb_trace
= lttv_traceset_number(ts
);
199 for(i
= 0 ; i
< nb_trace
; i
++) {
200 tc
= self
->traces
[i
];
202 lttv_hooks_destroy(tc
->check
);
203 lttv_hooks_destroy(tc
->before
);
204 lttv_hooks_destroy(tc
->after
);
205 g_object_unref(tc
->a
);
207 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
208 ltt_trace_per_cpu_tracefile_number(tc
->t
);
210 for(j
= 0 ; j
< nb_tracefile
; j
++) {
211 tfc
= tc
->tracefiles
[j
];
212 lttv_hooks_destroy(tfc
->check
);
213 lttv_hooks_destroy(tfc
->before
);
214 lttv_hooks_destroy(tfc
->after
);
215 lttv_hooks_destroy(tfc
->check_event
);
216 lttv_hooks_destroy(tfc
->before_event
);
217 lttv_hooks_by_id_destroy(tfc
->before_event_by_id
);
218 lttv_hooks_destroy(tfc
->after_event
);
219 lttv_hooks_by_id_destroy(tfc
->after_event_by_id
);
220 g_object_unref(tfc
->a
);
223 g_free(tc
->tracefiles
);
226 g_free(self
->traces
);
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
)
243 LttvTraceset
*ts
= self
->ts
;
245 guint i
, j
, nb_trace
, nb_tracefile
;
247 LttvTraceContext
*tc
;
249 LttvTracefileContext
*tfc
;
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
);
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_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
263 ltt_trace_per_cpu_tracefile_number(tc
->t
);
265 for(j
= 0 ; j
< nb_tracefile
; j
++) {
266 tfc
= tc
->tracefiles
[j
];
267 lttv_hooks_add_list(tfc
->check
, check_tracefile
);
268 lttv_hooks_add_list(tfc
->before
, before_tracefile
);
269 lttv_hooks_add_list(tfc
->after
, after_tracefile
);
270 lttv_hooks_add_list(tfc
->check_event
, check_event
);
271 lttv_hooks_add_list(tfc
->before_event
, before_event
);
272 lttv_hooks_add_list(tfc
->after_event
, after_event
);
278 void lttv_traceset_context_remove_hooks(LttvTracesetContext
*self
,
279 LttvHooks
*before_traceset
,
280 LttvHooks
*after_traceset
,
281 LttvHooks
*check_trace
,
282 LttvHooks
*before_trace
,
283 LttvHooks
*after_trace
,
284 LttvHooks
*check_tracefile
,
285 LttvHooks
*before_tracefile
,
286 LttvHooks
*after_tracefile
,
287 LttvHooks
*check_event
,
288 LttvHooks
*before_event
,
289 LttvHooks
*after_event
)
291 LttvTraceset
*ts
= self
->ts
;
293 guint i
, j
, nb_trace
, nb_tracefile
;
295 LttvTraceContext
*tc
;
297 LttvTracefileContext
*tfc
;
301 lttv_hooks_remove_list(self
->before
, before_traceset
);
302 lttv_hooks_remove_list(self
->after
, after_traceset
);
303 nb_trace
= lttv_traceset_number(ts
);
305 for(i
= 0 ; i
< nb_trace
; i
++) {
306 tc
= self
->traces
[i
];
307 lttv_hooks_remove_list(tc
->check
, check_trace
);
308 lttv_hooks_remove_list(tc
->before
, before_trace
);
309 lttv_hooks_remove_list(tc
->after
, after_trace
);
310 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
311 ltt_trace_per_cpu_tracefile_number(tc
->t
);
313 for(j
= 0 ; j
< nb_tracefile
; j
++) {
314 tfc
= tc
->tracefiles
[j
];
315 lttv_hooks_remove_list(tfc
->check
, check_tracefile
);
316 lttv_hooks_remove_list(tfc
->before
, before_tracefile
);
317 lttv_hooks_remove_list(tfc
->after
, after_tracefile
);
318 lttv_hooks_remove_list(tfc
->check_event
, check_event
);
319 lttv_hooks_remove_list(tfc
->before_event
, before_event
);
320 lttv_hooks_remove_list(tfc
->after_event
, after_event
);
325 void lttv_trace_context_add_hooks(LttvTraceContext
*tc
,
326 LttvHooks
*check_trace
,
327 LttvHooks
*before_trace
,
328 LttvHooks
*after_trace
)
330 lttv_hooks_add_list(tc
->check
, check_trace
);
331 lttv_hooks_add_list(tc
->before
, before_trace
);
332 lttv_hooks_add_list(tc
->after
, after_trace
);
335 void lttv_trace_context_remove_hooks(LttvTraceContext
*tc
,
336 LttvHooks
*check_trace
,
337 LttvHooks
*before_trace
,
338 LttvHooks
*after_trace
)
340 lttv_hooks_remove_list(tc
->check
, check_trace
);
341 lttv_hooks_remove_list(tc
->before
, before_trace
);
342 lttv_hooks_remove_list(tc
->after
, after_trace
);
345 void lttv_tracefile_context_add_hooks(LttvTracefileContext
*tfc
,
346 LttvHooks
*check_tracefile
,
347 LttvHooks
*before_tracefile
,
348 LttvHooks
*after_tracefile
,
349 LttvHooks
*check_event
,
350 LttvHooks
*before_event
,
351 LttvHooks
*after_event
)
353 lttv_hooks_add_list(tfc
->check
, check_tracefile
);
354 lttv_hooks_add_list(tfc
->before
, before_tracefile
);
355 lttv_hooks_add_list(tfc
->after
, after_tracefile
);
356 lttv_hooks_add_list(tfc
->check_event
, check_event
);
357 lttv_hooks_add_list(tfc
->before_event
, before_event
);
358 lttv_hooks_add_list(tfc
->after_event
, after_event
);
361 void lttv_tracefile_context_remove_hooks(LttvTracefileContext
*tfc
,
362 LttvHooks
*check_tracefile
,
363 LttvHooks
*before_tracefile
,
364 LttvHooks
*after_tracefile
,
365 LttvHooks
*check_event
,
366 LttvHooks
*before_event
,
367 LttvHooks
*after_event
)
369 lttv_hooks_remove_list(tfc
->check
, check_tracefile
);
370 lttv_hooks_remove_list(tfc
->before
, before_tracefile
);
371 lttv_hooks_remove_list(tfc
->after
, after_tracefile
);
372 lttv_hooks_remove_list(tfc
->check_event
, check_event
);
373 lttv_hooks_remove_list(tfc
->before_event
, before_event
);
374 lttv_hooks_remove_list(tfc
->after_event
, after_event
);
377 void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext
*tfc
,
379 LttvHooks
*before_event_by_id
,
380 LttvHooks
*after_event_by_id
)
383 h
= lttv_hooks_by_id_find(tfc
->before_event_by_id
, i
);
384 lttv_hooks_add_list(h
, before_event_by_id
);
385 h
= lttv_hooks_by_id_find(tfc
->after_event_by_id
, i
);
386 lttv_hooks_add_list(h
, after_event_by_id
);
389 void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext
*tfc
,
392 lttv_hooks_by_id_remove(tfc
->before_event_by_id
, i
);
393 lttv_hooks_by_id_remove(tfc
->after_event_by_id
, i
);
396 static LttvTracesetContext
*
397 new_traceset_context(LttvTracesetContext
*self
)
399 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE
, NULL
);
403 static LttvTraceContext
*
404 new_trace_context(LttvTracesetContext
*self
)
406 return g_object_new(LTTV_TRACE_CONTEXT_TYPE
, NULL
);
410 static LttvTracefileContext
*
411 new_tracefile_context(LttvTracesetContext
*self
)
413 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE
, NULL
);
418 traceset_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
420 /* Be careful of anything which would not work well with shallow copies */
425 traceset_context_finalize (LttvTracesetContext
*self
)
427 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE
)))
428 ->finalize(G_OBJECT(self
));
433 traceset_context_class_init (LttvTracesetContextClass
*klass
)
435 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
437 gobject_class
->finalize
= (void (*)(GObject
*self
))traceset_context_finalize
;
440 klass
->new_traceset_context
= new_traceset_context
;
441 klass
->new_trace_context
= new_trace_context
;
442 klass
->new_tracefile_context
= new_tracefile_context
;
447 lttv_traceset_context_get_type(void)
449 static GType type
= 0;
451 static const GTypeInfo info
= {
452 sizeof (LttvTracesetContextClass
),
453 NULL
, /* base_init */
454 NULL
, /* base_finalize */
455 (GClassInitFunc
) traceset_context_class_init
, /* class_init */
456 NULL
, /* class_finalize */
457 NULL
, /* class_data */
458 sizeof (LttvTracesetContext
),
460 (GInstanceInitFunc
) traceset_context_instance_init
/* instance_init */
463 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracesetContextType",
471 trace_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
473 /* Be careful of anything which would not work well with shallow copies */
478 trace_context_finalize (LttvTraceContext
*self
)
480 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE
)))->
481 finalize(G_OBJECT(self
));
486 trace_context_class_init (LttvTraceContextClass
*klass
)
488 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
490 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_context_finalize
;
495 lttv_trace_context_get_type(void)
497 static GType type
= 0;
499 static const GTypeInfo info
= {
500 sizeof (LttvTraceContextClass
),
501 NULL
, /* base_init */
502 NULL
, /* base_finalize */
503 (GClassInitFunc
) trace_context_class_init
, /* class_init */
504 NULL
, /* class_finalize */
505 NULL
, /* class_data */
506 sizeof (LttvTraceContext
),
508 (GInstanceInitFunc
) trace_context_instance_init
/* instance_init */
511 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTraceContextType",
519 tracefile_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
521 /* Be careful of anything which would not work well with shallow copies */
526 tracefile_context_finalize (LttvTracefileContext
*self
)
528 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE
)))
529 ->finalize(G_OBJECT(self
));
534 tracefile_context_class_init (LttvTracefileContextClass
*klass
)
536 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
538 gobject_class
->finalize
= (void (*)(GObject
*self
))tracefile_context_finalize
;
543 lttv_tracefile_context_get_type(void)
545 static GType type
= 0;
547 static const GTypeInfo info
= {
548 sizeof (LttvTracefileContextClass
),
549 NULL
, /* base_init */
550 NULL
, /* base_finalize */
551 (GClassInitFunc
) tracefile_context_class_init
, /* class_init */
552 NULL
, /* class_finalize */
553 NULL
, /* class_data */
554 sizeof (LttvTracefileContext
),
556 (GInstanceInitFunc
) tracefile_context_instance_init
/* instance_init */
559 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracefileContextType",
566 gint
compare_tracefile(gconstpointer a
, gconstpointer b
)
570 LttvTracefileContext
*trace_a
= (LttvTracefileContext
*)a
;
572 LttvTracefileContext
*trace_b
= (LttvTracefileContext
*)b
;
574 if(trace_a
== trace_b
) return 0;
575 comparison
= ltt_time_compare(trace_a
->timestamp
, trace_b
->timestamp
);
576 if(comparison
!= 0) return comparison
;
577 if(trace_a
->index
< trace_b
->index
) return -1;
578 else if(trace_a
->index
> trace_b
->index
) return 1;
579 if(trace_a
->t_context
->index
< trace_b
->t_context
->index
) return -1;
580 else if(trace_a
->t_context
->index
> trace_b
->t_context
->index
) return 1;
585 gboolean
get_first(gpointer key
, gpointer value
, gpointer user_data
) {
586 *((LttvTracefileContext
**)user_data
) = (LttvTracefileContext
*)value
;
591 void lttv_process_traceset_begin(LttvTracesetContext
*self
, LttTime end
)
593 guint i
, j
, nbi
, nb_tracefile
;
595 LttvTraceContext
*tc
;
597 LttvTracefileContext
*tfc
;
599 /* Call all before_traceset, before_trace, and before_tracefile hooks.
600 For all qualifying tracefiles, seek to the start time, create a context,
601 read one event and insert in the pqueue based on the event time. */
603 lttv_hooks_call(self
->before
, self
);
604 nbi
= lttv_traceset_number(self
->ts
);
605 self
->pqueue
= g_tree_new(compare_tracefile
);
607 for(i
= 0 ; i
< nbi
; i
++) {
608 tc
= self
->traces
[i
];
610 if(!lttv_hooks_call_check(tc
->check
, tc
)) {
611 lttv_hooks_call(tc
->before
, tc
);
612 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
613 ltt_trace_per_cpu_tracefile_number(tc
->t
);
615 for(j
= 0 ; j
< nb_tracefile
; j
++) {
616 tfc
= tc
->tracefiles
[j
];
618 if(!lttv_hooks_call_check(tfc
->check
, tfc
)) {
619 lttv_hooks_call(tfc
->before
, tfc
);
622 if(tfc
->timestamp
.tv_sec
< end
.tv_sec
||
623 (tfc
->timestamp
.tv_sec
== end
.tv_sec
&&
624 tfc
->timestamp
.tv_nsec
<= end
.tv_nsec
)) {
625 g_tree_insert(self
->pqueue
, tfc
, tfc
);
635 guint
lttv_process_traceset_middle(LttvTracesetContext
*self
, LttTime end
,
638 GTree
*pqueue
= self
->pqueue
;
642 LttvTraceContext
*tc
;
644 LttvTracefileContext
*tfc
;
650 LttTime previous_timestamp
= {0, 0};
652 /* Get the next event from the pqueue, call its hooks,
653 reinsert in the pqueue the following event from the same tracefile
654 unless the tracefile is finished or the event is later than the
659 g_tree_foreach(pqueue
, get_first
, &tfc
);
666 /* Have we reached the maximum number of events specified? However,
667 continue for all the events with the same time stamp (CHECK?). Then,
668 empty the queue and break from the loop. */
670 if(count
>= nb_events
&&
671 ltt_time_compare(tfc
->timestamp
, previous_timestamp
) != 0)
677 previous_timestamp
= tfc
->timestamp
;
680 /* Get the tracefile with an event for the smallest time found. If two
681 or more tracefiles have events for the same time, hope that lookup
682 and remove are consistent. */
684 g_tree_remove(pqueue
, tfc
);
687 if(!lttv_hooks_call(tfc
->check_event
, tfc
)) {
688 id
= ltt_event_eventtype_id(tfc
->e
);
689 lttv_hooks_call(lttv_hooks_by_id_get(tfc
->before_event_by_id
, id
), tfc
);
690 lttv_hooks_call(tfc
->before_event
, tfc
);
691 lttv_hooks_call(lttv_hooks_by_id_get(tfc
->after_event_by_id
, id
), tfc
);
692 lttv_hooks_call(tfc
->after_event
, tfc
);
695 event
= ltt_tracefile_read(tfc
->tf
);
698 tfc
->timestamp
= ltt_event_time(event
);
699 if(tfc
->timestamp
.tv_sec
< end
.tv_sec
||
700 (tfc
->timestamp
.tv_sec
== end
.tv_sec
&& tfc
->timestamp
.tv_nsec
<= end
.tv_nsec
))
701 g_tree_insert(pqueue
, tfc
, tfc
);
707 void lttv_process_traceset_end(LttvTracesetContext
*self
)
709 guint i
, j
, nbi
, nb_tracefile
;
711 LttvTraceContext
*tc
;
713 LttvTracefileContext
*tfc
;
715 /* Call all after_traceset, after_trace, and after_tracefile hooks. */
717 nbi
= lttv_traceset_number(self
->ts
);
719 for(i
= 0 ; i
< nbi
; i
++) {
720 tc
= self
->traces
[i
];
722 /* The check hooks are called again to avoid memorizing the results
723 obtained at the beginning. CHECK if it poses a problem */
725 if(!lttv_hooks_call_check(tc
->check
, tc
)) {
726 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
727 ltt_trace_per_cpu_tracefile_number(tc
->t
);
729 for(j
= 0 ; j
< nb_tracefile
; j
++) {
730 tfc
= tc
->tracefiles
[j
];
732 if(!lttv_hooks_call_check(tfc
->check
, tfc
)) {
733 lttv_hooks_call(tfc
->after
, tfc
);
736 lttv_hooks_call(tc
->after
, tc
);
739 lttv_hooks_call(self
->after
, self
);
741 /* Empty and free the pqueue */
745 g_tree_foreach(self
->pqueue
, get_first
, &tfc
);
746 if(tfc
== NULL
) break;
747 g_tree_remove(self
->pqueue
, &(tfc
->timestamp
));
749 g_tree_destroy(self
->pqueue
);
753 void lttv_process_traceset(LttvTracesetContext
*self
, LttTime end
,
756 lttv_process_traceset_begin(self
, end
);
757 lttv_process_traceset_middle(self
, end
, nb_events
);
758 lttv_process_traceset_end(self
);
762 void lttv_process_trace_seek_time(LttvTraceContext
*self
, LttTime start
)
764 guint i
, nb_tracefile
;
766 LttvTracefileContext
*tfc
;
770 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
771 ltt_trace_per_cpu_tracefile_number(self
->t
);
773 for(i
= 0 ; i
< nb_tracefile
; i
++) {
774 tfc
= self
->tracefiles
[i
];
775 ltt_tracefile_seek_time(tfc
->tf
, start
);
776 event
= ltt_tracefile_read(tfc
->tf
);
778 if(event
!= NULL
) tfc
->timestamp
= ltt_event_time(event
);
783 void lttv_process_traceset_seek_time(LttvTracesetContext
*self
, LttTime start
)
787 LttvTraceContext
*tc
;
789 nb_trace
= lttv_traceset_number(self
->ts
);
790 for(i
= 0 ; i
< nb_trace
; i
++) {
791 tc
= self
->traces
[i
];
792 lttv_process_trace_seek_time(tc
, start
);
798 find_field(LttEventType
*et
, const char *field
)
808 if(field
== NULL
) return NULL
;
810 f
= ltt_eventtype_field(et
);
811 t
= ltt_eventtype_type(et
);
812 g_assert(ltt_type_class(t
) == LTT_STRUCT
);
813 nb
= ltt_type_member_number(t
);
814 for(i
= 0 ; i
< nb
; i
++) {
815 ltt_type_member_type(t
, i
, &name
);
816 if(strcmp(name
, field
) == 0) break;
819 return ltt_field_member(f
, i
);
824 lttv_trace_find_hook(LttTrace
*t
, char *facility
, char *event_type
,
825 char *field1
, char *field2
, char *field3
, LttvHook h
, LttvTraceHook
*th
)
835 nb
= ltt_trace_facility_find(t
, facility
, &pos
);
836 if(nb
< 1) g_error("No %s facility", facility
);
837 f
= ltt_trace_facility_get(t
, pos
);
838 et
= ltt_facility_eventtype_get_by_name(f
, event_type
);
839 if(et
== NULL
) g_error("Event %s does not exist", event_type
);
842 th
->id
= ltt_eventtype_id(et
);
843 th
->f1
= find_field(et
, field1
);
844 th
->f2
= find_field(et
, field2
);
845 th
->f3
= find_field(et
, field3
);