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 trace */
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) */
57 void lttv_context_init(LttvTracesetContext
*self
, LttvTraceset
*ts
)
59 LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->init(self
, ts
);
63 void lttv_context_fini(LttvTracesetContext
*self
)
65 LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->fini(self
);
70 lttv_context_new_traceset_context(LttvTracesetContext
*self
)
72 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_traceset_context(self
);
79 lttv_context_new_trace_context(LttvTracesetContext
*self
)
81 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_trace_context(self
);
85 LttvTracefileContext
*
86 lttv_context_new_tracefile_context(LttvTracesetContext
*self
)
88 return LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_tracefile_context(self
);
91 /****************************************************************************
92 * lttv_traceset_context_compute_time_span
94 * Keep the time span is sync with on the fly addition and removal of traces
95 * in a trace set. It must be called each time a trace is added/removed from
96 * the traceset. It could be more efficient to call it only once a bunch
97 * of traces are loaded, but the calculation is not long, so it's not
100 * Author : Xang Xiu Yang
101 ***************************************************************************/
102 static void lttv_traceset_context_compute_time_span(
103 LttvTracesetContext
*self
,
104 TimeInterval
*time_span
)
106 LttvTraceset
* traceset
= self
->ts
;
107 int numTraces
= lttv_traceset_number(traceset
);
110 LttvTraceContext
*tc
;
113 time_span
->start_time
.tv_sec
= 0;
114 time_span
->start_time
.tv_nsec
= 0;
115 time_span
->end_time
.tv_sec
= 0;
116 time_span
->end_time
.tv_nsec
= 0;
118 for(i
=0; i
<numTraces
;i
++){
119 tc
= self
->traces
[i
];
122 ltt_trace_time_span_get(trace
, &s
, &e
);
125 time_span
->start_time
= s
;
126 time_span
->end_time
= e
;
128 if(s
.tv_sec
< time_span
->start_time
.tv_sec
129 || (s
.tv_sec
== time_span
->start_time
.tv_sec
130 && s
.tv_nsec
< time_span
->start_time
.tv_nsec
))
131 time_span
->start_time
= s
;
132 if(e
.tv_sec
> time_span
->end_time
.tv_sec
133 || (e
.tv_sec
== time_span
->end_time
.tv_sec
134 && e
.tv_nsec
> time_span
->end_time
.tv_nsec
))
135 time_span
->end_time
= e
;
142 init(LttvTracesetContext
*self
, LttvTraceset
*ts
)
144 guint i
, j
, nb_trace
, nb_control
, nb_per_cpu
, nb_tracefile
;
146 LttvTraceContext
*tc
;
148 LttvTracefileContext
*tfc
;
150 LttTime null_time
= {0, 0};
152 nb_trace
= lttv_traceset_number(ts
);
154 self
->traces
= g_new(LttvTraceContext
*, nb_trace
);
155 self
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
156 self
->ts_a
= lttv_traceset_attribute(ts
);
157 for(i
= 0 ; i
< nb_trace
; i
++) {
158 tc
= LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_trace_context(self
);
159 self
->traces
[i
] = tc
;
161 tc
->ts_context
= self
;
163 tc
->vt
= lttv_traceset_get(ts
, i
);
164 tc
->t
= lttv_trace(tc
->vt
);
165 tc
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
166 tc
->t_a
= lttv_trace_attribute(tc
->vt
);
167 nb_control
= ltt_trace_control_tracefile_number(tc
->t
);
168 nb_per_cpu
= ltt_trace_per_cpu_tracefile_number(tc
->t
);
169 nb_tracefile
= nb_control
+ nb_per_cpu
;
170 tc
->tracefiles
= g_new(LttvTracefileContext
*, nb_tracefile
);
172 for(j
= 0 ; j
< nb_tracefile
; j
++) {
173 tfc
= LTTV_TRACESET_CONTEXT_GET_CLASS(self
)->new_tracefile_context(self
);
174 tc
->tracefiles
[j
] = tfc
;
179 tfc
->tf
= ltt_trace_control_tracefile_get(tc
->t
, j
);
182 tfc
->control
= FALSE
;
183 tfc
->tf
= ltt_trace_per_cpu_tracefile_get(tc
->t
, j
- nb_control
);
186 tfc
->event
= lttv_hooks_new();
187 tfc
->event_by_id
= lttv_hooks_by_id_new();
188 tfc
->a
= g_object_new(LTTV_ATTRIBUTE_TYPE
, NULL
);
191 lttv_process_traceset_seek_time(self
, null_time
);
192 lttv_traceset_context_compute_time_span(self
, &self
->time_span
);
194 self
->pqueue
= g_tree_new(compare_tracefile
);
198 void fini(LttvTracesetContext
*self
)
200 guint i
, j
, nb_trace
, nb_tracefile
;
202 LttvTraceContext
*tc
;
204 LttvTracefileContext
*tfc
;
206 LttvTraceset
*ts
= self
->ts
;
210 g_tree_destroy(self
->pqueue
);
211 g_object_unref(self
->a
);
213 nb_trace
= lttv_traceset_number(ts
);
215 for(i
= 0 ; i
< nb_trace
; i
++) {
216 tc
= self
->traces
[i
];
218 g_object_unref(tc
->a
);
220 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
221 ltt_trace_per_cpu_tracefile_number(tc
->t
);
223 for(j
= 0 ; j
< nb_tracefile
; j
++) {
224 tfc
= tc
->tracefiles
[j
];
225 lttv_hooks_destroy(tfc
->event
);
226 lttv_hooks_by_id_destroy(tfc
->event_by_id
);
227 g_object_unref(tfc
->a
);
230 g_free(tc
->tracefiles
);
233 g_free(self
->traces
);
237 void lttv_traceset_context_add_hooks(LttvTracesetContext
*self
,
238 LttvHooks
*before_traceset
,
239 LttvHooks
*before_trace
,
240 LttvHooks
*before_tracefile
,
242 LttvHooksById
*event_by_id
)
244 LttvTraceset
*ts
= self
->ts
;
248 LttvTraceContext
*tc
;
250 lttv_hooks_call(before_traceset
, self
);
252 nb_trace
= lttv_traceset_number(ts
);
254 for(i
= 0 ; i
< nb_trace
; i
++) {
255 tc
= self
->traces
[i
];
256 lttv_trace_context_add_hooks(tc
,
265 void lttv_traceset_context_remove_hooks(LttvTracesetContext
*self
,
266 LttvHooks
*after_traceset
,
267 LttvHooks
*after_trace
,
268 LttvHooks
*after_tracefile
,
270 LttvHooksById
*event_by_id
)
273 LttvTraceset
*ts
= self
->ts
;
277 LttvTraceContext
*tc
;
279 nb_trace
= lttv_traceset_number(ts
);
281 for(i
= 0 ; i
< nb_trace
; i
++) {
282 tc
= self
->traces
[i
];
283 lttv_trace_context_remove_hooks(tc
,
290 lttv_hooks_call(after_traceset
, self
);
295 void lttv_trace_context_add_hooks(LttvTraceContext
*self
,
296 LttvHooks
*before_trace
,
297 LttvHooks
*before_tracefile
,
299 LttvHooksById
*event_by_id
)
301 guint i
, nb_tracefile
;
303 LttvTracefileContext
*tfc
;
305 lttv_hooks_call(before_trace
, self
);
306 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
307 ltt_trace_per_cpu_tracefile_number(self
->t
);
309 for(i
= 0 ; i
< nb_tracefile
; i
++) {
310 tfc
= self
->tracefiles
[i
];
311 lttv_tracefile_context_add_hooks(tfc
,
320 void lttv_trace_context_remove_hooks(LttvTraceContext
*self
,
321 LttvHooks
*after_trace
,
322 LttvHooks
*after_tracefile
,
324 LttvHooksById
*event_by_id
)
326 guint i
, nb_tracefile
;
328 LttvTracefileContext
*tfc
;
330 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
331 ltt_trace_per_cpu_tracefile_number(self
->t
);
333 for(i
= 0 ; i
< nb_tracefile
; i
++) {
334 tfc
= self
->tracefiles
[i
];
335 lttv_tracefile_context_remove_hooks(tfc
,
341 lttv_hooks_call(after_trace
, self
);
344 void lttv_tracefile_context_add_hooks(LttvTracefileContext
*self
,
345 LttvHooks
*before_tracefile
,
347 LttvHooksById
*event_by_id
)
353 lttv_hooks_call(before_tracefile
, self
);
354 lttv_hooks_add_list(self
->event
, event
);
355 if(event_by_id
!= NULL
)
356 for(i
= 0; i
< lttv_hooks_by_id_max_id(event_by_id
); i
++) {
357 hook
= lttv_hooks_by_id_get(self
->event_by_id
, i
);
359 lttv_hooks_remove_list(hook
, lttv_hooks_by_id_get(event_by_id
, i
));
364 void lttv_tracefile_context_remove_hooks(LttvTracefileContext
*self
,
365 LttvHooks
*after_tracefile
,
367 LttvHooksById
*event_by_id
)
374 lttv_hooks_remove_list(self
->event
, event
);
375 if(event_by_id
!= NULL
)
376 for(i
= 0; i
< lttv_hooks_by_id_max_id(event_by_id
); i
++) {
377 hook
= lttv_hooks_by_id_find(self
->event_by_id
, i
);
378 lttv_hooks_add_list(hook
, lttv_hooks_by_id_get(event_by_id
, i
));
381 lttv_hooks_call(after_tracefile
, self
);
386 void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext
*tfc
,
388 LttvHooks
*event_by_id
)
391 h
= lttv_hooks_by_id_find(tfc
->event_by_id
, i
);
392 lttv_hooks_add_list(h
, event_by_id
);
395 void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext
*tfc
,
398 lttv_hooks_by_id_remove(tfc
->event_by_id
, i
);
401 static LttvTracesetContext
*
402 new_traceset_context(LttvTracesetContext
*self
)
404 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE
, NULL
);
408 static LttvTraceContext
*
409 new_trace_context(LttvTracesetContext
*self
)
411 return g_object_new(LTTV_TRACE_CONTEXT_TYPE
, NULL
);
415 static LttvTracefileContext
*
416 new_tracefile_context(LttvTracesetContext
*self
)
418 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE
, NULL
);
423 traceset_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
425 /* Be careful of anything which would not work well with shallow copies */
430 traceset_context_finalize (LttvTracesetContext
*self
)
432 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE
)))
433 ->finalize(G_OBJECT(self
));
438 traceset_context_class_init (LttvTracesetContextClass
*klass
)
440 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
442 gobject_class
->finalize
= (void (*)(GObject
*self
))traceset_context_finalize
;
445 klass
->new_traceset_context
= new_traceset_context
;
446 klass
->new_trace_context
= new_trace_context
;
447 klass
->new_tracefile_context
= new_tracefile_context
;
452 lttv_traceset_context_get_type(void)
454 static GType type
= 0;
456 static const GTypeInfo info
= {
457 sizeof (LttvTracesetContextClass
),
458 NULL
, /* base_init */
459 NULL
, /* base_finalize */
460 (GClassInitFunc
) traceset_context_class_init
, /* class_init */
461 NULL
, /* class_finalize */
462 NULL
, /* class_data */
463 sizeof (LttvTracesetContext
),
465 (GInstanceInitFunc
) traceset_context_instance_init
/* instance_init */
468 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracesetContextType",
476 trace_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
478 /* Be careful of anything which would not work well with shallow copies */
483 trace_context_finalize (LttvTraceContext
*self
)
485 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE
)))->
486 finalize(G_OBJECT(self
));
491 trace_context_class_init (LttvTraceContextClass
*klass
)
493 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
495 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_context_finalize
;
500 lttv_trace_context_get_type(void)
502 static GType type
= 0;
504 static const GTypeInfo info
= {
505 sizeof (LttvTraceContextClass
),
506 NULL
, /* base_init */
507 NULL
, /* base_finalize */
508 (GClassInitFunc
) trace_context_class_init
, /* class_init */
509 NULL
, /* class_finalize */
510 NULL
, /* class_data */
511 sizeof (LttvTraceContext
),
513 (GInstanceInitFunc
) trace_context_instance_init
/* instance_init */
516 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTraceContextType",
524 tracefile_context_instance_init (GTypeInstance
*instance
, gpointer g_class
)
526 /* Be careful of anything which would not work well with shallow copies */
531 tracefile_context_finalize (LttvTracefileContext
*self
)
533 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE
)))
534 ->finalize(G_OBJECT(self
));
539 tracefile_context_class_init (LttvTracefileContextClass
*klass
)
541 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
543 gobject_class
->finalize
= (void (*)(GObject
*self
))tracefile_context_finalize
;
548 lttv_tracefile_context_get_type(void)
550 static GType type
= 0;
552 static const GTypeInfo info
= {
553 sizeof (LttvTracefileContextClass
),
554 NULL
, /* base_init */
555 NULL
, /* base_finalize */
556 (GClassInitFunc
) tracefile_context_class_init
, /* class_init */
557 NULL
, /* class_finalize */
558 NULL
, /* class_data */
559 sizeof (LttvTracefileContext
),
561 (GInstanceInitFunc
) tracefile_context_instance_init
/* instance_init */
564 type
= g_type_register_static (G_TYPE_OBJECT
, "LttvTracefileContextType",
572 gboolean
get_first(gpointer key
, gpointer value
, gpointer user_data
) {
573 *((LttvTracefileContext
**)user_data
) = (LttvTracefileContext
*)value
;
579 void lttv_process_traceset_begin(LttvTracesetContext
*self
,
580 LttvHooks
*before_traceset
,
581 LttvHooks
*before_trace
,
582 LttvHooks
*before_tracefile
,
584 LttvHooksById
*event_by_id
)
587 /* simply add hooks in context. _before hooks are called by add_hooks. */
588 /* It calls all before_traceset, before_trace, and before_tracefile hooks. */
589 lttv_traceset_context_add_hooks(self
,
598 /* Note : a _middle must be preceded from a _seek or another middle */
599 guint
lttv_process_traceset_middle(LttvTracesetContext
*self
,
602 const LttvTracesetContextPosition
*end_position
)
604 GTree
*pqueue
= self
->pqueue
;
608 LttvTracefileContext
*tfc
;
614 gboolean last_ret
= FALSE
; /* return value of the last hook list called */
616 /* Get the next event from the pqueue, call its hooks,
617 reinsert in the pqueue the following event from the same tracefile
618 unless the tracefile is finished or the event is later than the
623 g_tree_foreach(pqueue
, get_first
, &tfc
);
624 /* End of traceset : tfc is NULL */
631 * - the maximum number of events specified?
632 * - the end position ?
634 * then the read is finished. We leave the queue in the same state and
638 if(last_ret
== TRUE
||
639 count
>= nb_events
||
640 (end_position
!=NULL
)?FALSE
:lttv_traceset_context_ctx_pos_compare(self
,
641 end_position
) >= 0 ||
642 ltt_time_compare(tfc
->timestamp
, end
) >= 0)
647 /* Get the tracefile with an event for the smallest time found. If two
648 or more tracefiles have events for the same time, hope that lookup
649 and remove are consistent. */
651 g_tree_remove(pqueue
, tfc
);
654 id
= ltt_event_eventtype_id(tfc
->e
);
655 last_ret
= lttv_hooks_call_merge(tfc
->event
, tfc
,
656 lttv_hooks_by_id_get(tfc
->event_by_id
, id
), tfc
);
658 event
= ltt_tracefile_read(tfc
->tf
);
661 tfc
->timestamp
= ltt_event_time(event
);
662 g_tree_insert(pqueue
, tfc
, tfc
);
668 void lttv_process_traceset_end(LttvTracesetContext
*self
,
669 LttvHooks
*after_traceset
,
670 LttvHooks
*after_trace
,
671 LttvHooks
*after_tracefile
,
673 LttvHooksById
*event_by_id
)
675 /* Remove hooks from context. _after hooks are called by remove_hooks. */
676 /* It calls all after_traceset, after_trace, and after_tracefile hooks. */
677 lttv_traceset_context_remove_hooks(self
,
685 void lttv_process_trace_seek_time(LttvTraceContext
*self
, LttTime start
)
687 guint i
, nb_tracefile
;
689 LttvTracefileContext
*tfc
;
693 GTree
*pqueue
= self
->ts_context
->pqueue
;
695 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
696 ltt_trace_per_cpu_tracefile_number(self
->t
);
698 for(i
= 0 ; i
< nb_tracefile
; i
++) {
699 tfc
= self
->tracefiles
[i
];
700 ltt_tracefile_seek_time(tfc
->tf
, start
);
701 g_tree_remove(pqueue
, tfc
);
702 event
= ltt_tracefile_read(tfc
->tf
);
705 tfc
->timestamp
= ltt_event_time(event
);
706 g_tree_insert(pqueue
, tfc
, tfc
);
712 void lttv_process_traceset_seek_time(LttvTracesetContext
*self
, LttTime start
)
716 LttvTraceContext
*tc
;
718 LttvTracefileContext
*tfc
;
720 nb_trace
= lttv_traceset_number(self
->ts
);
721 for(i
= 0 ; i
< nb_trace
; i
++) {
722 tc
= self
->traces
[i
];
723 lttv_process_trace_seek_time(tc
, start
);
728 gboolean
lttv_process_tracefile_seek_position(LttvTracefileContext
*self
,
729 const LttEventPosition
*pos
)
731 LttvTracefileContext
*tfc
= self
;
735 GTree
*pqueue
= self
->t_context
->ts_context
->pqueue
;
737 ltt_tracefile_seek_position(tfc
->tf
, pos
);
738 g_tree_remove(pqueue
, tfc
);
739 event
= ltt_tracefile_read(tfc
->tf
);
742 tfc
->timestamp
= ltt_event_time(event
);
743 g_tree_insert(pqueue
, tfc
, tfc
);
749 gboolean
lttv_process_trace_seek_position(LttvTraceContext
*self
,
750 const LttvTraceContextPosition
*pos
)
752 guint i
, nb_tracefile
;
754 LttvTracefileContext
*tfc
;
758 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
759 ltt_trace_per_cpu_tracefile_number(self
->t
);
761 if(nb_tracefile
!= pos
->nb_tracefile
)
762 return FALSE
; /* Error */
764 for(i
= 0 ; i
< nb_tracefile
; i
++) {
765 tfc
= self
->tracefiles
[i
];
766 lttv_process_tracefile_seek_position(tfc
, pos
->tf_pos
[i
]);
774 gboolean
lttv_process_traceset_seek_position(LttvTracesetContext
*self
,
775 const LttvTracesetContextPosition
*pos
)
778 gboolean sum_ret
= TRUE
;
780 LttvTraceContext
*tc
;
782 LttvTracefileContext
*tfc
;
784 nb_trace
= lttv_traceset_number(self
->ts
);
786 if(nb_trace
!= pos
->nb_trace
)
787 return FALSE
; /* Error */
789 for(i
= 0 ; i
< nb_trace
; i
++) {
790 tc
= self
->traces
[i
];
791 sum_ret
= sum_ret
&& lttv_process_trace_seek_position(tc
, &pos
->t_pos
[i
]);
800 find_field(LttEventType
*et
, const char *field
)
810 if(field
== NULL
) return NULL
;
812 f
= ltt_eventtype_field(et
);
813 t
= ltt_eventtype_type(et
);
814 g_assert(ltt_type_class(t
) == LTT_STRUCT
);
815 nb
= ltt_type_member_number(t
);
816 for(i
= 0 ; i
< nb
; i
++) {
817 ltt_type_member_type(t
, i
, &name
);
818 if(strcmp(name
, field
) == 0) break;
821 return ltt_field_member(f
, i
);
826 lttv_trace_find_hook(LttTrace
*t
, char *facility
, char *event_type
,
827 char *field1
, char *field2
, char *field3
, LttvHook h
, LttvTraceHook
*th
)
837 nb
= ltt_trace_facility_find(t
, facility
, &pos
);
838 if(nb
< 1) g_error("No %s facility", facility
);
839 f
= ltt_trace_facility_get(t
, pos
);
840 et
= ltt_facility_eventtype_get_by_name(f
, event_type
);
841 if(et
== NULL
) g_error("Event %s does not exist", event_type
);
844 th
->id
= ltt_eventtype_id(et
);
845 th
->f1
= find_field(et
, field1
);
846 th
->f2
= find_field(et
, field2
);
847 th
->f3
= find_field(et
, field3
);
851 void lttv_traceset_context_position_save(const LttvTracesetContext
*self
,
852 LttvTracesetContextPosition
*pos
)
854 guint nb_trace
, nb_tracefile
;
855 guint iter_trace
, iter_tracefile
;
857 LttvTraceContext
*tc
;
859 LttvTracefileContext
*tfc
;
863 pos
->nb_trace
= nb_trace
= lttv_traceset_number(self
->ts
);
864 pos
->t_pos
= g_new(LttvTraceContextPosition
, nb_trace
);
866 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
867 tc
= self
->traces
[iter_trace
];
868 pos
->t_pos
[iter_trace
].nb_tracefile
= nb_tracefile
=
869 ltt_trace_control_tracefile_number(tc
->t
) +
870 ltt_trace_per_cpu_tracefile_number(tc
->t
);
872 pos
->t_pos
[iter_trace
].tf_pos
= g_new(LttEventPosition
*, nb_tracefile
);
873 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
874 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]
875 = ltt_event_position_new();
876 tfc
= tc
->tracefiles
[iter_tracefile
];
878 ltt_event_position(event
,
879 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
884 void lttv_traceset_context_position_destroy(LttvTracesetContextPosition
*pos
)
886 guint nb_trace
, nb_tracefile
;
887 guint iter_trace
, iter_tracefile
;
889 nb_trace
= pos
->nb_trace
;
891 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
892 for(iter_tracefile
= 0; iter_tracefile
<
893 pos
->t_pos
[iter_trace
].nb_tracefile
;
896 g_free(pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
898 g_free(pos
->t_pos
[iter_trace
].tf_pos
);
904 gint
lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext
*self
,
905 const LttvTracesetContextPosition
*pos
)
907 guint nb_trace
, nb_tracefile
;
908 guint iter_trace
, iter_tracefile
;
911 LttvTraceContext
*tc
;
913 LttvTracefileContext
*tfc
;
917 nb_trace
= lttv_traceset_number(self
->ts
);
919 if(pos
->nb_trace
!= nb_trace
)
920 g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match.");
922 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
923 tc
= self
->traces
[iter_trace
];
924 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
925 ltt_trace_per_cpu_tracefile_number(tc
->t
);
927 if(pos
->t_pos
[iter_trace
].nb_tracefile
!= nb_tracefile
)
928 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
930 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
931 tfc
= tc
->tracefiles
[iter_tracefile
];
935 ltt_event_event_position_compare(event
,
936 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
])
945 gint
lttv_traceset_context_pos_pos_compare(
946 const LttvTracesetContextPosition
*pos1
,
947 const LttvTracesetContextPosition
*pos2
)
949 guint nb_trace
, nb_tracefile
;
950 guint iter_trace
, iter_tracefile
;
954 nb_trace
= pos1
->nb_trace
;
955 if(nb_trace
!= pos2
->nb_trace
)
956 g_error("lttv_traceset_context_pos_pos_compare : nb_trace does not match.");
958 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
960 nb_tracefile
= pos1
->t_pos
[iter_trace
].nb_tracefile
;
961 if(nb_tracefile
!= pos2
->t_pos
[iter_trace
].nb_tracefile
)
962 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
964 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
966 ltt_event_position_compare(
967 pos1
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
],
968 pos2
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
])