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>
38 LttEvent
*ltt_event_new()
40 return g_new(LttEvent
, 1);
43 void ltt_event_destroy(LttEvent
*event
)
50 /* Use get_field_type_size instead */
51 /*****************************************************************************
53 * ltt_event_refresh_fields : refresh fields of an event
55 * offsetRoot : offset from the root
56 * offsetParent : offset from the parent
59 * reverse_byte_order : 1 or 0
61 * int : size of the field
62 ****************************************************************************/
64 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
65 LttField
* fld
, void *evD
, gboolean reverse_byte_order
)
67 int size
, size1
, element_number
, i
, offset1
, offset2
;
68 LttType
* type
= fld
->field_type
;
70 switch(type
->type_class
) {
72 element_number
= (int) type
->element_number
;
73 if(fld
->field_fixed
== 0){// has string or sequence
75 for(i
=0;i
<element_number
;i
++){
76 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
77 fld
->child
[0], evD
+size
, reverse_byte_order
);
79 }else size
= fld
->field_size
;
83 size1
= fld
->sequ_number_size
;
84 element_number
= getIntNumber(reverse_byte_order
,size1
,evD
);
85 type
->element_number
= element_number
;
86 if(fld
->element_size
> 0){
87 size
= element_number
* fld
->element_size
;
88 }else{//sequence has string or sequence
90 for(i
=0;i
<element_number
;i
++){
91 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
92 fld
->child
[0], evD
+size
+size1
, reverse_byte_order
);
99 size
= strlen((gchar
*)evD
) + 1; //include end : '\0'
103 element_number
= (int) type
->element_number
;
104 if(fld
->field_fixed
== 0){
105 offset1
= offsetRoot
;
107 for(i
=0;i
<element_number
;i
++){
108 size
=ltt_event_refresh_fields(offset1
,offset2
,
109 fld
->child
[i
],evD
+offset2
, reverse_byte_order
);
114 }else size
= fld
->field_size
;
118 size
= fld
->field_size
;
122 size
= fld
->field_size
;
126 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
127 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
128 size
= fld
->field_size
;
129 }else if(type
->type_class
== LTT_ARRAY
){
130 element_number
= (int) type
->element_number
;
131 if(fld
->field_fixed
== 0){// has string or sequence
133 for(i
=0;i
<element_number
;i
++){
134 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
135 fld
->child
[0], evD
+size
);
137 }else size
= fld
->field_size
;
138 }else if(type
->type_class
== LTT_SEQUENCE
){
139 size1
= fld
->sequ_number_size
;
140 element_number
= getIntNumber(size1
,evD
);
141 type
->element_number
= element_number
;
142 if(fld
->element_size
> 0){
143 size
= element_number
* fld
->element_size
;
144 }else{//sequence has string or sequence
146 for(i
=0;i
<element_number
;i
++){
147 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
148 fld
->child
[0], evD
+size
+size1
);
152 }else if(type
->type_class
== LTT_STRING
){
153 size
= strlen((char*)evD
) + 1; //include end : '\0'
154 }else if(type
->type_class
== LTT_STRUCT
){
155 element_number
= (int) type
->element_number
;
156 if(fld
->field_fixed
== 0){
157 offset1
= offsetRoot
;
159 for(i
=0;i
<element_number
;i
++){
160 size
=ltt_event_refresh_fields(offset1
,offset2
,
161 fld
->child
[i
],evD
+offset2
);
166 }else size
= fld
->field_size
;
169 fld
->offset_root
= offsetRoot
;
170 fld
->offset_parent
= offsetParent
;
171 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
172 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
173 fld
->field_size
= size
;
180 /*****************************************************************************
182 * ltt_event_eventtype_id: get event type id
183 * (base id + position of the event)
185 * e : an instance of an event type
187 * unsigned : event type id
188 ****************************************************************************/
190 unsigned ltt_event_eventtype_id(const LttEvent
*e
)
192 return (unsigned) e
->event_id
;
195 /*****************************************************************************
197 * ltt_event_facility : get the facility of the event
199 * e : an instance of an event type
201 * LttFacility * : the facility of the event
202 ****************************************************************************/
204 LttFacility
*ltt_event_facility(const LttEvent
*e
)
206 LttTrace
* trace
= e
->tracefile
->trace
;
207 unsigned id
= e
->facility_id
;
208 LttFacility
*facility
= ltt_trace_facility_by_id(trace
,id
);
210 g_assert(facility
->exists
);
215 /*****************************************************************************
217 * ltt_event_facility_id : get the facility id of the event
219 * e : an instance of an event type
221 * unsigned : the facility of the event
222 ****************************************************************************/
224 unsigned ltt_event_facility_id(const LttEvent
*e
)
226 return e
->facility_id
;
229 /*****************************************************************************
231 * ltt_event_eventtype : get the event type of the event
233 * e : an instance of an event type
235 * LttEventType * : the event type of the event
236 ****************************************************************************/
238 LttEventType
*ltt_event_eventtype(const LttEvent
*e
)
240 LttFacility
* facility
= ltt_event_facility(e
);
241 if(!facility
) return NULL
;
242 return &g_array_index(facility
->events
, LttEventType
, e
->event_id
);
245 /*****************************************************************************
247 * ltt_event_field : get the root field of the event
249 * e : an instance of an event type
252 * LttField * : The requested field, or NULL
253 ****************************************************************************/
255 LttField
*ltt_event_field(LttEvent
*e
, GQuark name
)
258 LttEventType
* event_type
= ltt_event_eventtype(e
);
259 if(unlikely(!event_type
)) return NULL
;
261 return (LttField
*)g_datalist_id_get_data(&event_type
->fields_by_name
, name
);
265 /*****************************************************************************
267 * ltt_event_time : get the time of the event
269 * e : an instance of an event type
271 * LttTime : the time of the event
272 ****************************************************************************/
274 LttTime
ltt_event_time(const LttEvent
*e
)
276 return e
->event_time
;
279 /*****************************************************************************
281 * ltt_event_time : get the cycle count of the event
283 * e : an instance of an event type
285 * LttCycleCount : the cycle count of the event
286 ****************************************************************************/
288 LttCycleCount
ltt_event_cycle_count(const LttEvent
*e
)
295 /*****************************************************************************
297 * ltt_event_position_get : get the event position data
299 * e : an instance of an event type
300 * ep : a pointer to event's position structure
301 * tf : tracefile pointer
302 * block : current block
303 * offset : current offset
305 ****************************************************************************/
306 void ltt_event_position_get(LttEventPosition
*ep
, LttTracefile
**tf
,
307 guint
*block
, guint
*offset
, guint64
*tsc
)
311 *offset
= ep
->offset
;
316 /*****************************************************************************
318 * ltt_event_position : get the event's position
320 * e : an instance of an event type
321 * ep : a pointer to event's position structure
322 ****************************************************************************/
324 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
326 ep
->tracefile
= e
->tracefile
;
327 ep
->block
= e
->block
;
328 ep
->offset
= e
->offset
;
332 LttEventPosition
* ltt_event_position_new()
334 return g_new(LttEventPosition
, 1);
338 /*****************************************************************************
340 * ltt_event_position_compare : compare two positions
341 * A NULL value is infinite.
343 * ep1 : a pointer to event's position structure
344 * ep2 : a pointer to event's position structure
349 ****************************************************************************/
352 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
353 const LttEventPosition
*ep2
)
355 if(ep1
== NULL
&& ep2
== NULL
)
357 if(ep1
!= NULL
&& ep2
== NULL
)
359 if(ep1
== NULL
&& ep2
!= NULL
)
362 if(ep1
->tracefile
!= ep2
->tracefile
)
363 g_error("ltt_event_position_compare on different tracefiles makes no sense");
365 if(ep1
->block
< ep2
->block
)
367 if(ep1
->block
> ep2
->block
)
369 if(ep1
->offset
< ep2
->offset
)
371 if(ep1
->offset
> ep2
->offset
)
376 /*****************************************************************************
378 * ltt_event_position_copy : copy position
380 * src : a pointer to event's position structure source
381 * dest : a pointer to event's position structure dest
384 ****************************************************************************/
385 void ltt_event_position_copy(LttEventPosition
*dest
,
386 const LttEventPosition
*src
)
396 LttTracefile
*ltt_event_position_tracefile(LttEventPosition
*ep
)
398 return ep
->tracefile
;
401 /*****************************************************************************
403 * ltt_event_cpu_i: get the cpu id where the event happens
405 * e : an instance of an event type
407 * unsigned : the cpu id
408 ****************************************************************************/
410 unsigned ltt_event_cpu_id(LttEvent
*e
)
412 return e
->tracefile
->cpu_num
;
415 /*****************************************************************************
417 * ltt_event_data : get the raw data for the event
419 * e : an instance of an event type
421 * void * : pointer to the raw data for the event
422 ****************************************************************************/
424 void *ltt_event_data(LttEvent
*e
)
429 /*****************************************************************************
431 * ltt_event_field_element_number
432 * : The number of elements in a sequence field is specific
433 * to each event. This function returns the number of
434 * elements for an array or sequence field in an event.
436 * e : an instance of an event type
437 * f : a field of the instance
439 * unsigned : the number of elements for an array/sequence field
440 ****************************************************************************/
441 guint64
ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
443 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
444 f
->field_type
->type_class
!= LTT_SEQUENCE
)
447 if(f
->field_type
->type_class
== LTT_ARRAY
)
448 return f
->field_type
->size
;
449 return ltt_get_long_unsigned(e
, &g_array_index(f
->fields
, LttField
, 0));
452 /*****************************************************************************
454 * ltt_event_field_element_select
455 * : Set the currently selected element for a sequence or
457 * O(1) because of offset array.
459 * e : an instance of an event type
460 * f : a field of the instance
461 * i : the ith element (0, ...)
462 *returns : the child field, at the right index, updated.
463 ****************************************************************************/
464 LttField
*ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, gulong i
)
466 gulong element_number
;
470 LttEventType
*event_type
;
473 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
474 f
->field_type
->type_class
!= LTT_SEQUENCE
)
477 element_number
= ltt_event_field_element_number(e
,f
);
478 event_type
= ltt_event_eventtype(e
);
479 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
481 if(i
>= element_number
) return;
483 if(f
->field_type
->type_class
== LTT_ARRAY
) {
484 field
= &g_array_index(f
->fields
, LttField
, 0);
486 field
= &g_array_index(f
->fields
, LttField
, 1);
489 if(field
->field_size
!= 0) {
490 if(f
->array_offset
+ (i
* field
->field_size
) == field
->offset_root
)
491 return; /* fixed length child, already at the right offset */
493 new_offset
= f
->array_offset
+ (i
* field
->field_size
);
495 /* Var. len. child */
496 new_offset
= g_array_index(f
->dynamic_offsets
, off_t
, i
);
498 compute_fields_offsets(e
->tracefile
, field
, new_offset
);
503 /*****************************************************************************
504 * These functions extract data from an event after architecture specific
506 ****************************************************************************/
507 guint32
ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
509 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
511 LttTypeEnum t
= f
->field_type
->type_class
;
513 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
515 if(f
->field_size
== 1){
516 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
518 }else if(f
->field_size
== 2){
519 return (guint32
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
520 }else if(f
->field_size
== 4){
521 return (guint32
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
524 else if(f
->field_size
== 8){
525 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
526 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
527 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
529 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
532 g_critical("ltt_event_get_unsigned : field size %i unknown", f
->field_size
);
536 gint32
ltt_event_get_int(LttEvent
*e
, LttField
*f
)
538 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
540 g_assert(f
->field_type
->type_class
== LTT_INT
);
542 if(f
->field_size
== 1){
543 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
545 }else if(f
->field_size
== 2){
546 return (gint32
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
547 }else if(f
->field_size
== 4){
548 return (gint32
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
551 else if(f
->field_size
== 8){
552 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
553 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
554 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
556 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
559 g_critical("ltt_event_get_int : field size %i unknown", f
->field_size
);
563 guint64
ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
565 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
567 LttTypeEnum t
= f
->field_type
->type_class
;
569 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
570 || t
== LTT_ULONG
|| LTT_SIZE_T
|| LTT_OFF_T
|| LTT_POINTER
);
572 if(f
->field_size
== 1){
573 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
575 }else if(f
->field_size
== 2){
576 return (guint64
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
577 }else if(f
->field_size
== 4){
578 return (guint64
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
579 }else if(f
->field_size
== 8){
580 return ltt_get_uint64(reverse_byte_order
, e
->data
+ f
->offset_root
);
582 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f
->field_size
);
586 gint64
ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
588 //int revFlag = e->tracefile->trace->my_arch_endian ==
589 // e->tracefile->trace->system_description->endian ? 0:1;
590 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
592 g_assert( f
->field_type
->type_class
== LTT_INT
593 || f
->field_type
->type_class
== LTT_LONG
594 || f
->field_type
->type_class
== LTT_SSIZE_T
);
596 if(f
->field_size
== 1){
597 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
599 }else if(f
->field_size
== 2){
600 return (gint64
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
601 }else if(f
->field_size
== 4){
602 return (gint64
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
603 }else if(f
->field_size
== 8){
604 return ltt_get_int64(reverse_byte_order
, e
->data
+ f
->offset_root
);
606 g_critical("ltt_event_get_long_int : field size %i unknown", f
->field_size
);
610 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
612 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
613 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
615 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 4);
617 if(reverse_byte_order
== 0) return *(float *)(e
->data
+ f
->offset_root
);
619 void *ptr
= e
->data
+ f
->offset_root
;
620 guint32 value
= bswap_32(*(guint32
*)ptr
);
621 return *(float*)&value
;
625 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
627 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
628 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
630 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 8);
632 if(reverse_byte_order
== 0) return *(double *)(e
->data
+ f
->offset_root
);
634 void *ptr
= e
->data
+ f
->offset_root
;
635 guint64 value
= bswap_64(*(guint64
*)ptr
);
636 return *(double*)&value
;
640 /*****************************************************************************
641 * The string obtained is only valid until the next read from
642 * the same tracefile.
643 ****************************************************************************/
644 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
646 g_assert(f
->field_type
->type_class
== LTT_STRING
);
648 return (gchar
*)g_strdup((gchar
*)(e
->data
+ f
->offset_root
));
652 /*****************************************************************************
654 * get_field_type_size : set the fixed and dynamic sizes of the field type
655 * from the data read.
658 * event_type : event type
659 * offset_root : offset from the root
660 * offset_parent : offset from the parent
662 * data : a pointer to the event data.
663 *Returns the field type size.
664 ****************************************************************************/
666 // Change this function so it uses a *to offset value incrementation, just like
667 // genevent-new instead of returning a size. What is of interest here is the
668 // offset needed to read each field.
670 // Precomputed ones can be returned directly. Otherwise, the field is flagged
671 // "VARIABLE OFFSET" and must be computed dynamically. The dynamic processing
672 // of an offset takes the last known fixed offset, and then dynamically
673 // calculates all variable field offsets from it.
675 // After a VARIABLE SIZE element, all fields have a variable offset.
676 // Also, is an array or a sequence has variable length child, we must pass
677 // through all of them, saving the offsets in the dynamic_offsets array.
680 size_t get_field_type_size(LttTracefile
*tf
, LttEventType
*event_type
,
681 off_t offset_root
, off_t offset_parent
,
682 LttField
*field
, void *data
)
689 g_assert(field
->fixed_root
!= FIELD_UNKNOWN
);
690 g_assert(field
->fixed_parent
!= FIELD_UNKNOWN
);
691 g_assert(field
->fixed_size
!= FIELD_UNKNOWN
);
693 field
->offset_root
= offset_root
;
694 field
->offset_parent
= offset_parent
;
696 type
= field
->field_type
;
698 switch(type
->type_class
) {
709 g_assert(field
->fixed_size
== FIELD_FIXED
);
710 size
= field
->field_size
;
711 align
= ltt_align(field
->offset_root
,
712 size
, event_type
->facility
->has_alignment
);
713 field
->offset_root
+= align
;
714 field
->offset_parent
+= align
;
719 /* FIXME : check the type of sequence identifier */
720 gint seqnum
= ltt_get_uint(LTT_GET_BO(tf
),
721 field
->sequ_number_size
,
724 if(field
->child
[0]->fixed_size
== FIELD_FIXED
) {
725 size
= field
->sequ_number_size
+
726 (seqnum
* get_field_type_size(tf
, event_type
,
727 offset_root
, offset_parent
,
728 field
->child
[0], data
));
730 size
+= field
->sequ_number_size
;
731 for(i
=0;i
<seqnum
;i
++) {
733 child_size
= get_field_type_size(tf
, event_type
,
734 offset_root
, offset_parent
,
735 field
->child
[0], data
);
736 offset_root
+= child_size
;
737 offset_parent
+= child_size
;
741 field
->field_size
= size
;
745 size
= strlen((char*)(data
+offset_root
)) + 1;// length + \0
746 field
->field_size
= size
;
749 if(field
->fixed_size
== FIELD_FIXED
)
750 size
= field
->field_size
;
752 for(i
=0;i
<field
->field_type
->element_number
;i
++) {
754 child_size
= get_field_type_size(tf
, event_type
,
755 offset_root
, offset_parent
,
756 field
->child
[0], data
);
757 offset_root
+= child_size
;
758 offset_parent
+= child_size
;
761 field
->field_size
= size
;
765 if(field
->fixed_size
== FIELD_FIXED
)
766 size
= field
->field_size
;
768 size_t current_root_offset
= offset_root
;
769 size_t current_offset
= 0;
770 size_t child_size
= 0;
771 for(i
=0;i
<type
->element_number
;i
++) {
772 child_size
= get_field_type_size(tf
,
773 event_type
, current_root_offset
, current_offset
,
774 field
->child
[i
], data
);
775 current_offset
+= child_size
;
776 current_root_offset
+= child_size
;
779 size
= current_offset
;
780 field
->field_size
= size
;
784 if(field
->fixed_size
== FIELD_FIXED
)
785 size
= field
->field_size
;
787 size_t current_root_offset
= field
->offset_root
;
788 size_t current_offset
= 0;
789 for(i
=0;i
<type
->element_number
;i
++) {
790 size
= get_field_type_size(tf
, event_type
,
791 current_root_offset
, current_offset
,
792 field
->child
[i
], data
);
793 size
= max(size
, field
->child
[i
]->field_size
);
795 field
->field_size
= size
;
808 /*****************************************************************************
810 * compute_fields_offsets : set the precomputable offset of the fields
814 * offset : pointer to the current offset, must be incremented
815 ****************************************************************************/
818 void compute_fields_offsets(LttTracefile
*tf
, LttField
*field
, off_t
*offset
,
821 type
= &field
->field_type
;
823 switch(type
->type_class
) {
840 if(field
->fixed_root
== FIELD_VARIABLE
) {
841 /* Align offset on type size */
842 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
844 /* remember offset */
845 field
->offset_root
= *offset
;
846 /* Increment offset */
847 *offset
+= field
->field_size
;
849 /* None of these types has variable size, so we are sure that if
850 * this element has a fixed_root, then the following one will have
851 * a fixed root too, so it does not need the *offset at all.
855 if(field
->fixed_root
== FIELD_VARIABLE
) {
856 field
->offset_root
= *offset
;
858 *offset
+= strlen((gchar
*)(root
+*offset
)) + 1;
861 g_assert(type
->fields
->len
== 1);
864 LttField
*child
= &g_array_index(type
->fields
, LttField
, 0);
865 if(field
->fixed_root
== FIELD_VARIABLE
) {
866 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
868 /* remember offset */
869 field
->offset_root
= *offset
;
870 field
->array_offset
= *offset
;
873 if(field
->field_size
!= 0) {
874 /* Increment offset */
875 /* field_size is the array size in bytes */
876 *offset
= field
->offset_root
+ field
->field_size
;
879 *offset
= field
->array_offset
;
880 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
882 for(i
=0; i
<type
->size
; i
++) {
883 g_array_append_val(field
->dynamic_offsets
, *offset
);
884 compute_fields_offsets(tf
, child
, offset
);
887 // local_offset = field->array_offset;
888 // /* Set the offset at position 0 */
889 // compute_fields_offsets(tf, child, &local_offset);
892 g_assert(type
->fields
->len
== 2);
897 if(field
->fixed_root
== FIELD_VARIABLE
) {
898 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
900 /* remember offset */
901 field
->offset_root
= *offset
;
903 child
= &g_array_index(type
->fields
, LttField
, 0);
904 compute_fields_offsets(tf
, child
, offset
);
905 child
= &g_array_index(type
->fields
, LttField
, 1);
906 *offset
+= ltt_align(*offset
, get_alignment(tf
, child
),
908 field
->array_offset
= *offset
;
911 child
= &g_array_index(type
->fields
, LttField
, 1);
913 *offset
= field
->array_offset
;
914 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
916 for(i
=0; i
<ltt_event_field_element_number(&tf
->event
, field
); i
++) {
917 g_array_append_val(field
->dynamic_offsets
, *offset
);
918 compute_fields_offsets(tf
, child
, offset
);
920 // local_offset = field->array_offset;
921 // /* Set the offset at position 0 */
922 // compute_fields_offsets(tf, child, &local_offset);
930 if(field
->fixed_root
== FIELD_VARIABLE
) {
931 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
933 /* remember offset */
934 field
->offset_root
= *offset
;
936 *offset
= field
->offset_root
;
938 for(i
=0; i
<type
->fields
->len
; i
++) {
939 child
= &g_array_index(type
->fields
, LttField
, i
);
940 compute_fields_offsets(tf
, child
, offset
);
949 if(field
->fixed_root
== FIELD_VARIABLE
) {
950 *offset
+= ltt_align(*offset
, get_alignment(tf
, field
),
952 /* remember offset */
953 field
->offset_root
= *offset
;
955 for(i
=0; i
<type
->fields
->len
; i
++) {
956 *offset
= field
->offset_root
;
957 child
= &g_array_index(type
->fields
, LttField
, i
);
958 compute_fields_offsets(tf
, child
, offset
);
960 *offset
= field
->offset_root
+ field
->field_size
;
965 g_error("compute_fields_offsets : unknown type");
971 /*****************************************************************************
973 * compute_offsets : set the dynamically computable offsets of an event type
978 ****************************************************************************/
979 void compute_offsets(LttTracefile
*tf
, LttEventType
*event
, size_t *offset
,
985 /* compute all variable offsets */
986 for(i
=0; i
<event
->fields
->len
; i
++) {
987 LttField
*field
= &g_array_index(event
->fields
, LttField
, i
);
988 ret
= compute_fields_offsets(tf
, field
, offset
, root
);