1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
3 * 2006 Mathieu Desnoyers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License Version 2.1 as published by the Free Software Foundation.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
29 #include <asm/types.h>
34 #include "ltt-private.h"
35 #include <ltt/event.h>
36 #include <ltt/trace.h>
37 #include <ltt/ltt-types.h>
41 void compute_fields_offsets(LttTracefile
*tf
,
42 LttFacility
*fac
, LttField
*field
, off_t
*offset
, void *root
);
45 LttEvent
*ltt_event_new()
47 return g_new(LttEvent
, 1);
50 void ltt_event_destroy(LttEvent
*event
)
57 /* Use get_field_type_size instead */
58 /*****************************************************************************
60 * ltt_event_refresh_fields : refresh fields of an event
62 * offsetRoot : offset from the root
63 * offsetParent : offset from the parent
66 * reverse_byte_order : 1 or 0
68 * int : size of the field
69 ****************************************************************************/
71 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
72 LttField
* fld
, void *evD
, gboolean reverse_byte_order
)
74 int size
, size1
, element_number
, i
, offset1
, offset2
;
75 LttType
* type
= fld
->field_type
;
77 switch(type
->type_class
) {
79 element_number
= (int) type
->element_number
;
80 if(fld
->field_fixed
== 0){// has string or sequence
82 for(i
=0;i
<element_number
;i
++){
83 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
84 fld
->child
[0], evD
+size
, reverse_byte_order
);
86 }else size
= fld
->field_size
;
90 size1
= fld
->sequ_number_size
;
91 element_number
= getIntNumber(reverse_byte_order
,size1
,evD
);
92 type
->element_number
= element_number
;
93 if(fld
->element_size
> 0){
94 size
= element_number
* fld
->element_size
;
95 }else{//sequence has string or sequence
97 for(i
=0;i
<element_number
;i
++){
98 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
99 fld
->child
[0], evD
+size
+size1
, reverse_byte_order
);
106 size
= strlen((gchar
*)evD
) + 1; //include end : '\0'
110 element_number
= (int) type
->element_number
;
111 if(fld
->field_fixed
== 0){
112 offset1
= offsetRoot
;
114 for(i
=0;i
<element_number
;i
++){
115 size
=ltt_event_refresh_fields(offset1
,offset2
,
116 fld
->child
[i
],evD
+offset2
, reverse_byte_order
);
121 }else size
= fld
->field_size
;
125 size
= fld
->field_size
;
129 size
= fld
->field_size
;
133 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
134 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
135 size
= fld
->field_size
;
136 }else if(type
->type_class
== LTT_ARRAY
){
137 element_number
= (int) type
->element_number
;
138 if(fld
->field_fixed
== 0){// has string or sequence
140 for(i
=0;i
<element_number
;i
++){
141 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
142 fld
->child
[0], evD
+size
);
144 }else size
= fld
->field_size
;
145 }else if(type
->type_class
== LTT_SEQUENCE
){
146 size1
= fld
->sequ_number_size
;
147 element_number
= getIntNumber(size1
,evD
);
148 type
->element_number
= element_number
;
149 if(fld
->element_size
> 0){
150 size
= element_number
* fld
->element_size
;
151 }else{//sequence has string or sequence
153 for(i
=0;i
<element_number
;i
++){
154 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
155 fld
->child
[0], evD
+size
+size1
);
159 }else if(type
->type_class
== LTT_STRING
){
160 size
= strlen((char*)evD
) + 1; //include end : '\0'
161 }else if(type
->type_class
== LTT_STRUCT
){
162 element_number
= (int) type
->element_number
;
163 if(fld
->field_fixed
== 0){
164 offset1
= offsetRoot
;
166 for(i
=0;i
<element_number
;i
++){
167 size
=ltt_event_refresh_fields(offset1
,offset2
,
168 fld
->child
[i
],evD
+offset2
);
173 }else size
= fld
->field_size
;
176 fld
->offset_root
= offsetRoot
;
177 fld
->offset_parent
= offsetParent
;
178 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
179 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
180 fld
->field_size
= size
;
187 /*****************************************************************************
189 * ltt_event_eventtype_id: get event type id
190 * (base id + position of the event)
192 * e : an instance of an event type
194 * unsigned : event type id
195 ****************************************************************************/
197 unsigned ltt_event_eventtype_id(const LttEvent
*e
)
199 return (unsigned) e
->event_id
;
202 /*****************************************************************************
204 * ltt_event_facility : get the facility of the event
206 * e : an instance of an event type
208 * LttFacility * : the facility of the event
209 ****************************************************************************/
211 LttFacility
*ltt_event_facility(const LttEvent
*e
)
213 LttTrace
* trace
= e
->tracefile
->trace
;
214 unsigned id
= e
->facility_id
;
215 LttFacility
*facility
= ltt_trace_facility_by_id(trace
,id
);
217 g_assert(facility
->exists
);
222 /*****************************************************************************
224 * ltt_event_facility_id : get the facility id of the event
226 * e : an instance of an event type
228 * unsigned : the facility of the event
229 ****************************************************************************/
231 unsigned ltt_event_facility_id(const LttEvent
*e
)
233 return e
->facility_id
;
236 /*****************************************************************************
238 * ltt_event_eventtype : get the event type of the event
240 * e : an instance of an event type
242 * LttEventType * : the event type of the event
243 ****************************************************************************/
245 LttEventType
*ltt_event_eventtype(const LttEvent
*e
)
247 LttFacility
* facility
= ltt_event_facility(e
);
248 if(!facility
) return NULL
;
249 return &g_array_index(facility
->events
, LttEventType
, e
->event_id
);
253 /*****************************************************************************
255 * ltt_event_time : get the time of the event
257 * e : an instance of an event type
259 * LttTime : the time of the event
260 ****************************************************************************/
262 LttTime
ltt_event_time(const LttEvent
*e
)
264 return e
->event_time
;
267 /*****************************************************************************
269 * ltt_event_time : get the cycle count of the event
271 * e : an instance of an event type
273 * LttCycleCount : the cycle count of the event
274 ****************************************************************************/
276 LttCycleCount
ltt_event_cycle_count(const LttEvent
*e
)
283 /*****************************************************************************
285 * ltt_event_position_get : get the event position data
287 * e : an instance of an event type
288 * ep : a pointer to event's position structure
289 * tf : tracefile pointer
290 * block : current block
291 * offset : current offset
293 ****************************************************************************/
294 void ltt_event_position_get(LttEventPosition
*ep
, LttTracefile
**tf
,
295 guint
*block
, guint
*offset
, guint64
*tsc
)
299 *offset
= ep
->offset
;
304 /*****************************************************************************
306 * ltt_event_position : get the event's position
308 * e : an instance of an event type
309 * ep : a pointer to event's position structure
310 ****************************************************************************/
312 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
314 ep
->tracefile
= e
->tracefile
;
315 ep
->block
= e
->block
;
316 ep
->offset
= e
->offset
;
320 LttEventPosition
* ltt_event_position_new()
322 return g_new(LttEventPosition
, 1);
326 /*****************************************************************************
328 * ltt_event_position_compare : compare two positions
329 * A NULL value is infinite.
331 * ep1 : a pointer to event's position structure
332 * ep2 : a pointer to event's position structure
337 ****************************************************************************/
340 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
341 const LttEventPosition
*ep2
)
343 if(ep1
== NULL
&& ep2
== NULL
)
345 if(ep1
!= NULL
&& ep2
== NULL
)
347 if(ep1
== NULL
&& ep2
!= NULL
)
350 if(ep1
->tracefile
!= ep2
->tracefile
)
351 g_error("ltt_event_position_compare on different tracefiles makes no sense");
353 if(ep1
->block
< ep2
->block
)
355 if(ep1
->block
> ep2
->block
)
357 if(ep1
->offset
< ep2
->offset
)
359 if(ep1
->offset
> ep2
->offset
)
364 /*****************************************************************************
366 * ltt_event_position_copy : copy position
368 * src : a pointer to event's position structure source
369 * dest : a pointer to event's position structure dest
372 ****************************************************************************/
373 void ltt_event_position_copy(LttEventPosition
*dest
,
374 const LttEventPosition
*src
)
384 LttTracefile
*ltt_event_position_tracefile(LttEventPosition
*ep
)
386 return ep
->tracefile
;
389 /*****************************************************************************
391 * ltt_event_cpu_i: get the cpu id where the event happens
393 * e : an instance of an event type
395 * unsigned : the cpu id
396 ****************************************************************************/
398 unsigned ltt_event_cpu_id(LttEvent
*e
)
400 return e
->tracefile
->cpu_num
;
403 /*****************************************************************************
405 * ltt_event_data : get the raw data for the event
407 * e : an instance of an event type
409 * void * : pointer to the raw data for the event
410 ****************************************************************************/
412 void *ltt_event_data(LttEvent
*e
)
417 /*****************************************************************************
419 * ltt_event_field_element_number
420 * : The number of elements in a sequence field is specific
421 * to each event. This function returns the number of
422 * elements for an array or sequence field in an event.
424 * e : an instance of an event type
425 * f : a field of the instance
427 * unsigned : the number of elements for an array/sequence field
428 ****************************************************************************/
429 guint64
ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
431 if(f
->field_type
.type_class
!= LTT_ARRAY
&&
432 f
->field_type
.type_class
!= LTT_SEQUENCE
)
435 if(f
->field_type
.type_class
== LTT_ARRAY
)
436 return f
->field_type
.size
;
437 return ltt_event_get_long_unsigned(e
, &g_array_index(f
->field_type
.fields
,
441 /*****************************************************************************
443 * ltt_event_field_element_select
444 * : Set the currently selected element for a sequence or
446 * O(1) because of offset array.
448 * e : an instance of an event type
449 * f : a field of the instance
450 * i : the ith element (0, ...)
451 *returns : the child field, at the right index, updated.
452 ****************************************************************************/
453 LttField
*ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, gulong i
)
455 gulong element_number
;
459 LttEventType
*event_type
;
462 if(f
->field_type
.type_class
!= LTT_ARRAY
&&
463 f
->field_type
.type_class
!= LTT_SEQUENCE
)
466 element_number
= ltt_event_field_element_number(e
,f
);
467 event_type
= ltt_event_eventtype(e
);
468 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
470 if(i
>= element_number
) return NULL
;
472 if(f
->field_type
.type_class
== LTT_ARRAY
) {
473 field
= &g_array_index(f
->field_type
.fields
, LttField
, 0);
475 field
= &g_array_index(f
->field_type
.fields
, LttField
, 1);
478 if(field
->field_size
!= 0) {
479 if(f
->array_offset
+ (i
* field
->field_size
) == field
->offset_root
)
480 return field
; /* fixed length child, already at the right offset */
482 new_offset
= f
->array_offset
+ (i
* field
->field_size
);
484 /* Var. len. child */
485 new_offset
= g_array_index(f
->dynamic_offsets
, off_t
, i
);
487 compute_fields_offsets(e
->tracefile
,
488 ltt_event_facility(e
), field
, &new_offset
, e
->data
);
494 off_t
ltt_event_field_offset(LttEvent
*e
, LttField
*f
)
496 return f
->offset_root
;
501 /*****************************************************************************
502 * These functions extract data from an event after architecture specific
504 ****************************************************************************/
505 guint32
ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
507 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
509 LttTypeEnum t
= f
->field_type
.type_class
;
511 if(f
->field_size
== 1){
512 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
514 }else if(f
->field_size
== 2){
515 return (guint32
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
516 }else if(f
->field_size
== 4){
517 return (guint32
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
520 else if(f
->field_size
== 8){
521 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
522 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
523 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
525 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
528 g_critical("ltt_event_get_unsigned : field size %i unknown", f
->field_size
);
532 gint32
ltt_event_get_int(LttEvent
*e
, LttField
*f
)
534 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
536 if(f
->field_size
== 1){
537 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
539 }else if(f
->field_size
== 2){
540 return (gint32
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
541 }else if(f
->field_size
== 4){
542 return (gint32
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
545 else if(f
->field_size
== 8){
546 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
547 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
548 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
550 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
553 g_critical("ltt_event_get_int : field size %i unknown", f
->field_size
);
557 guint64
ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
559 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
561 LttTypeEnum t
= f
->field_type
.type_class
;
563 if(f
->field_size
== 1){
564 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
566 }else if(f
->field_size
== 2){
567 return (guint64
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
568 }else if(f
->field_size
== 4){
569 return (guint64
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
570 }else if(f
->field_size
== 8){
571 return ltt_get_uint64(reverse_byte_order
, e
->data
+ f
->offset_root
);
573 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f
->field_size
);
577 gint64
ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
579 //int revFlag = e->tracefile->trace->my_arch_endian ==
580 // e->tracefile->trace->system_description->endian ? 0:1;
581 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
583 if(f
->field_size
== 1){
584 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
586 }else if(f
->field_size
== 2){
587 return (gint64
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
588 }else if(f
->field_size
== 4){
589 return (gint64
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
590 }else if(f
->field_size
== 8){
591 return ltt_get_int64(reverse_byte_order
, e
->data
+ f
->offset_root
);
593 g_critical("ltt_event_get_long_int : field size %i unknown", f
->field_size
);
597 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
599 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
600 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
602 g_assert(f
->field_type
.type_class
== LTT_FLOAT
&& f
->field_size
== 4);
604 if(reverse_byte_order
== 0) return *(float *)(e
->data
+ f
->offset_root
);
606 void *ptr
= e
->data
+ f
->offset_root
;
607 guint32 value
= bswap_32(*(guint32
*)ptr
);
608 return *(float*)&value
;
612 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
614 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
615 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
617 if(f
->field_size
== 4)
618 return ltt_event_get_float(e
, f
);
620 g_assert(f
->field_type
.type_class
== LTT_FLOAT
&& f
->field_size
== 8);
622 if(reverse_byte_order
== 0) return *(double *)(e
->data
+ f
->offset_root
);
624 void *ptr
= e
->data
+ f
->offset_root
;
625 guint64 value
= bswap_64(*(guint64
*)ptr
);
626 return *(double*)&value
;
630 /*****************************************************************************
631 * The string obtained is only valid until the next read from
632 * the same tracefile.
633 ****************************************************************************/
634 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
636 g_assert(f
->field_type
.type_class
== LTT_STRING
);
638 return (gchar
*)g_strdup((gchar
*)(e
->data
+ f
->offset_root
));
642 /*****************************************************************************
644 * get_field_type_size : set the fixed and dynamic sizes of the field type
645 * from the data read.
648 * event_type : event type
649 * offset_root : offset from the root
650 * offset_parent : offset from the parent
652 * data : a pointer to the event data.
653 *Returns the field type size.
654 ****************************************************************************/
656 // Change this function so it uses a *to offset value incrementation, just like
657 // genevent-new instead of returning a size. What is of interest here is the
658 // offset needed to read each field.
660 // Precomputed ones can be returned directly. Otherwise, the field is flagged
661 // "VARIABLE OFFSET" and must be computed dynamically. The dynamic processing
662 // of an offset takes the last known fixed offset, and then dynamically
663 // calculates all variable field offsets from it.
665 // After a VARIABLE SIZE element, all fields have a variable offset.
666 // Also, is an array or a sequence has variable length child, we must pass
667 // through all of them, saving the offsets in the dynamic_offsets array.
670 size_t get_field_type_size(LttTracefile
*tf
, LttEventType
*event_type
,
671 off_t offset_root
, off_t offset_parent
,
672 LttField
*field
, void *data
)
679 g_assert(field
->fixed_root
!= FIELD_UNKNOWN
);
680 g_assert(field
->fixed_parent
!= FIELD_UNKNOWN
);
681 g_assert(field
->fixed_size
!= FIELD_UNKNOWN
);
683 field
->offset_root
= offset_root
;
684 field
->offset_parent
= offset_parent
;
686 type
= field
->field_type
;
688 switch(type
->type_class
) {
699 g_assert(field
->fixed_size
== FIELD_FIXED
);
700 size
= field
->field_size
;
701 align
= ltt_align(field
->offset_root
,
702 size
, event_type
->facility
->alignment
);
703 field
->offset_root
+= align
;
704 field
->offset_parent
+= align
;
709 /* FIXME : check the type of sequence identifier */
710 gint seqnum
= ltt_get_uint(LTT_GET_BO(tf
),
711 field
->sequ_number_size
,
714 if(field
->child
[0]->fixed_size
== FIELD_FIXED
) {
715 size
= field
->sequ_number_size
+
716 (seqnum
* get_field_type_size(tf
, event_type
,
717 offset_root
, offset_parent
,
718 field
->child
[0], data
));
720 size
+= field
->sequ_number_size
;
721 for(i
=0;i
<seqnum
;i
++) {
723 child_size
= get_field_type_size(tf
, event_type
,
724 offset_root
, offset_parent
,
725 field
->child
[0], data
);
726 offset_root
+= child_size
;
727 offset_parent
+= child_size
;
731 field
->field_size
= size
;
735 size
= strlen((char*)(data
+offset_root
)) + 1;// length + \0
736 field
->field_size
= size
;
739 if(field
->fixed_size
== FIELD_FIXED
)
740 size
= field
->field_size
;
742 for(i
=0;i
<field
->field_type
->element_number
;i
++) {
744 child_size
= get_field_type_size(tf
, event_type
,
745 offset_root
, offset_parent
,
746 field
->child
[0], data
);
747 offset_root
+= child_size
;
748 offset_parent
+= child_size
;
751 field
->field_size
= size
;
755 if(field
->fixed_size
== FIELD_FIXED
)
756 size
= field
->field_size
;
758 size_t current_root_offset
= offset_root
;
759 size_t current_offset
= 0;
760 size_t child_size
= 0;
761 for(i
=0;i
<type
->element_number
;i
++) {
762 child_size
= get_field_type_size(tf
,
763 event_type
, current_root_offset
, current_offset
,
764 field
->child
[i
], data
);
765 current_offset
+= child_size
;
766 current_root_offset
+= child_size
;
769 size
= current_offset
;
770 field
->field_size
= size
;
774 if(field
->fixed_size
== FIELD_FIXED
)
775 size
= field
->field_size
;
777 size_t current_root_offset
= field
->offset_root
;
778 size_t current_offset
= 0;
779 for(i
=0;i
<type
->element_number
;i
++) {
780 size
= get_field_type_size(tf
, event_type
,
781 current_root_offset
, current_offset
,
782 field
->child
[i
], data
);
783 size
= max(size
, field
->child
[i
]->field_size
);
785 field
->field_size
= size
;
798 /*****************************************************************************
800 * compute_fields_offsets : set the precomputable offset of the fields
804 * offset : pointer to the current offset, must be incremented
805 ****************************************************************************/
808 void compute_fields_offsets(LttTracefile
*tf
,
809 LttFacility
*fac
, LttField
*field
, off_t
*offset
, void *root
)
811 LttType
*type
= &field
->field_type
;
813 switch(type
->type_class
) {
830 if(field
->fixed_root
== FIELD_VARIABLE
) {
831 /* Align offset on type size */
832 *offset
+= ltt_align(*offset
, get_alignment(field
),
834 /* remember offset */
835 field
->offset_root
= *offset
;
836 /* Increment offset */
837 *offset
+= field
->field_size
;
839 //g_debug("type before offset : %llu %llu %u\n", *offset,
840 // field->offset_root,
841 // field->field_size);
842 *offset
= field
->offset_root
;
843 *offset
+= field
->field_size
;
844 //g_debug("type after offset : %llu\n", *offset);
848 if(field
->fixed_root
== FIELD_VARIABLE
) {
849 field
->offset_root
= *offset
;
851 *offset
+= strlen((gchar
*)(root
+*offset
)) + 1;
852 /* Realign the data */
853 *offset
+= ltt_align(*offset
, fac
->pointer_size
,
857 g_assert(type
->fields
->len
== 1);
860 LttField
*child
= &g_array_index(type
->fields
, LttField
, 0);
861 if(field
->fixed_root
== FIELD_VARIABLE
) {
862 *offset
+= ltt_align(*offset
, get_alignment(field
),
864 /* remember offset */
865 field
->offset_root
= *offset
;
866 field
->array_offset
= *offset
;
869 if(field
->field_size
!= 0) {
870 /* Increment offset */
871 /* field_size is the array size in bytes */
872 *offset
= field
->offset_root
+ field
->field_size
;
875 *offset
= field
->array_offset
;
876 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
878 for(i
=0; i
<type
->size
; i
++) {
879 g_array_append_val(field
->dynamic_offsets
, *offset
);
880 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
883 // local_offset = field->array_offset;
884 // /* Set the offset at position 0 */
885 // compute_fields_offsets(tf, fac, child, &local_offset, root);
889 g_assert(type
->fields
->len
== 2);
895 if(field
->fixed_root
== FIELD_VARIABLE
) {
896 *offset
+= ltt_align(*offset
, get_alignment(field
),
898 /* remember offset */
899 field
->offset_root
= *offset
;
901 child
= &g_array_index(type
->fields
, LttField
, 0);
902 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
903 child
= &g_array_index(type
->fields
, LttField
, 1);
904 *offset
+= ltt_align(*offset
, get_alignment(child
),
906 field
->array_offset
= *offset
;
909 child
= &g_array_index(type
->fields
, LttField
, 1);
911 *offset
= field
->array_offset
;
912 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
914 num_elem
= ltt_event_field_element_number(&tf
->event
, field
);
915 for(i
=0; i
<num_elem
; i
++) {
916 g_array_append_val(field
->dynamic_offsets
, *offset
);
917 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
919 g_assert(num_elem
== field
->dynamic_offsets
->len
);
921 /* Realign the data */
922 *offset
+= ltt_align(*offset
, fac
->pointer_size
,
925 // local_offset = field->array_offset;
926 // /* Set the offset at position 0 */
927 // compute_fields_offsets(tf, fac, child, &local_offset, root);
935 if(field
->fixed_root
== FIELD_VARIABLE
) {
936 *offset
+= ltt_align(*offset
, get_alignment(fac
, field
),
938 /* remember offset */
939 field
->offset_root
= *offset
;
941 *offset
= field
->offset_root
;
943 for(i
=0; i
<type
->fields
->len
; i
++) {
944 child
= &g_array_index(type
->fields
, LttField
, i
);
945 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
954 if(field
->fixed_root
== FIELD_VARIABLE
) {
955 *offset
+= ltt_align(*offset
, get_alignment(field
),
957 /* remember offset */
958 field
->offset_root
= *offset
;
960 for(i
=0; i
<type
->fields
->len
; i
++) {
961 *offset
= field
->offset_root
;
962 child
= &g_array_index(type
->fields
, LttField
, i
);
963 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
965 *offset
= field
->offset_root
+ field
->field_size
;
970 g_error("compute_fields_offsets : unknown type");
976 /*****************************************************************************
978 * compute_offsets : set the dynamically computable offsets of an event type
983 ****************************************************************************/
984 void compute_offsets(LttTracefile
*tf
, LttFacility
*fac
,
985 LttEventType
*event
, off_t
*offset
, void *root
)
989 /* compute all variable offsets */
990 for(i
=0; i
<event
->fields
->len
; i
++) {
991 //g_debug("computing offset %u of %u\n", i, event->fields->len-1);
992 LttField
*field
= &g_array_index(event
->fields
, LttField
, i
);
993 compute_fields_offsets(tf
, fac
, field
, offset
, root
);