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
,
41 LttFacility
*fac
, LttField
*field
, off_t
*offset
, void *root
);
44 LttEvent
*ltt_event_new()
46 return g_new(LttEvent
, 1);
49 void ltt_event_destroy(LttEvent
*event
)
56 /* Use get_field_type_size instead */
57 /*****************************************************************************
59 * ltt_event_refresh_fields : refresh fields of an event
61 * offsetRoot : offset from the root
62 * offsetParent : offset from the parent
65 * reverse_byte_order : 1 or 0
67 * int : size of the field
68 ****************************************************************************/
70 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
71 LttField
* fld
, void *evD
, gboolean reverse_byte_order
)
73 int size
, size1
, element_number
, i
, offset1
, offset2
;
74 LttType
* type
= fld
->field_type
;
76 switch(type
->type_class
) {
78 element_number
= (int) type
->element_number
;
79 if(fld
->field_fixed
== 0){// has string or sequence
81 for(i
=0;i
<element_number
;i
++){
82 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
83 fld
->child
[0], evD
+size
, reverse_byte_order
);
85 }else size
= fld
->field_size
;
89 size1
= fld
->sequ_number_size
;
90 element_number
= getIntNumber(reverse_byte_order
,size1
,evD
);
91 type
->element_number
= element_number
;
92 if(fld
->element_size
> 0){
93 size
= element_number
* fld
->element_size
;
94 }else{//sequence has string or sequence
96 for(i
=0;i
<element_number
;i
++){
97 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
98 fld
->child
[0], evD
+size
+size1
, reverse_byte_order
);
105 size
= strlen((gchar
*)evD
) + 1; //include end : '\0'
109 element_number
= (int) type
->element_number
;
110 if(fld
->field_fixed
== 0){
111 offset1
= offsetRoot
;
113 for(i
=0;i
<element_number
;i
++){
114 size
=ltt_event_refresh_fields(offset1
,offset2
,
115 fld
->child
[i
],evD
+offset2
, reverse_byte_order
);
120 }else size
= fld
->field_size
;
124 size
= fld
->field_size
;
128 size
= fld
->field_size
;
132 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
133 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
134 size
= fld
->field_size
;
135 }else if(type
->type_class
== LTT_ARRAY
){
136 element_number
= (int) type
->element_number
;
137 if(fld
->field_fixed
== 0){// has string or sequence
139 for(i
=0;i
<element_number
;i
++){
140 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
141 fld
->child
[0], evD
+size
);
143 }else size
= fld
->field_size
;
144 }else if(type
->type_class
== LTT_SEQUENCE
){
145 size1
= fld
->sequ_number_size
;
146 element_number
= getIntNumber(size1
,evD
);
147 type
->element_number
= element_number
;
148 if(fld
->element_size
> 0){
149 size
= element_number
* fld
->element_size
;
150 }else{//sequence has string or sequence
152 for(i
=0;i
<element_number
;i
++){
153 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
154 fld
->child
[0], evD
+size
+size1
);
158 }else if(type
->type_class
== LTT_STRING
){
159 size
= strlen((char*)evD
) + 1; //include end : '\0'
160 }else if(type
->type_class
== LTT_STRUCT
){
161 element_number
= (int) type
->element_number
;
162 if(fld
->field_fixed
== 0){
163 offset1
= offsetRoot
;
165 for(i
=0;i
<element_number
;i
++){
166 size
=ltt_event_refresh_fields(offset1
,offset2
,
167 fld
->child
[i
],evD
+offset2
);
172 }else size
= fld
->field_size
;
175 fld
->offset_root
= offsetRoot
;
176 fld
->offset_parent
= offsetParent
;
177 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
178 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
179 fld
->field_size
= size
;
186 /*****************************************************************************
188 * ltt_event_eventtype_id: get event type id
189 * (base id + position of the event)
191 * e : an instance of an event type
193 * unsigned : event type id
194 ****************************************************************************/
196 unsigned ltt_event_eventtype_id(const LttEvent
*e
)
198 return (unsigned) e
->event_id
;
201 /*****************************************************************************
203 * ltt_event_facility : get the facility of the event
205 * e : an instance of an event type
207 * LttFacility * : the facility of the event
208 ****************************************************************************/
210 LttFacility
*ltt_event_facility(const LttEvent
*e
)
212 LttTrace
* trace
= e
->tracefile
->trace
;
213 unsigned id
= e
->facility_id
;
214 LttFacility
*facility
= ltt_trace_facility_by_id(trace
,id
);
216 g_assert(facility
->exists
);
221 /*****************************************************************************
223 * ltt_event_facility_id : get the facility id of the event
225 * e : an instance of an event type
227 * unsigned : the facility of the event
228 ****************************************************************************/
230 unsigned ltt_event_facility_id(const LttEvent
*e
)
232 return e
->facility_id
;
235 /*****************************************************************************
237 * ltt_event_eventtype : get the event type of the event
239 * e : an instance of an event type
241 * LttEventType * : the event type of the event
242 ****************************************************************************/
244 LttEventType
*ltt_event_eventtype(const LttEvent
*e
)
246 LttFacility
* facility
= ltt_event_facility(e
);
247 if(!facility
) return NULL
;
248 return &g_array_index(facility
->events
, LttEventType
, e
->event_id
);
252 /*****************************************************************************
254 * ltt_event_time : get the time of the event
256 * e : an instance of an event type
258 * LttTime : the time of the event
259 ****************************************************************************/
261 LttTime
ltt_event_time(const LttEvent
*e
)
263 return e
->event_time
;
266 /*****************************************************************************
268 * ltt_event_time : get the cycle count of the event
270 * e : an instance of an event type
272 * LttCycleCount : the cycle count of the event
273 ****************************************************************************/
275 LttCycleCount
ltt_event_cycle_count(const LttEvent
*e
)
282 /*****************************************************************************
284 * ltt_event_position_get : get the event position data
286 * e : an instance of an event type
287 * ep : a pointer to event's position structure
288 * tf : tracefile pointer
289 * block : current block
290 * offset : current offset
292 ****************************************************************************/
293 void ltt_event_position_get(LttEventPosition
*ep
, LttTracefile
**tf
,
294 guint
*block
, guint
*offset
, guint64
*tsc
)
298 *offset
= ep
->offset
;
303 /*****************************************************************************
305 * ltt_event_position : get the event's position
307 * e : an instance of an event type
308 * ep : a pointer to event's position structure
309 ****************************************************************************/
311 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
313 ep
->tracefile
= e
->tracefile
;
314 ep
->block
= e
->block
;
315 ep
->offset
= e
->offset
;
319 LttEventPosition
* ltt_event_position_new()
321 return g_new(LttEventPosition
, 1);
325 /*****************************************************************************
327 * ltt_event_position_compare : compare two positions
328 * A NULL value is infinite.
330 * ep1 : a pointer to event's position structure
331 * ep2 : a pointer to event's position structure
336 ****************************************************************************/
339 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
340 const LttEventPosition
*ep2
)
342 if(ep1
== NULL
&& ep2
== NULL
)
344 if(ep1
!= NULL
&& ep2
== NULL
)
346 if(ep1
== NULL
&& ep2
!= NULL
)
349 if(ep1
->tracefile
!= ep2
->tracefile
)
350 g_error("ltt_event_position_compare on different tracefiles makes no sense");
352 if(ep1
->block
< ep2
->block
)
354 if(ep1
->block
> ep2
->block
)
356 if(ep1
->offset
< ep2
->offset
)
358 if(ep1
->offset
> ep2
->offset
)
363 /*****************************************************************************
365 * ltt_event_position_copy : copy position
367 * src : a pointer to event's position structure source
368 * dest : a pointer to event's position structure dest
371 ****************************************************************************/
372 void ltt_event_position_copy(LttEventPosition
*dest
,
373 const LttEventPosition
*src
)
383 LttTracefile
*ltt_event_position_tracefile(LttEventPosition
*ep
)
385 return ep
->tracefile
;
388 /*****************************************************************************
390 * ltt_event_cpu_i: get the cpu id where the event happens
392 * e : an instance of an event type
394 * unsigned : the cpu id
395 ****************************************************************************/
397 unsigned ltt_event_cpu_id(LttEvent
*e
)
399 return e
->tracefile
->cpu_num
;
402 /*****************************************************************************
404 * ltt_event_data : get the raw data for the event
406 * e : an instance of an event type
408 * void * : pointer to the raw data for the event
409 ****************************************************************************/
411 void *ltt_event_data(LttEvent
*e
)
416 /*****************************************************************************
418 * ltt_event_field_element_number
419 * : The number of elements in a sequence field is specific
420 * to each event. This function returns the number of
421 * elements for an array or sequence field in an event.
423 * e : an instance of an event type
424 * f : a field of the instance
426 * unsigned : the number of elements for an array/sequence field
427 ****************************************************************************/
428 guint64
ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
430 if(f
->field_type
.type_class
!= LTT_ARRAY
&&
431 f
->field_type
.type_class
!= LTT_SEQUENCE
)
434 if(f
->field_type
.type_class
== LTT_ARRAY
)
435 return f
->field_type
.size
;
436 return ltt_event_get_long_unsigned(e
, &g_array_index(f
->field_type
.fields
,
440 /*****************************************************************************
442 * ltt_event_field_element_select
443 * : Set the currently selected element for a sequence or
445 * O(1) because of offset array.
447 * e : an instance of an event type
448 * f : a field of the instance
449 * i : the ith element (0, ...)
450 *returns : the child field, at the right index, updated.
451 ****************************************************************************/
452 LttField
*ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, gulong i
)
454 gulong element_number
;
458 LttEventType
*event_type
;
461 if(f
->field_type
.type_class
!= LTT_ARRAY
&&
462 f
->field_type
.type_class
!= LTT_SEQUENCE
)
465 element_number
= ltt_event_field_element_number(e
,f
);
466 event_type
= ltt_event_eventtype(e
);
467 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
469 if(i
>= element_number
) return NULL
;
471 if(f
->field_type
.type_class
== LTT_ARRAY
) {
472 field
= &g_array_index(f
->field_type
.fields
, LttField
, 0);
474 field
= &g_array_index(f
->field_type
.fields
, LttField
, 1);
477 if(field
->field_size
!= 0) {
478 if(f
->array_offset
+ (i
* field
->field_size
) == field
->offset_root
)
479 return field
; /* fixed length child, already at the right offset */
481 new_offset
= f
->array_offset
+ (i
* field
->field_size
);
483 /* Var. len. child */
484 new_offset
= g_array_index(f
->dynamic_offsets
, off_t
, i
);
486 compute_fields_offsets(e
->tracefile
,
487 ltt_event_facility(e
), field
, &new_offset
, e
->data
);
493 off_t
ltt_event_field_offset(LttEvent
*e
, LttField
*f
)
495 return f
->offset_root
;
500 /*****************************************************************************
501 * These functions extract data from an event after architecture specific
503 ****************************************************************************/
504 guint32
ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
506 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
508 LttTypeEnum t
= f
->field_type
.type_class
;
510 if(f
->field_size
== 1){
511 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
513 }else if(f
->field_size
== 2){
514 return (guint32
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
515 }else if(f
->field_size
== 4){
516 return (guint32
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
519 else if(f
->field_size
== 8){
520 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
521 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
522 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
524 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
527 g_critical("ltt_event_get_unsigned : field size %i unknown", f
->field_size
);
531 gint32
ltt_event_get_int(LttEvent
*e
, LttField
*f
)
533 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
535 if(f
->field_size
== 1){
536 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
538 }else if(f
->field_size
== 2){
539 return (gint32
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
540 }else if(f
->field_size
== 4){
541 return (gint32
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
544 else if(f
->field_size
== 8){
545 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
546 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
547 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
549 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
552 g_critical("ltt_event_get_int : field size %i unknown", f
->field_size
);
556 guint64
ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
558 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
560 LttTypeEnum t
= f
->field_type
.type_class
;
562 if(f
->field_size
== 1){
563 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
565 }else if(f
->field_size
== 2){
566 return (guint64
)ltt_get_uint16(reverse_byte_order
, e
->data
+ f
->offset_root
);
567 }else if(f
->field_size
== 4){
568 return (guint64
)ltt_get_uint32(reverse_byte_order
, e
->data
+ f
->offset_root
);
569 }else if(f
->field_size
== 8){
570 return ltt_get_uint64(reverse_byte_order
, e
->data
+ f
->offset_root
);
572 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f
->field_size
);
576 gint64
ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
578 //int revFlag = e->tracefile->trace->my_arch_endian ==
579 // e->tracefile->trace->system_description->endian ? 0:1;
580 gboolean reverse_byte_order
= LTT_GET_BO(e
->tracefile
);
582 if(f
->field_size
== 1){
583 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
585 }else if(f
->field_size
== 2){
586 return (gint64
)ltt_get_int16(reverse_byte_order
, e
->data
+ f
->offset_root
);
587 }else if(f
->field_size
== 4){
588 return (gint64
)ltt_get_int32(reverse_byte_order
, e
->data
+ f
->offset_root
);
589 }else if(f
->field_size
== 8){
590 return ltt_get_int64(reverse_byte_order
, e
->data
+ f
->offset_root
);
592 g_critical("ltt_event_get_long_int : field size %i unknown", f
->field_size
);
596 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
598 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
599 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
601 g_assert(f
->field_type
.type_class
== LTT_FLOAT
&& f
->field_size
== 4);
603 if(reverse_byte_order
== 0) return *(float *)(e
->data
+ f
->offset_root
);
605 void *ptr
= e
->data
+ f
->offset_root
;
606 guint32 value
= bswap_32(*(guint32
*)ptr
);
607 return *(float*)&value
;
611 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
613 g_assert(LTT_HAS_FLOAT(e
->tracefile
));
614 gboolean reverse_byte_order
= LTT_GET_FLOAT_BO(e
->tracefile
);
616 if(f
->field_size
== 4)
617 return ltt_event_get_float(e
, f
);
619 g_assert(f
->field_type
.type_class
== LTT_FLOAT
&& f
->field_size
== 8);
621 if(reverse_byte_order
== 0) return *(double *)(e
->data
+ f
->offset_root
);
623 void *ptr
= e
->data
+ f
->offset_root
;
624 guint64 value
= bswap_64(*(guint64
*)ptr
);
625 return *(double*)&value
;
629 /*****************************************************************************
630 * The string obtained is only valid until the next read from
631 * the same tracefile.
632 ****************************************************************************/
633 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
635 g_assert(f
->field_type
.type_class
== LTT_STRING
);
637 return (gchar
*)g_strdup((gchar
*)(e
->data
+ f
->offset_root
));
641 /*****************************************************************************
643 * get_field_type_size : set the fixed and dynamic sizes of the field type
644 * from the data read.
647 * event_type : event type
648 * offset_root : offset from the root
649 * offset_parent : offset from the parent
651 * data : a pointer to the event data.
652 *Returns the field type size.
653 ****************************************************************************/
655 // Change this function so it uses a *to offset value incrementation, just like
656 // genevent-new instead of returning a size. What is of interest here is the
657 // offset needed to read each field.
659 // Precomputed ones can be returned directly. Otherwise, the field is flagged
660 // "VARIABLE OFFSET" and must be computed dynamically. The dynamic processing
661 // of an offset takes the last known fixed offset, and then dynamically
662 // calculates all variable field offsets from it.
664 // After a VARIABLE SIZE element, all fields have a variable offset.
665 // Also, is an array or a sequence has variable length child, we must pass
666 // through all of them, saving the offsets in the dynamic_offsets array.
669 size_t get_field_type_size(LttTracefile
*tf
, LttEventType
*event_type
,
670 off_t offset_root
, off_t offset_parent
,
671 LttField
*field
, void *data
)
678 g_assert(field
->fixed_root
!= FIELD_UNKNOWN
);
679 g_assert(field
->fixed_parent
!= FIELD_UNKNOWN
);
680 g_assert(field
->fixed_size
!= FIELD_UNKNOWN
);
682 field
->offset_root
= offset_root
;
683 field
->offset_parent
= offset_parent
;
685 type
= field
->field_type
;
687 switch(type
->type_class
) {
698 g_assert(field
->fixed_size
== FIELD_FIXED
);
699 size
= field
->field_size
;
700 align
= ltt_align(field
->offset_root
,
701 size
, event_type
->facility
->alignment
);
702 field
->offset_root
+= align
;
703 field
->offset_parent
+= align
;
708 /* FIXME : check the type of sequence identifier */
709 gint seqnum
= ltt_get_uint(LTT_GET_BO(tf
),
710 field
->sequ_number_size
,
713 if(field
->child
[0]->fixed_size
== FIELD_FIXED
) {
714 size
= field
->sequ_number_size
+
715 (seqnum
* get_field_type_size(tf
, event_type
,
716 offset_root
, offset_parent
,
717 field
->child
[0], data
));
719 size
+= field
->sequ_number_size
;
720 for(i
=0;i
<seqnum
;i
++) {
722 child_size
= get_field_type_size(tf
, event_type
,
723 offset_root
, offset_parent
,
724 field
->child
[0], data
);
725 offset_root
+= child_size
;
726 offset_parent
+= child_size
;
730 field
->field_size
= size
;
734 size
= strlen((char*)(data
+offset_root
)) + 1;// length + \0
735 field
->field_size
= size
;
738 if(field
->fixed_size
== FIELD_FIXED
)
739 size
= field
->field_size
;
741 for(i
=0;i
<field
->field_type
->element_number
;i
++) {
743 child_size
= get_field_type_size(tf
, event_type
,
744 offset_root
, offset_parent
,
745 field
->child
[0], data
);
746 offset_root
+= child_size
;
747 offset_parent
+= child_size
;
750 field
->field_size
= size
;
754 if(field
->fixed_size
== FIELD_FIXED
)
755 size
= field
->field_size
;
757 size_t current_root_offset
= offset_root
;
758 size_t current_offset
= 0;
759 size_t child_size
= 0;
760 for(i
=0;i
<type
->element_number
;i
++) {
761 child_size
= get_field_type_size(tf
,
762 event_type
, current_root_offset
, current_offset
,
763 field
->child
[i
], data
);
764 current_offset
+= child_size
;
765 current_root_offset
+= child_size
;
768 size
= current_offset
;
769 field
->field_size
= size
;
773 if(field
->fixed_size
== FIELD_FIXED
)
774 size
= field
->field_size
;
776 size_t current_root_offset
= field
->offset_root
;
777 size_t current_offset
= 0;
778 for(i
=0;i
<type
->element_number
;i
++) {
779 size
= get_field_type_size(tf
, event_type
,
780 current_root_offset
, current_offset
,
781 field
->child
[i
], data
);
782 size
= max(size
, field
->child
[i
]->field_size
);
784 field
->field_size
= size
;
797 /*****************************************************************************
799 * compute_fields_offsets : set the precomputable offset of the fields
803 * offset : pointer to the current offset, must be incremented
804 ****************************************************************************/
807 void compute_fields_offsets(LttTracefile
*tf
,
808 LttFacility
*fac
, LttField
*field
, off_t
*offset
, void *root
)
810 LttType
*type
= &field
->field_type
;
812 switch(type
->type_class
) {
829 if(field
->fixed_root
== FIELD_VARIABLE
) {
830 /* Align offset on type size */
831 *offset
+= ltt_align(*offset
, get_alignment(field
),
833 /* remember offset */
834 field
->offset_root
= *offset
;
835 /* Increment offset */
836 *offset
+= field
->field_size
;
838 //g_debug("type before offset : %llu %llu %u\n", *offset,
839 // field->offset_root,
840 // field->field_size);
841 *offset
= field
->offset_root
;
842 *offset
+= field
->field_size
;
843 //g_debug("type after offset : %llu\n", *offset);
847 if(field
->fixed_root
== FIELD_VARIABLE
) {
848 field
->offset_root
= *offset
;
850 *offset
+= strlen((gchar
*)(root
+*offset
)) + 1;
851 /* Realign the data */
852 *offset
+= ltt_align(*offset
, fac
->pointer_size
,
856 g_assert(type
->fields
->len
== 1);
859 LttField
*child
= &g_array_index(type
->fields
, LttField
, 0);
860 if(field
->fixed_root
== FIELD_VARIABLE
) {
861 *offset
+= ltt_align(*offset
, get_alignment(field
),
863 /* remember offset */
864 field
->offset_root
= *offset
;
865 field
->array_offset
= *offset
;
868 if(field
->field_size
!= 0) {
869 /* Increment offset */
870 /* field_size is the array size in bytes */
871 *offset
= field
->offset_root
+ field
->field_size
;
874 *offset
= field
->array_offset
;
875 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
877 for(i
=0; i
<type
->size
; i
++) {
878 g_array_append_val(field
->dynamic_offsets
, *offset
);
879 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
882 // local_offset = field->array_offset;
883 // /* Set the offset at position 0 */
884 // compute_fields_offsets(tf, fac, child, &local_offset, root);
888 g_assert(type
->fields
->len
== 2);
894 if(field
->fixed_root
== FIELD_VARIABLE
) {
895 *offset
+= ltt_align(*offset
, get_alignment(field
),
897 /* remember offset */
898 field
->offset_root
= *offset
;
900 child
= &g_array_index(type
->fields
, LttField
, 0);
901 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
902 child
= &g_array_index(type
->fields
, LttField
, 1);
903 *offset
+= ltt_align(*offset
, get_alignment(child
),
905 field
->array_offset
= *offset
;
908 child
= &g_array_index(type
->fields
, LttField
, 1);
910 *offset
= field
->array_offset
;
911 field
->dynamic_offsets
= g_array_set_size(field
->dynamic_offsets
,
913 num_elem
= ltt_event_field_element_number(&tf
->event
, field
);
914 for(i
=0; i
<num_elem
; i
++) {
915 g_array_append_val(field
->dynamic_offsets
, *offset
);
916 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
918 g_assert(num_elem
== field
->dynamic_offsets
->len
);
920 /* Realign the data */
921 *offset
+= ltt_align(*offset
, fac
->pointer_size
,
924 // local_offset = field->array_offset;
925 // /* Set the offset at position 0 */
926 // compute_fields_offsets(tf, fac, child, &local_offset, root);
934 if(field
->fixed_root
== FIELD_VARIABLE
) {
935 *offset
+= ltt_align(*offset
, get_alignment(fac
, field
),
937 /* remember offset */
938 field
->offset_root
= *offset
;
940 *offset
= field
->offset_root
;
942 for(i
=0; i
<type
->fields
->len
; i
++) {
943 child
= &g_array_index(type
->fields
, LttField
, i
);
944 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
953 if(field
->fixed_root
== FIELD_VARIABLE
) {
954 *offset
+= ltt_align(*offset
, get_alignment(field
),
956 /* remember offset */
957 field
->offset_root
= *offset
;
959 for(i
=0; i
<type
->fields
->len
; i
++) {
960 *offset
= field
->offset_root
;
961 child
= &g_array_index(type
->fields
, LttField
, i
);
962 compute_fields_offsets(tf
, fac
, child
, offset
, root
);
964 *offset
= field
->offset_root
+ field
->field_size
;
969 g_error("compute_fields_offsets : unknown type");
975 /*****************************************************************************
977 * compute_offsets : set the dynamically computable offsets of an event type
982 ****************************************************************************/
983 void compute_offsets(LttTracefile
*tf
, LttFacility
*fac
,
984 LttEventType
*event
, off_t
*offset
, void *root
)
988 /* compute all variable offsets */
989 for(i
=0; i
<event
->fields
->len
; i
++) {
990 //g_debug("computing offset %u of %u\n", i, event->fields->len-1);
991 LttField
*field
= &g_array_index(event
->fields
, LttField
, i
);
992 compute_fields_offsets(tf
, fac
, field
, offset
, root
);