1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
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,
28 #include <asm/types.h>
33 #include "ltt-private.h"
34 #include <ltt/event.h>
35 #include <ltt/trace.h>
36 #include <ltt/ltt-types.h>
40 void compute_fields_offsets(LttTracefile
*tf
, LttField
*field
, off_t
*offset
,
46 LttEvent
*ltt_event_new()
48 return g_new(LttEvent
, 1);
51 void ltt_event_destroy(LttEvent
*event
)
58 /* Use get_field_type_size instead */
59 /*****************************************************************************
61 * ltt_event_refresh_fields : refresh fields of an event
63 * offsetRoot : offset from the root
64 * offsetParent : offset from the parent
67 * reverse_byte_order : 1 or 0
69 * int : size of the field
70 ****************************************************************************/
72 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
73 LttField
* fld
, void *evD
, gboolean reverse_byte_order
)
75 int size
, size1
, element_number
, i
, offset1
, offset2
;
76 LttType
* type
= fld
->field_type
;
78 switch(type
->type_class
) {
80 element_number
= (int) type
->element_number
;
81 if(fld
->field_fixed
== 0){// has string or sequence
83 for(i
=0;i
<element_number
;i
++){
84 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
85 fld
->child
[0], evD
+size
, reverse_byte_order
);
87 }else size
= fld
->field_size
;
91 size1
= fld
->sequ_number_size
;
92 element_number
= getIntNumber(reverse_byte_order
,size1
,evD
);
93 type
->element_number
= element_number
;
94 if(fld
->element_size
> 0){
95 size
= element_number
* fld
->element_size
;
96 }else{//sequence has string or sequence
98 for(i
=0;i
<element_number
;i
++){
99 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
100 fld
->child
[0], evD
+size
+size1
, reverse_byte_order
);
107 size
= strlen((gchar
*)evD
) + 1; //include end : '\0'
111 element_number
= (int) type
->element_number
;
112 if(fld
->field_fixed
== 0){
113 offset1
= offsetRoot
;
115 for(i
=0;i
<element_number
;i
++){
116 size
=ltt_event_refresh_fields(offset1
,offset2
,
117 fld
->child
[i
],evD
+offset2
, reverse_byte_order
);
122 }else size
= fld
->field_size
;
126 size
= fld
->field_size
;
130 size
= fld
->field_size
;
134 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
135 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
136 size
= fld
->field_size
;
137 }else if(type
->type_class
== LTT_ARRAY
){
138 element_number
= (int) type
->element_number
;
139 if(fld
->field_fixed
== 0){// has string or sequence
141 for(i
=0;i
<element_number
;i
++){
142 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
143 fld
->child
[0], evD
+size
);
145 }else size
= fld
->field_size
;
146 }else if(type
->type_class
== LTT_SEQUENCE
){
147 size1
= fld
->sequ_number_size
;
148 element_number
= getIntNumber(size1
,evD
);
149 type
->element_number
= element_number
;
150 if(fld
->element_size
> 0){
151 size
= element_number
* fld
->element_size
;
152 }else{//sequence has string or sequence
154 for(i
=0;i
<element_number
;i
++){
155 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
156 fld
->child
[0], evD
+size
+size1
);
160 }else if(type
->type_class
== LTT_STRING
){
161 size
= strlen((char*)evD
) + 1; //include end : '\0'
162 }else if(type
->type_class
== LTT_STRUCT
){
163 element_number
= (int) type
->element_number
;
164 if(fld
->field_fixed
== 0){
165 offset1
= offsetRoot
;
167 for(i
=0;i
<element_number
;i
++){
168 size
=ltt_event_refresh_fields(offset1
,offset2
,
169 fld
->child
[i
],evD
+offset2
);
174 }else size
= fld
->field_size
;
177 fld
->offset_root
= offsetRoot
;
178 fld
->offset_parent
= offsetParent
;
179 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
180 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
181 fld
->field_size
= size
;
188 /*****************************************************************************
190 * ltt_event_eventtype_id: get event type id
191 * (base id + position of the event)
193 * e : an instance of an event type
195 * unsigned : event type id
196 ****************************************************************************/
198 unsigned ltt_event_eventtype_id(const LttEvent
*e
)
200 return (unsigned) e
->event_id
;
203 /*****************************************************************************
205 * ltt_event_facility : get the facility of the event
207 * e : an instance of an event type
209 * LttFacility * : the facility of the event
210 ****************************************************************************/
212 LttFacility
*ltt_event_facility(const LttEvent
*e
)
214 LttTrace
* trace
= e
->tracefile
->trace
;
215 unsigned id
= e
->facility_id
;
216 LttFacility
*facility
= ltt_trace_facility_by_id(trace
,id
);
218 g_assert(facility
->exists
);
223 /*****************************************************************************
225 * ltt_event_facility_id : get the facility id of the event
227 * e : an instance of an event type
229 * unsigned : the facility of the event
230 ****************************************************************************/
232 unsigned ltt_event_facility_id(const LttEvent
*e
)
234 return e
->facility_id
;
237 /*****************************************************************************
239 * ltt_event_eventtype : get the event type of the event
241 * e : an instance of an event type
243 * LttEventType * : the event type of the event
244 ****************************************************************************/
246 LttEventType
*ltt_event_eventtype(const LttEvent
*e
)
248 LttFacility
* facility
= ltt_event_facility(e
);
249 if(!facility
) return NULL
;
250 return &g_array_index(facility
->events
, LttEventType
, e
->event_id
);
254 /*****************************************************************************
256 * ltt_event_time : get the time of the event
258 * e : an instance of an event type
260 * LttTime : the time of the event
261 ****************************************************************************/
263 LttTime
ltt_event_time(const LttEvent
*e
)
265 return e
->event_time
;
268 /*****************************************************************************
270 * ltt_event_time : get the cycle count of the event
272 * e : an instance of an event type
274 * LttCycleCount : the cycle count of the event
275 ****************************************************************************/
277 LttCycleCount
ltt_event_cycle_count(const LttEvent
*e
)
284 /*****************************************************************************
286 * ltt_event_position_get : get the event position data
288 * e : an instance of an event type
289 * ep : a pointer to event's position structure
290 * tf : tracefile pointer
291 * block : current block
292 * offset : current offset
294 ****************************************************************************/
295 void ltt_event_position_get(LttEventPosition
*ep
, LttTracefile
**tf
,
296 guint
*block
, guint
*offset
, guint64
*tsc
)
300 *offset
= ep
->offset
;
305 /*****************************************************************************
307 * ltt_event_position : get the event's position
309 * e : an instance of an event type
310 * ep : a pointer to event's position structure
311 ****************************************************************************/
313 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
315 ep
->tracefile
= e
->tracefile
;
316 ep
->block
= e
->block
;
317 ep
->offset
= e
->offset
;
321 LttEventPosition
* ltt_event_position_new()
323 return g_new(LttEventPosition
, 1);
327 /*****************************************************************************
329 * ltt_event_position_compare : compare two positions
330 * A NULL value is infinite.
332 * ep1 : a pointer to event's position structure
333 * ep2 : a pointer to event's position structure
338 ****************************************************************************/
341 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
342 const LttEventPosition
*ep2
)
344 if(ep1
== NULL
&& ep2
== NULL
)
346 if(ep1
!= NULL
&& ep2
== NULL
)
348 if(ep1
== NULL
&& ep2
!= NULL
)
351 if(ep1
->tracefile
!= ep2
->tracefile
)
352 g_error("ltt_event_position_compare on different tracefiles makes no sense");
354 if(ep1
->block
< ep2
->block
)
356 if(ep1
->block
> ep2
->block
)
358 if(ep1
->offset
< ep2
->offset
)
360 if(ep1
->offset
> ep2
->offset
)
365 /*****************************************************************************
367 * ltt_event_position_copy : copy position
369 * src : a pointer to event's position structure source
370 * dest : a pointer to event's position structure dest
373 ****************************************************************************/
374 void ltt_event_position_copy(LttEventPosition
*dest
,
375 const LttEventPosition
*src
)
385 LttTracefile
*ltt_event_position_tracefile(LttEventPosition
*ep
)
387 return ep
->tracefile
;
390 /*****************************************************************************
392 * ltt_event_cpu_i: get the cpu id where the event happens
394 * e : an instance of an event type
396 * unsigned : the cpu id
397 ****************************************************************************/
399 unsigned ltt_event_cpu_id(LttEvent
*e
)
401 return e
->tracefile
->cpu_num
;
404 /*****************************************************************************
406 * ltt_event_data : get the raw data for the event
408 * e : an instance of an event type
410 * void * : pointer to the raw data for the event
411 ****************************************************************************/
413 void *ltt_event_data(LttEvent
*e
)
418 /*****************************************************************************
420 * ltt_event_field_element_number
421 * : The number of elements in a sequence field is specific
422 * to each event. This function returns the number of
423 * elements for an array or sequence field in an event.
425 * e : an instance of an event type
426 * f : a field of the instance
428 * unsigned : the number of elements for an array/sequence field
429 ****************************************************************************/
430 guint64
ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
432 if(f
->field_type
.type_class
!= LTT_ARRAY
&&
433 f
->field_type
.type_class
!= LTT_SEQUENCE
)
436 if(f
->field_type
.type_class
== LTT_ARRAY
)
437 return f
->field_type
.size
;
438 return ltt_event_get_long_unsigned(e
, &g_array_index(f
->field_type
.fields
,
442 /*****************************************************************************
444 * ltt_event_field_element_select
445 * : Set the currently selected element for a sequence or
447 * O(1) because of offset array.
449 * e : an instance of an event type
450 * f : a field of the instance
451 * i : the ith element (0, ...)
452 *returns : the child field, at the right index, updated.
453 ****************************************************************************/
454 LttField
*ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, gulong i
)
456 gulong element_number
;
460 LttEventType
*event_type
;
463 if(f
->field_type
.type_class
!= LTT_ARRAY
&&
464 f
->field_type
.type_class
!= LTT_SEQUENCE
)
467 element_number
= ltt_event_field_element_number(e
,f
);
468 event_type
= ltt_event_eventtype(e
);
469 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
471 if(i
>= element_number
) return;
473 if(f
->field_type
.type_class
== LTT_ARRAY
) {
474 field
= &g_array_index(f
->field_type
.fields
, LttField
, 0);
476 field
= &g_array_index(f
->field_type
.fields
, LttField
, 1);
479 if(field
->field_size
!= 0) {
480 if(f
->array_offset
+ (i
* field
->field_size
) == field
->offset_root
)
481 return; /* fixed length child, already at the right offset */
483 new_offset
= f
->array_offset
+ (i
* field
->field_size
);
485 /* Var. len. child */
486 new_offset
= g_array_index(f
->dynamic_offsets
, off_t
, i
);
488 compute_fields_offsets(e
->tracefile
, field
, &new_offset
, e
->data
);
493 /*****************************************************************************
494 * These functions extract data from an event after architecture specific
496 ****************************************************************************/
497 guint32
ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
499 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
501 LttTypeEnum t
= f
->field_type
.type_class
;
503 if(f
->field_size
== 1){
504 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
506 }else if(f
->field_size
== 2){
507 return (guint32
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
508 }else if(f
->field_size
== 4){
509 return (guint32
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
512 else if(f
->field_size
== 8){
513 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
514 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
515 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
517 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
520 g_critical("ltt_event_get_unsigned : field size %i unknown", f
->field_size
);
524 gint32
ltt_event_get_int(LttEvent
*e
, LttField
*f
)
526 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
528 if(f
->field_size
== 1){
529 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
531 }else if(f
->field_size
== 2){
532 return (gint32
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
533 }else if(f
->field_size
== 4){
534 return (gint32
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
537 else if(f
->field_size
== 8){
538 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
539 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
540 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
542 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
545 g_critical("ltt_event_get_int : field size %i unknown", f
->field_size
);
549 guint64
ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
551 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
553 LttTypeEnum t
= f
->field_type
.type_class
;
555 if(f
->field_size
== 1){
556 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
558 }else if(f
->field_size
== 2){
559 return (guint64
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
560 }else if(f
->field_size
== 4){
561 return (guint64
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
562 }else if(f
->field_size
== 8){
563 return ltt_get_uint64(reverse_byte_order
, e
->data
+ f
->offset_root
);
565 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f
->field_size
);
569 gint64
ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
571 //int revFlag = e->tracefile->trace->my_arch_endian ==
572 // e->tracefile->trace->system_description->endian ? 0:1;
573 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
575 if(f
->field_size
== 1){
576 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
578 }else if(f
->field_size
== 2){
579 return (gint64
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
580 }else if(f
->field_size
== 4){
581 return (gint64
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
582 }else if(f
->field_size
== 8){
583 return ltt_get_int64(reverse_byte_order
, e
->data
+ f
->offset_root
);
585 g_critical("ltt_event_get_long_int : field size %i unknown", f
->field_size
);
589 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
591 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
592 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
594 g_assert(f
->field_type
.type_class
== LTT_FLOAT
&& f
->field_size
== 4);
596 if(reverse_byte_order
== 0) return *(float *)(e
->data
+ f
->offset_root
);
598 void *ptr
= e
->data
+ f
->offset_root
;
599 guint32 value
= bswap_32(*(guint32
*)ptr
);
600 return *(float*)&value
;
604 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
606 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
607 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
609 if(f
->field_size
== 4)
610 return ltt_event_get_float(e
, f
);
612 g_assert(f
->field_type
.type_class
== LTT_FLOAT
&& f
->field_size
== 8);
614 if(reverse_byte_order
== 0) return *(double *)(e
->data
+ f
->offset_root
);
616 void *ptr
= e
->data
+ f
->offset_root
;
617 guint64 value
= bswap_64(*(guint64
*)ptr
);
618 return *(double*)&value
;
622 /*****************************************************************************
623 * The string obtained is only valid until the next read from
624 * the same tracefile.
625 ****************************************************************************/
626 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
628 g_assert(f
->field_type
.type_class
== LTT_STRING
);
630 return (gchar
*)g_strdup((gchar
*)(e
->data
+ f
->offset_root
));
634 /*****************************************************************************
636 * get_field_type_size : set the fixed and dynamic sizes of the field type
637 * from the data read.
640 * event_type : event type
641 * offset_root : offset from the root
642 * offset_parent : offset from the parent
644 * data : a pointer to the event data.
645 *Returns the field type size.
646 ****************************************************************************/
648 // Change this function so it uses a *to offset value incrementation, just like
649 // genevent-new instead of returning a size. What is of interest here is the
650 // offset needed to read each field.
652 // Precomputed ones can be returned directly. Otherwise, the field is flagged
653 // "VARIABLE OFFSET" and must be computed dynamically. The dynamic processing
654 // of an offset takes the last known fixed offset, and then dynamically
655 // calculates all variable field offsets from it.
657 // After a VARIABLE SIZE element, all fields have a variable offset.
658 // Also, is an array or a sequence has variable length child, we must pass
659 // through all of them, saving the offsets in the dynamic_offsets array.
662 size_t get_field_type_size(LttTracefile
*tf
, LttEventType
*event_type
,
663 off_t offset_root
, off_t offset_parent
,
664 LttField
*field
, void *data
)
671 g_assert(field
->fixed_root
!= FIELD_UNKNOWN
);
672 g_assert(field
->fixed_parent
!= FIELD_UNKNOWN
);
673 g_assert(field
->fixed_size
!= FIELD_UNKNOWN
);
675 field
->offset_root
= offset_root
;
676 field
->offset_parent
= offset_parent
;
678 type
= field
->field_type
;
680 switch(type
->type_class
) {
691 g_assert(field
->fixed_size
== FIELD_FIXED
);
692 size
= field
->field_size
;
693 align
= ltt_align(field
->offset_root
,
694 size
, event_type
->facility
->has_alignment
);
695 field
->offset_root
+= align
;
696 field
->offset_parent
+= align
;
701 /* FIXME : check the type of sequence identifier */
702 gint seqnum
= ltt_get_uint(LTT_GET_BO(tf
),
703 field
->sequ_number_size
,
706 if(field
->child
[0]->fixed_size
== FIELD_FIXED
) {
707 size
= field
->sequ_number_size
+
708 (seqnum
* get_field_type_size(tf
, event_type
,
709 offset_root
, offset_parent
,
710 field
->child
[0], data
));
712 size
+= field
->sequ_number_size
;
713 for(i
=0;i
<seqnum
;i
++) {
715 child_size
= get_field_type_size(tf
, event_type
,
716 offset_root
, offset_parent
,
717 field
->child
[0], data
);
718 offset_root
+= child_size
;
719 offset_parent
+= child_size
;
723 field
->field_size
= size
;
727 size
= strlen((char*)(data
+offset_root
)) + 1;// length + \0
728 field
->field_size
= size
;
731 if(field
->fixed_size
== FIELD_FIXED
)
732 size
= field
->field_size
;
734 for(i
=0;i
<field
->field_type
->element_number
;i
++) {
736 child_size
= get_field_type_size(tf
, event_type
,
737 offset_root
, offset_parent
,
738 field
->child
[0], data
);
739 offset_root
+= child_size
;
740 offset_parent
+= child_size
;
743 field
->field_size
= size
;
747 if(field
->fixed_size
== FIELD_FIXED
)
748 size
= field
->field_size
;
750 size_t current_root_offset
= offset_root
;
751 size_t current_offset
= 0;
752 size_t child_size
= 0;
753 for(i
=0;i
<type
->element_number
;i
++) {
754 child_size
= get_field_type_size(tf
,
755 event_type
, current_root_offset
, current_offset
,
756 field
->child
[i
], data
);
757 current_offset
+= child_size
;
758 current_root_offset
+= child_size
;
761 size
= current_offset
;
762 field
->field_size
= size
;
766 if(field
->fixed_size
== FIELD_FIXED
)
767 size
= field
->field_size
;
769 size_t current_root_offset
= field
->offset_root
;
770 size_t current_offset
= 0;
771 for(i
=0;i
<type
->element_number
;i
++) {
772 size
= get_field_type_size(tf
, event_type
,
773 current_root_offset
, current_offset
,
774 field
->child
[i
], data
);
775 size
= max(size
, field
->child
[i
]->field_size
);
777 field
->field_size
= size
;
790 /*****************************************************************************
792 * compute_fields_offsets : set the precomputable offset of the fields
796 * offset : pointer to the current offset, must be incremented
797 ****************************************************************************/
800 void compute_fields_offsets(LttTracefile
*tf
, LttField
*field
, off_t
*offset
,
803 LttType
*type
= &field
->field_type
;
805 switch(type
->type_class
) {
822 if(field
->fixed_root
== FIELD_VARIABLE
) {
823 /* Align offset on type size */
824 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
826 /* remember offset */
827 field
->offset_root
= *offset
;
828 /* Increment offset */
829 *offset
+= field
->field_size
;
831 /* None of these types has variable size, so we are sure that if
832 * this element has a fixed_root, then the following one will have
833 * a fixed root too, so it does not need the *offset at all.
837 if(field
->fixed_root
== FIELD_VARIABLE
) {
838 field
->offset_root
= *offset
;
840 *offset
+= strlen((gchar
*)(root
+*offset
)) + 1;
843 g_assert(type
->fields
->len
== 1);
846 LttField
*child
= &g_array_index(type
->fields
, LttField
, 0);
847 if(field
->fixed_root
== FIELD_VARIABLE
) {
848 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
850 /* remember offset */
851 field
->offset_root
= *offset
;
852 field
->array_offset
= *offset
;
855 if(field
->field_size
!= 0) {
856 /* Increment offset */
857 /* field_size is the array size in bytes */
858 *offset
= field
->offset_root
+ field
->field_size
;
861 *offset
= field
->array_offset
;
862 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
864 for(i
=0; i
<type
->size
; i
++) {
865 g_array_append_val(field
->dynamic_offsets
, *offset
);
866 compute_fields_offsets(tf
, child
, offset
, root
);
869 // local_offset = field->array_offset;
870 // /* Set the offset at position 0 */
871 // compute_fields_offsets(tf, child, &local_offset, root);
875 g_assert(type
->fields
->len
== 2);
880 if(field
->fixed_root
== FIELD_VARIABLE
) {
881 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
883 /* remember offset */
884 field
->offset_root
= *offset
;
886 child
= &g_array_index(type
->fields
, LttField
, 0);
887 compute_fields_offsets(tf
, child
, offset
, root
);
888 child
= &g_array_index(type
->fields
, LttField
, 1);
889 *offset
+= ltt_align(*offset
, get_alignment(tf
, child
),
891 field
->array_offset
= *offset
;
894 child
= &g_array_index(type
->fields
, LttField
, 1);
896 *offset
= field
->array_offset
;
897 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
899 for(i
=0; i
<ltt_event_field_element_number(&tf
->event
, field
); i
++) {
900 g_array_append_val(field
->dynamic_offsets
, *offset
);
901 compute_fields_offsets(tf
, child
, offset
, root
);
903 // local_offset = field->array_offset;
904 // /* Set the offset at position 0 */
905 // compute_fields_offsets(tf, child, &local_offset, root);
913 if(field
->fixed_root
== FIELD_VARIABLE
) {
914 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
916 /* remember offset */
917 field
->offset_root
= *offset
;
919 *offset
= field
->offset_root
;
921 for(i
=0; i
<type
->fields
->len
; i
++) {
922 child
= &g_array_index(type
->fields
, LttField
, i
);
923 compute_fields_offsets(tf
, child
, offset
, root
);
932 if(field
->fixed_root
== FIELD_VARIABLE
) {
933 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
935 /* remember offset */
936 field
->offset_root
= *offset
;
938 for(i
=0; i
<type
->fields
->len
; i
++) {
939 *offset
= field
->offset_root
;
940 child
= &g_array_index(type
->fields
, LttField
, i
);
941 compute_fields_offsets(tf
, child
, offset
, root
);
943 *offset
= field
->offset_root
+ field
->field_size
;
948 g_error("compute_fields_offsets : unknown type");
954 /*****************************************************************************
956 * compute_offsets : set the dynamically computable offsets of an event type
961 ****************************************************************************/
962 void compute_offsets(LttTracefile
*tf
, LttEventType
*event
, off_t
*offset
,
968 /* compute all variable offsets */
969 for(i
=0; i
<event
->fields
->len
; i
++) {
970 LttField
*field
= &g_array_index(event
->fields
, LttField
, i
);
971 compute_fields_offsets(tf
, field
, offset
, root
);