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
.startTime
.tv_sec
= 0;
114 time_span
.startTime
.tv_nsec
= 0;
115 time_span
.endTime
.tv_sec
= 0;
116 time_span
.endTime
.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
.startTime
= s
;
126 time_span
.endTime
= e
;
128 if(s
.tv_sec
< time_span
.startTime
.tv_sec
129 || (s
.tv_sec
== time_span
.startTime
.tv_sec
130 && s
.tv_nsec
< time_span
.startTime
.tv_nsec
))
131 time_span
.startTime
= s
;
132 if(e
.tv_sec
> time_span
.endTime
.tv_sec
133 || (e
.tv_sec
== time_span
.endTime
.tv_sec
134 && e
.tv_nsec
> time_span
.endTime
.tv_nsec
))
135 time_span
.endTime
= 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
);
195 self
->pqueue
= g_tree_new(compare_tracefile
);
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
;
580 void lttv_process_traceset_begin(LttvTracesetContext
*self
,
581 LttvHooks
*before_traceset
,
582 LttvHooks
*before_trace
,
583 LttvHooks
*before_tracefile
,
585 LttvHooksById
*event_by_id
)
588 /* simply add hooks in context. _before hooks are called by add_hooks. */
589 /* It calls all before_traceset, before_trace, and before_tracefile hooks. */
590 lttv_traceset_context_add_hooks(self
,
599 /* Note : a _middle must be preceded from a _seek or another middle */
600 guint
lttv_process_traceset_middle(LttvTracesetContext
*self
,
603 const LttvTracesetContextPosition
*end_position
)
605 GTree
*pqueue
= self
->pqueue
;
609 LttvTracefileContext
*tfc
;
615 gboolean last_ret
= FALSE
; /* return value of the last hook list called */
617 /* Get the next event from the pqueue, call its hooks,
618 reinsert in the pqueue the following event from the same tracefile
619 unless the tracefile is finished or the event is later than the
624 g_tree_foreach(pqueue
, get_first
, &tfc
);
632 * - the maximum number of events specified?
633 * - the end position ?
635 * then the read is finished. We leave the queue in the same state and
639 if(last_ret
== TRUE
||
640 count
>= nb_events
||
641 lttv_traceset_context_ctx_pos_compare(self
,
642 end_position
) >= 0 ||
643 ltt_time_compare(tfc
->timestamp
, end
) >= 0)
649 /* Get the tracefile with an event for the smallest time found. If two
650 or more tracefiles have events for the same time, hope that lookup
651 and remove are consistent. */
653 g_tree_remove(pqueue
, tfc
);
656 id
= ltt_event_eventtype_id(tfc
->e
);
657 last_ret
= lttv_hooks_call_merge(tfc
->event
, tfc
,
658 lttv_hooks_by_id_get(tfc
->event_by_id
, id
), tfc
);
660 event
= ltt_tracefile_read(tfc
->tf
);
663 tfc
->timestamp
= ltt_event_time(event
);
664 if(tfc
->timestamp
.tv_sec
< end
.tv_sec
||
665 (tfc
->timestamp
.tv_sec
== end
.tv_sec
&&
666 tfc
->timestamp
.tv_nsec
<= end
.tv_nsec
))
667 g_tree_insert(pqueue
, tfc
, tfc
);
673 void lttv_process_traceset_end(LttvTracesetContext
*self
,
674 LttvHooks
*after_traceset
,
675 LttvHooks
*after_trace
,
676 LttvHooks
*after_tracefile
,
678 LttvHooksById
*event_by_id
)
680 /* Remove hooks from context. _after hooks are called by remove_hooks. */
681 /* It calls all after_traceset, after_trace, and after_tracefile hooks. */
682 lttv_traceset_context_remove_hooks(self
,
690 void lttv_process_trace_seek_time(LttvTraceContext
*self
, LttTime start
)
692 guint i
, nb_tracefile
;
694 LttvTracefileContext
*tfc
;
698 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
699 ltt_trace_per_cpu_tracefile_number(self
->t
);
701 for(i
= 0 ; i
< nb_tracefile
; i
++) {
702 tfc
= self
->tracefiles
[i
];
703 ltt_tracefile_seek_time(tfc
->tf
, start
);
704 event
= ltt_tracefile_read(tfc
->tf
);
707 tfc
->timestamp
= ltt_event_time(event
);
708 g_tree_insert(self
->ts_context
->pqueue
, tfc
, tfc
);
714 void lttv_process_traceset_seek_time(LttvTracesetContext
*self
, LttTime start
)
718 LttvTraceContext
*tc
;
720 LttvTracefileContext
*tfc
;
722 /* Empty the pqueue */
726 g_tree_foreach(self
->pqueue
, get_first
, &tfc
);
727 if(tfc
== NULL
) break;
728 g_tree_remove(self
->pqueue
, &(tfc
->timestamp
));
731 nb_trace
= lttv_traceset_number(self
->ts
);
732 for(i
= 0 ; i
< nb_trace
; i
++) {
733 tc
= self
->traces
[i
];
734 lttv_process_trace_seek_time(tc
, start
);
739 gboolean
lttv_process_trace_seek_position(LttvTraceContext
*self
,
740 const LttvTraceContextPosition
*pos
)
742 guint i
, nb_tracefile
;
744 LttvTracefileContext
*tfc
;
748 nb_tracefile
= ltt_trace_control_tracefile_number(self
->t
) +
749 ltt_trace_per_cpu_tracefile_number(self
->t
);
751 if(nb_tracefile
!= pos
->nb_tracefile
)
752 return FALSE
; /* Error */
754 for(i
= 0 ; i
< nb_tracefile
; i
++) {
755 tfc
= self
->tracefiles
[i
];
756 ltt_tracefile_seek_position(tfc
->tf
, pos
->tf_pos
[i
]);
757 event
= ltt_tracefile_read(tfc
->tf
);
760 tfc
->timestamp
= ltt_event_time(event
);
761 g_tree_insert(self
->ts_context
->pqueue
, tfc
, tfc
);
770 gboolean
lttv_process_traceset_seek_position(LttvTracesetContext
*self
,
771 const LttvTracesetContextPosition
*pos
)
774 gboolean sum_ret
= TRUE
;
776 LttvTraceContext
*tc
;
778 LttvTracefileContext
*tfc
;
780 nb_trace
= lttv_traceset_number(self
->ts
);
782 if(nb_trace
!= pos
->nb_trace
)
783 return FALSE
; /* Error */
785 /* Empty the pqueue */
789 g_tree_foreach(self
->pqueue
, get_first
, &tfc
);
790 if(tfc
== NULL
) break;
791 g_tree_remove(self
->pqueue
, &(tfc
->timestamp
));
794 for(i
= 0 ; i
< nb_trace
; i
++) {
795 tc
= self
->traces
[i
];
796 sum_ret
= sum_ret
&& lttv_process_trace_seek_position(tc
, &pos
->t_pos
[i
]);
805 find_field(LttEventType
*et
, const char *field
)
815 if(field
== NULL
) return NULL
;
817 f
= ltt_eventtype_field(et
);
818 t
= ltt_eventtype_type(et
);
819 g_assert(ltt_type_class(t
) == LTT_STRUCT
);
820 nb
= ltt_type_member_number(t
);
821 for(i
= 0 ; i
< nb
; i
++) {
822 ltt_type_member_type(t
, i
, &name
);
823 if(strcmp(name
, field
) == 0) break;
826 return ltt_field_member(f
, i
);
831 lttv_trace_find_hook(LttTrace
*t
, char *facility
, char *event_type
,
832 char *field1
, char *field2
, char *field3
, LttvHook h
, LttvTraceHook
*th
)
842 nb
= ltt_trace_facility_find(t
, facility
, &pos
);
843 if(nb
< 1) g_error("No %s facility", facility
);
844 f
= ltt_trace_facility_get(t
, pos
);
845 et
= ltt_facility_eventtype_get_by_name(f
, event_type
);
846 if(et
== NULL
) g_error("Event %s does not exist", event_type
);
849 th
->id
= ltt_eventtype_id(et
);
850 th
->f1
= find_field(et
, field1
);
851 th
->f2
= find_field(et
, field2
);
852 th
->f3
= find_field(et
, field3
);
856 void lttv_traceset_context_position_save(const LttvTracesetContext
*self
,
857 LttvTracesetContextPosition
*pos
)
859 guint nb_trace
, nb_tracefile
;
860 guint iter_trace
, iter_tracefile
;
862 LttvTraceContext
*tc
;
864 LttvTracefileContext
*tfc
;
868 pos
->nb_trace
= nb_trace
= lttv_traceset_number(self
->ts
);
869 pos
->t_pos
= g_new(LttvTraceContextPosition
, nb_trace
);
871 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
872 tc
= self
->traces
[iter_trace
];
873 pos
->t_pos
[iter_trace
].nb_tracefile
= nb_tracefile
=
874 ltt_trace_control_tracefile_number(tc
->t
) +
875 ltt_trace_per_cpu_tracefile_number(tc
->t
);
877 pos
->t_pos
[iter_trace
].tf_pos
= g_new(LttEventPosition
*, nb_tracefile
);
878 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
879 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]
880 = ltt_event_position_new();
881 tfc
= tc
->tracefiles
[iter_tracefile
];
883 ltt_event_position(event
,
884 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
889 void lttv_traceset_context_position_destroy(LttvTracesetContextPosition
*pos
)
891 guint nb_trace
, nb_tracefile
;
892 guint iter_trace
, iter_tracefile
;
894 nb_trace
= pos
->nb_trace
;
896 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
897 for(iter_tracefile
= 0; iter_tracefile
<
898 pos
->t_pos
[iter_trace
].nb_tracefile
;
901 g_free(pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
]);
903 g_free(pos
->t_pos
[iter_trace
].tf_pos
);
909 gint
lttv_traceset_context_ctx_pos_compare(const LttvTracesetContext
*self
,
910 const LttvTracesetContextPosition
*pos
)
912 guint nb_trace
, nb_tracefile
;
913 guint iter_trace
, iter_tracefile
;
916 LttvTraceContext
*tc
;
918 LttvTracefileContext
*tfc
;
922 nb_trace
= lttv_traceset_number(self
->ts
);
924 if(pos
->nb_trace
!= nb_trace
)
925 g_error("lttv_traceset_context_ctx_pos_compare : nb_trace does not match.");
927 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
928 tc
= self
->traces
[iter_trace
];
929 nb_tracefile
= ltt_trace_control_tracefile_number(tc
->t
) +
930 ltt_trace_per_cpu_tracefile_number(tc
->t
);
932 if(pos
->t_pos
[iter_trace
].nb_tracefile
!= nb_tracefile
)
933 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
935 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
936 tfc
= tc
->tracefiles
[iter_tracefile
];
940 ltt_event_event_position_compare(event
,
941 pos
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
])
950 gint
lttv_traceset_context_pos_pos_compare(
951 const LttvTracesetContextPosition
*pos1
,
952 const LttvTracesetContextPosition
*pos2
)
954 guint nb_trace
, nb_tracefile
;
955 guint iter_trace
, iter_tracefile
;
959 nb_trace
= pos1
->nb_trace
;
960 if(nb_trace
!= pos2
->nb_trace
)
961 g_error("lttv_traceset_context_pos_pos_compare : nb_trace does not match.");
963 for(iter_trace
= 0 ; iter_trace
< nb_trace
; iter_trace
++) {
965 nb_tracefile
= pos1
->t_pos
[iter_trace
].nb_tracefile
;
966 if(nb_tracefile
!= pos2
->t_pos
[iter_trace
].nb_tracefile
)
967 g_error("lttv_traceset_context_ctx_pos_compare : nb_tracefile does not match.");
969 for(iter_tracefile
= 0; iter_tracefile
< nb_tracefile
; iter_tracefile
++) {
971 ltt_event_position_compare(
972 pos1
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
],
973 pos2
->t_pos
[iter_trace
].tf_pos
[iter_tracefile
])