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>
29 gint
compare_tracefile(gconstpointer a
, gconstpointer b
)
33 LttvTracefileContext
*trace_a
= (LttvTracefileContext
*)a
;
35 LttvTracefileContext
*trace_b
= (LttvTracefileContext
*)b
;
37 if(trace_a
== trace_b
) return 0;
38 comparison
= ltt_time_compare(trace_a
->timestamp
, trace_b
->timestamp
);
39 if(comparison
!= 0) return comparison
;
40 if(trace_a
->index
< trace_b
->index
) return -1;
41 else if(trace_a
->index
> trace_b
->index
) return 1;
42 if(trace_a
->t_context
->index
< trace_b
->t_context
->index
) return -1;
43 else if(trace_a
->t_context
->index
> trace_b
->t_context
->index
) return 1;
47 struct _LttvTraceContextPosition
{
48 LttEventPosition
**tf_pos
; /* Position in each tracefile */
49 guint nb_tracefile
; /* Number of tracefiles (check) */
52 struct _LttvTracesetContextPosition
{
53 LttvTraceContextPosition
*t_pos
; /* Position in each trace */
54 guint nb_trace
; /* Number of traces (check) */
55 LttTime timestamp
; /* Current time at the saved position */
58 void lttv_context_init(LttvTracesetContext
*self
, LttvTraceset
*ts
)
60 LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->init(self
, ts
);
64 void lttv_context_fini(LttvTracesetContext
*self
)
66 LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->fini(self
);
71 lttv_context_new_traceset_context(LttvTracesetContext
*self
)
73 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_traceset_context(self
);
80 lttv_context_new_trace_context(LttvTracesetContext
*self
)
82 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_trace_context(self
);
86 LttvTracefileContext
*
87 lttv_context_new_tracefile_context(LttvTracesetContext
*self
)
89 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_tracefile_context(self
);
92 /****************************************************************************
93 * lttv_traceset_context_compute_time_span
95 * Keep the time span is sync with on the fly addition and removal of traces
96 * in a trace set. It must be called each time a trace is added/removed from
97 * the traceset. It could be more efficient to call it only once a bunch
98 * of traces are loaded, but the calculation is not long, so it's not
101 * Author : Xang Xiu Yang
102 ***************************************************************************/
103 static void lttv_traceset_context_compute_time_span(
104 LttvTracesetContext
*self
,
105 TimeInterval
*time_span
)
107 LttvTraceset
* traceset
= self
->ts
;
108 int numTraces
= lttv_traceset_number(traceset
);
111 LttvTraceContext
*tc
;
114 time_span
->start_time
.tv_sec
= 0;
115 time_span
->start_time
.tv_nsec
= 0;
116 time_span
->end_time
.tv_sec
= 0;
117 time_span
->end_time
.tv_nsec
= 0;
119 for(i
=0; i
<numTraces
;i
++){
120 tc
= self
->traces
[i
];
123 ltt_trace_time_span_get(trace
, &s
, &e
);
126 time_span
->start_time
= s
;
127 time_span
->end_time
= e
;
129 if(s
.tv_sec
< time_span
->start_time
.tv_sec
130 || (s
.tv_sec
== time_span
->start_time
.tv_sec
131 && s
.tv_nsec
< time_span
->start_time
.tv_nsec
))
132 time_span
->start_time
= s
;
133 if(e
.tv_sec
> time_span
->end_time
.tv_sec
134 || (e
.tv_sec
== time_span
->end_time
.tv_sec
135 && e
.tv_nsec
> time_span
->end_time
.tv_nsec
))
136 time_span
->end_time
= e
;
143 init(LttvTracesetContext
*self
, LttvTraceset
*ts
)
145 guint i
, j
, nb_trace
, nb_control
, nb_per_cpu
, nb_tracefile
;
147 LttvTraceContext
*tc
;
149 LttvTracefileContext
*tfc
;
151 LttTime null_time
= {0, 0};
153 nb_trace
= lttv_traceset_number(ts
);
155 self
->traces
= g_new(LttvTraceContext
*, nb_trace
);
156 self
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
157 self
->ts_a
= lttv_traceset_attribute(ts
);
158 for(i
= 0 ; i
< nb_trace
; i
++) {
159 tc
= LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_trace_context(self
);
160 self
->traces
[i
] = tc
;
162 tc
->ts_context
= self
;
164 tc
->vt
= lttv_traceset_get(ts
, i
);
165 tc
->t
= lttv_trace(tc
->vt
);
166 tc
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
167 tc
->t_a
= lttv_trace_attribute(tc
->vt
);
168 nb_control
= ltt_trace_control_tracefile_number(tc
->t
);
169 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(tc
->t
);
170 nb_tracefile
= nb_control
+ nb_per_cpu
;
171 tc
->tracefiles
= g_new(LttvTracefileContext
*, nb_tracefile
);
173 for(j
= 0 ; j
< nb_tracefile
; j
++) {
174 tfc
= LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_tracefile_context(self
);
175 tc
->tracefiles
[j
] = tfc
;
180 tfc
->tf
= ltt_trace_control_tracefile_get(tc
->t
, j
);
183 tfc
->control
= FALSE
;
184 tfc
->tf
= ltt_trace_per_cpu_tracefile_get(tc
->t
, j
- nb_control
);
187 tfc
->event
= lttv_hooks_new();
188 tfc
->event_by_id
= lttv_hooks_by_id_new();
189 tfc
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
192 self
->pqueue
= g_tree_new(compare_tracefile
);
193 lttv_process_traceset_seek_time(self
, null_time
);
194 lttv_traceset_context_compute_time_span(self
, &self
->time_span
);
199 void fini(LttvTracesetContext
*self
)
201 guint i
, j
, nb_trace
, nb_tracefile
;
203 LttvTraceContext
*tc
;
205 LttvTracefileContext
*tfc
;
207 LttvTraceset
*ts
= self
->ts
;
211 g_tree_destroy(self
->pqueue
);
212 g_object_unref(self
->a
);
214 nb_trace
= lttv_traceset_number(ts
);
216 for(i
= 0 ; i
< nb_trace
; i
++) {
217 tc
= self
->traces
[i
];
219 g_object_unref(tc
->a
);
221 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
222 ltt_trace_per_cpu_tracefile_number(tc
->t
);
224 for(j
= 0 ; j
< nb_tracefile
; j
++) {
225 tfc
= tc
->tracefiles
[j
];
226 lttv_hooks_destroy(tfc
->event
);
227 lttv_hooks_by_id_destroy(tfc
->event_by_id
);
228 g_object_unref(tfc
->a
);
231 g_free(tc
->tracefiles
);
234 g_free(self
->traces
);
238 void lttv_traceset_context_add_hooks(LttvTracesetContext
*self
,
239 LttvHooks
*before_traceset
,
240 LttvHooks
*before_trace
,
241 LttvHooks
*before_tracefile
,
243 LttvHooksById
*event_by_id
)
245 LttvTraceset
*ts
= self
->ts
;
249 LttvTraceContext
*tc
;
251 lttv_hooks_call(before_traceset
, self
);
253 nb_trace
= lttv_traceset_number(ts
);
255 for(i
= 0 ; i
< nb_trace
; i
++) {
256 tc
= self
->traces
[i
];
257 lttv_trace_context_add_hooks(tc
,
266 void lttv_traceset_context_remove_hooks(LttvTracesetContext
*self
,
267 LttvHooks
*after_traceset
,
268 LttvHooks
*after_trace
,
269 LttvHooks
*after_tracefile
,
271 LttvHooksById
*event_by_id
)
274 LttvTraceset
*ts
= self
->ts
;
278 LttvTraceContext
*tc
;
280 nb_trace
= lttv_traceset_number(ts
);
282 for(i
= 0 ; i
< nb_trace
; i
++) {
283 tc
= self
->traces
[i
];
284 lttv_trace_context_remove_hooks(tc
,
291 lttv_hooks_call(after_traceset
, self
);
296 void lttv_trace_context_add_hooks(LttvTraceContext
*self
,
297 LttvHooks
*before_trace
,
298 LttvHooks
*before_tracefile
,
300 LttvHooksById
*event_by_id
)
302 guint i
, nb_tracefile
;
304 LttvTracefileContext
*tfc
;
306 lttv_hooks_call(before_trace
, self
);
307 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
308 ltt_trace_per_cpu_tracefile_number(self
->t
);
310 for(i
= 0 ; i
< nb_tracefile
; i
++) {
311 tfc
= self
->tracefiles
[i
];
312 lttv_tracefile_context_add_hooks(tfc
,
321 void lttv_trace_context_remove_hooks(LttvTraceContext
*self
,
322 LttvHooks
*after_trace
,
323 LttvHooks
*after_tracefile
,
325 LttvHooksById
*event_by_id
)
327 guint i
, nb_tracefile
;
329 LttvTracefileContext
*tfc
;
331 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
332 ltt_trace_per_cpu_tracefile_number(self
->t
);
334 for(i
= 0 ; i
< nb_tracefile
; i
++) {
335 tfc
= self
->tracefiles
[i
];
336 lttv_tracefile_context_remove_hooks(tfc
,
342 lttv_hooks_call(after_trace
, self
);
345 void lttv_tracefile_context_add_hooks(LttvTracefileContext
*self
,
346 LttvHooks
*before_tracefile
,
348 LttvHooksById
*event_by_id
)
354 lttv_hooks_call(before_tracefile
, self
);
355 lttv_hooks_add_list(self
->event
, event
);
356 if(event_by_id
!= NULL
)
357 for(i
= 0; i
< lttv_hooks_by_id_max_id(event_by_id
); i
++) {
358 hook
= lttv_hooks_by_id_get(self
->event_by_id
, i
);
360 lttv_hooks_remove_list(hook
, lttv_hooks_by_id_get(event_by_id
, i
));
365 void lttv_tracefile_context_remove_hooks(LttvTracefileContext
*self
,
366 LttvHooks
*after_tracefile
,
368 LttvHooksById
*event_by_id
)
375 lttv_hooks_remove_list(self
->event
, event
);
376 if(event_by_id
!= NULL
)
377 for(i
= 0; i
< lttv_hooks_by_id_max_id(event_by_id
); i
++) {
378 hook
= lttv_hooks_by_id_find(self
->event_by_id
, i
);
379 lttv_hooks_add_list(hook
, lttv_hooks_by_id_get(event_by_id
, i
));
382 lttv_hooks_call(after_tracefile
, self
);
387 void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext
*tfc
,
389 LttvHooks
*event_by_id
)
392 h
= lttv_hooks_by_id_find(tfc
->event_by_id
, i
);
393 lttv_hooks_add_list(h
, event_by_id
);
396 void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext
*tfc
,
399 lttv_hooks_by_id_remove(tfc
->event_by_id
, i
);
402 static LttvTracesetContext
*
403 new_traceset_context(LttvTracesetContext
*self
)
405 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE
, NULL
);
409 static LttvTraceContext
*
410 new_trace_context(LttvTracesetContext
*self
)
412 return g_object_new(LTTV_TRACE_CONTEXT_TYPE
, NULL
);
416 static LttvTracefileContext
*
417 new_tracefile_context(LttvTracesetContext
*self
)
419 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE
, NULL
);
424 traceset_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
426 /* Be careful of anything which would not work well with shallow copies */
431 traceset_context_finalize (LttvTracesetContext
*self
)
433 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE
)))
434 ->finalize(G_OBJECT(self
));
439 traceset_context_class_init (LttvTracesetContextClass
*klass
)
441 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
443 gobject_class
->finalize
= (void (*)(GObject
*self
))traceset_context_finalize
;
446 klass
->new_traceset_context
= new_traceset_context
;
447 klass
->new_trace_context
= new_trace_context
;
448 klass
->new_tracefile_context
= new_tracefile_context
;
453 lttv_traceset_context_get_type(void)
455 static GType type
= 0;
457 static const GTypeInfo info
= {
458 sizeof (LttvTracesetContextClass
),
459 NULL
, /* base_init */
460 NULL
, /* base_finalize */
461 (GClassInitFunc
) traceset_context_class_init
, /* class_init */
462 NULL
, /* class_finalize */
463 NULL
, /* class_data */
464 sizeof (LttvTracesetContext
),
466 (GInstanceInitFunc
) traceset_context_instance_init
/* instance_init */
469 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracesetContextType",
477 trace_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
479 /* Be careful of anything which would not work well with shallow copies */
484 trace_context_finalize (LttvTraceContext
*self
)
486 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE
)))->
487 finalize(G_OBJECT(self
));
492 trace_context_class_init (LttvTraceContextClass
*klass
)
494 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
496 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_context_finalize
;
501 lttv_trace_context_get_type(void)
503 static GType type
= 0;
505 static const GTypeInfo info
= {
506 sizeof (LttvTraceContextClass
),
507 NULL
, /* base_init */
508 NULL
, /* base_finalize */
509 (GClassInitFunc
) trace_context_class_init
, /* class_init */
510 NULL
, /* class_finalize */
511 NULL
, /* class_data */
512 sizeof (LttvTraceContext
),
514 (GInstanceInitFunc
) trace_context_instance_init
/* instance_init */
517 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTraceContextType",
525 tracefile_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
527 /* Be careful of anything which would not work well with shallow copies */
532 tracefile_context_finalize (LttvTracefileContext
*self
)
534 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE
)))
535 ->finalize(G_OBJECT(self
));
540 tracefile_context_class_init (LttvTracefileContextClass
*klass
)
542 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
544 gobject_class
->finalize
= (void (*)(GObject
*self
))tracefile_context_finalize
;
549 lttv_tracefile_context_get_type(void)
551 static GType type
= 0;
553 static const GTypeInfo info
= {
554 sizeof (LttvTracefileContextClass
),
555 NULL
, /* base_init */
556 NULL
, /* base_finalize */
557 (GClassInitFunc
) tracefile_context_class_init
, /* class_init */
558 NULL
, /* class_finalize */
559 NULL
, /* class_data */
560 sizeof (LttvTracefileContext
),
562 (GInstanceInitFunc
) tracefile_context_instance_init
/* instance_init */
565 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracefileContextType",
573 gboolean
get_first(gpointer key
, gpointer value
, gpointer user_data
) {
574 *((LttvTracefileContext
**)user_data
) = (LttvTracefileContext
*)value
;
579 /* Put all the tracefiles at the tracefile context position */
580 void lttv_process_traceset_synchronize_tracefiles(LttvTracesetContext
*self
)
582 guint iter_trace
, nb_trace
;
584 LttvTraceContext
*tc
;
586 nb_trace
= lttv_traceset_number(self
->ts
);
588 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
589 tc
= self
->traces
[iter_trace
];
592 guint iter_tf
, nb_tracefile
;
594 LttvTracefileContext
*tfc
;
596 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
597 ltt_trace_per_cpu_tracefile_number(tc
->t
);
599 for(iter_tf
= 0 ; iter_tf
< nb_tracefile
; iter_tf
++) {
600 tfc
= tc
->tracefiles
[iter_tf
];
603 //ltt_tracefile_copy(tfc->tf_sync_data, tfc->tf);
604 LttEventPosition
*ep
= ltt_event_position_new();
606 ltt_event_position(tfc
->e
, ep
);
608 ltt_tracefile_seek_position(tfc
->tf
, ep
);
618 void lttv_process_traceset_begin(LttvTracesetContext
*self
,
619 LttvHooks
*before_traceset
,
620 LttvHooks
*before_trace
,
621 LttvHooks
*before_tracefile
,
623 LttvHooksById
*event_by_id
)
626 /* simply add hooks in context. _before hooks are called by add_hooks. */
627 /* It calls all before_traceset, before_trace, and before_tracefile hooks. */
628 lttv_traceset_context_add_hooks(self
,
637 /* Note : a _middle must be preceded from a _seek or another middle */
638 guint
lttv_process_traceset_middle(LttvTracesetContext
*self
,
641 const LttvTracesetContextPosition
*end_position
)
643 GTree
*pqueue
= self
->pqueue
;
647 LttvTracefileContext
*tfc
;
653 gboolean last_ret
= FALSE
; /* return value of the last hook list called */
655 /* Get the next event from the pqueue, call its hooks,
656 reinsert in the pqueue the following event from the same tracefile
657 unless the tracefile is finished or the event is later than the
662 g_tree_foreach(pqueue
, get_first
, &tfc
);
663 /* End of traceset : tfc is NULL */
670 * - the maximum number of events specified?
671 * - the end position ?
673 * then the read is finished. We leave the queue in the same state and
677 if(last_ret
== TRUE
||
678 count
>= nb_events
||
679 (end_position
!=NULL
&<tv_traceset_context_ctx_pos_compare(self
,
680 end_position
) == 0)||
681 ltt_time_compare(tfc
->timestamp
, end
) >= 0)
686 /* Get the tracefile with an event for the smallest time found. If two
687 or more tracefiles have events for the same time, hope that lookup
688 and remove are consistent. */
690 g_tree_remove(pqueue
, tfc
);
693 id
= ltt_event_eventtype_id(tfc
->e
);
694 last_ret
= lttv_hooks_call_merge(tfc
->event
, tfc
,
695 lttv_hooks_by_id_get(tfc
->event_by_id
, id
), tfc
);
697 event
= ltt_tracefile_read(tfc
->tf
);
700 tfc
->timestamp
= ltt_event_time(event
);
701 g_tree_insert(pqueue
, tfc
, tfc
);
707 void lttv_process_traceset_end(LttvTracesetContext
*self
,
708 LttvHooks
*after_traceset
,
709 LttvHooks
*after_trace
,
710 LttvHooks
*after_tracefile
,
712 LttvHooksById
*event_by_id
)
714 /* Remove hooks from context. _after hooks are called by remove_hooks. */
715 /* It calls all after_traceset, after_trace, and after_tracefile hooks. */
716 lttv_traceset_context_remove_hooks(self
,
724 void lttv_process_trace_seek_time(LttvTraceContext
*self
, LttTime start
)
726 guint i
, nb_tracefile
;
728 LttvTracefileContext
*tfc
;
732 GTree
*pqueue
= self
->ts_context
->pqueue
;
734 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
735 ltt_trace_per_cpu_tracefile_number(self
->t
);
737 for(i
= 0 ; i
< nb_tracefile
; i
++) {
738 tfc
= self
->tracefiles
[i
];
739 ltt_tracefile_seek_time(tfc
->tf
, start
);
740 g_tree_remove(pqueue
, tfc
);
741 event
= ltt_tracefile_read(tfc
->tf
);
744 tfc
->timestamp
= ltt_event_time(event
);
745 g_tree_insert(pqueue
, tfc
, tfc
);
751 void lttv_process_traceset_seek_time(LttvTracesetContext
*self
, LttTime start
)
755 LttvTraceContext
*tc
;
757 LttvTracefileContext
*tfc
;
759 nb_trace
= lttv_traceset_number(self
->ts
);
760 for(i
= 0 ; i
< nb_trace
; i
++) {
761 tc
= self
->traces
[i
];
762 lttv_process_trace_seek_time(tc
, start
);
767 gboolean
lttv_process_tracefile_seek_position(LttvTracefileContext
*self
,
768 const LttEventPosition
*pos
)
770 LttvTracefileContext
*tfc
= self
;
774 GTree
*pqueue
= self
->t_context
->ts_context
->pqueue
;
776 ltt_tracefile_seek_position(tfc
->tf
, pos
);
777 g_tree_remove(pqueue
, tfc
);
778 event
= ltt_tracefile_read(tfc
->tf
);
781 tfc
->timestamp
= ltt_event_time(event
);
782 g_tree_insert(pqueue
, tfc
, tfc
);
788 gboolean
lttv_process_trace_seek_position(LttvTraceContext
*self
,
789 const LttvTraceContextPosition
*pos
)
791 guint i
, nb_tracefile
;
793 LttvTracefileContext
*tfc
;
797 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
798 ltt_trace_per_cpu_tracefile_number(self
->t
);
800 if(nb_tracefile
!= pos
->nb_tracefile
)
801 return FALSE
; /* Error */
803 for(i
= 0 ; i
< nb_tracefile
; i
++) {
804 tfc
= self
->tracefiles
[i
];
805 lttv_process_tracefile_seek_position(tfc
, pos
->tf_pos
[i
]);
813 gboolean
lttv_process_traceset_seek_position(LttvTracesetContext
*self
,
814 const LttvTracesetContextPosition
*pos
)
817 gboolean sum_ret
= TRUE
;
819 LttvTraceContext
*tc
;
821 LttvTracefileContext
*tfc
;
823 nb_trace
= lttv_traceset_number(self
->ts
);
825 if(nb_trace
!= pos
->nb_trace
)
826 return FALSE
; /* Error */
828 for(i
= 0 ; i
< nb_trace
; i
++) {
829 tc
= self
->traces
[i
];
830 sum_ret
= sum_ret
&& lttv_process_trace_seek_position(tc
, &pos
->t_pos
[i
]);
839 find_field(LttEventType
*et
, const char *field
)
849 if(field
== NULL
) return NULL
;
851 f
= ltt_eventtype_field(et
);
852 t
= ltt_eventtype_type(et
);
853 g_assert(ltt_type_class(t
) == LTT_STRUCT
);
854 nb
= ltt_type_member_number(t
);
855 for(i
= 0 ; i
< nb
; i
++) {
856 ltt_type_member_type(t
, i
, &name
);
857 if(strcmp(name
, field
) == 0) break;
860 return ltt_field_member(f
, i
);
865 lttv_trace_find_hook(LttTrace
*t
, char *facility
, char *event_type
,
866 char *field1
, char *field2
, char *field3
, LttvHook h
, LttvTraceHook
*th
)
876 nb
= ltt_trace_facility_find(t
, facility
, &pos
);
877 if(nb
< 1) g_error("No %s facility", facility
);
878 f
= ltt_trace_facility_get(t
, pos
);
879 et
= ltt_facility_eventtype_get_by_name(f
, event_type
);
880 if(et
== NULL
) g_error("Event %s does not exist", event_type
);
883 th
->id
= ltt_eventtype_id(et
);
884 th
->f1
= find_field(et
, field1
);
885 th
->f2
= find_field(et
, field2
);
886 th
->f3
= find_field(et
, field3
);
890 LttvTracesetContextPosition
*lttv_traceset_context_position_new()
892 return g_new(LttvTracesetContextPosition
,1);
896 void lttv_traceset_context_position_save(const LttvTracesetContext
*self
,
897 LttvTracesetContextPosition
*pos
)
899 guint nb_trace
, nb_tracefile
;
900 guint iter_trace
, iter_tracefile
;
902 LttvTraceContext
*tc
;
904 LttvTracefileContext
*tfc
;
908 LttTime timestamp
= self
->time_span
.end_time
;
910 pos
->nb_trace
= nb_trace
= lttv_traceset_number(self
->ts
);
911 pos
->t_pos
= g_new(LttvTraceContextPosition
, nb_trace
);
913 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
914 tc
= self
->traces
[iter_trace
];
915 pos
->t_pos
[iter_trace
].nb_tracefile
= nb_tracefile
=
916 ltt_trace_control_tracefile_number(tc
->t
) +
917 ltt_trace_per_cpu_tracefile_number(tc
->t
);
919 pos
->t_pos
[iter_trace
].tf_pos
= g_new(LttEventPosition
*, nb_tracefile
);
920 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
921 tfc
= tc
->tracefiles
[iter_tracefile
];
924 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]
925 = ltt_event_position_new();
926 ltt_event_position(event
,
927 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
929 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
] = NULL
;
931 if(ltt_time_compare(tfc
->timestamp
, timestamp
) < 0)
932 timestamp
= tfc
->timestamp
;
935 pos
->timestamp
= timestamp
;
938 void lttv_traceset_context_position_destroy(LttvTracesetContextPosition
*pos
)
940 guint nb_trace
, nb_tracefile
;
941 guint iter_trace
, iter_tracefile
;
943 nb_trace
= pos
->nb_trace
;
945 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
946 for(iter_tracefile
= 0; iter_tracefile
<
947 pos
->t_pos
[iter_trace
].nb_tracefile
;
949 if(pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
] != NULL
)
950 g_free(pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
952 g_free(pos
->t_pos
[iter_trace
].tf_pos
);
958 void lttv_traceset_context_position_copy(LttvTracesetContextPosition
*dest
,
959 const LttvTracesetContextPosition
*src
)
961 guint nb_trace
, nb_tracefile
;
962 guint iter_trace
, iter_tracefile
;
964 nb_trace
= dest
->nb_trace
= src
->nb_trace
;
965 dest
->t_pos
= g_new(LttvTraceContextPosition
, nb_trace
);
967 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
969 nb_tracefile
= dest
->t_pos
[iter_trace
].nb_tracefile
=
970 src
->t_pos
[iter_trace
].nb_tracefile
;
972 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
973 dest
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
] =
974 ltt_event_position_new();
975 if(src
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
] != NULL
)
976 ltt_event_position_copy(
977 dest
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
],
978 src
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
980 dest
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
] = NULL
;
984 dest
->timestamp
= src
->timestamp
;
987 gint
lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext
*self
,
988 const LttvTracesetContextPosition
*pos
)
990 guint nb_trace
, nb_tracefile
;
991 guint iter_trace
, iter_tracefile
;
994 LttvTraceContext
*tc
;
996 LttvTracefileContext
*tfc
;
1000 nb_trace
= lttv_traceset_number(self
->ts
);
1002 if(pos
->nb_trace
!= nb_trace
)
1003 g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match.");
1005 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
1006 tc
= self
->traces
[iter_trace
];
1007 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
1008 ltt_trace_per_cpu_tracefile_number(tc
->t
);
1010 if(pos
->t_pos
[iter_trace
].nb_tracefile
!= nb_tracefile
)
1011 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
1013 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
1014 tfc
= tc
->tracefiles
[iter_tracefile
];
1018 ltt_event_event_position_compare(event
,
1019 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
])
1028 gint
lttv_traceset_context_pos_pos_compare(
1029 const LttvTracesetContextPosition
*pos1
,
1030 const LttvTracesetContextPosition
*pos2
)
1032 guint nb_trace
, nb_tracefile
;
1033 guint iter_trace
, iter_tracefile
;
1037 nb_trace
= pos1
->nb_trace
;
1038 if(nb_trace
!= pos2
->nb_trace
)
1039 g_error("lttv_traceset_context_pos_pos_compare : nb_trace does not match.");
1041 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
1043 nb_tracefile
= pos1
->t_pos
[iter_trace
].nb_tracefile
;
1044 if(nb_tracefile
!= pos2
->t_pos
[iter_trace
].nb_tracefile
)
1045 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
1047 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
1049 ltt_event_position_compare(
1050 pos1
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
],
1051 pos2
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
])
1060 LttTime
lttv_traceset_context_position_get_time(
1061 const LttvTracesetContextPosition
*pos
)
1063 return pos
->timestamp
;
1067 LttvTracefileContext
*lttv_traceset_context_get_current_tfc(LttvTracesetContext
*self
)
1069 GTree
*pqueue
= self
->pqueue
;
1070 LttvTracefileContext
*tfc
= NULL
;
1072 g_tree_foreach(pqueue
, get_first
, &tfc
);