Make sure libtraceread is completely licensed LGPL
[lttv.git] / ltt / branches / poly / ltt / event.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
3 * 2006 Mathieu Desnoyers
4 *
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.
8 *
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.
13 *
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.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <glib.h>
28
29 #include <asm/types.h>
30 #include <byteswap.h>
31
32 #include "parser.h"
33 #include <ltt/ltt.h>
34 #include "ltt-private.h"
35 #include <ltt/event.h>
36 #include <ltt/trace.h>
37 #include <ltt/ltt-types.h>
38
39
40
41 void compute_fields_offsets(LttTracefile *tf,
42 LttFacility *fac, LttField *field, off_t *offset, void *root);
43
44
45 LttEvent *ltt_event_new()
46 {
47 return g_new(LttEvent, 1);
48 }
49
50 void ltt_event_destroy(LttEvent *event)
51 {
52 g_free(event);
53 }
54
55
56 #if 0
57 /* Use get_field_type_size instead */
58 /*****************************************************************************
59 *Function name
60 * ltt_event_refresh_fields : refresh fields of an event
61 *Input params
62 * offsetRoot : offset from the root
63 * offsetParent : offset from the parent
64 * fld : field
65 * evD : event data
66 * reverse_byte_order : 1 or 0
67 *Return value
68 * int : size of the field
69 ****************************************************************************/
70
71 int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
72 LttField * fld, void *evD, gboolean reverse_byte_order)
73 {
74 int size, size1, element_number, i, offset1, offset2;
75 LttType * type = fld->field_type;
76
77 switch(type->type_class) {
78 case LTT_ARRAY:
79 element_number = (int) type->element_number;
80 if(fld->field_fixed == 0){// has string or sequence
81 size = 0;
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);
85 }
86 }else size = fld->field_size;
87 break;
88
89 case LTT_SEQUENCE:
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
96 size = 0;
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);
100 }
101 size += size1;
102 }
103 break;
104
105 case LTT_STRING:
106 size = strlen((gchar*)evD) + 1; //include end : '\0'
107 break;
108
109 case LTT_STRUCT:
110 element_number = (int) type->element_number;
111 if(fld->field_fixed == 0){
112 offset1 = offsetRoot;
113 offset2 = 0;
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);
117 offset1 += size;
118 offset2 += size;
119 }
120 size = offset2;
121 }else size = fld->field_size;
122 break;
123
124 case LTT_UNION:
125 size = fld->field_size;
126 break;
127
128 default:
129 size = fld->field_size;
130 }
131
132 #if 0
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
139 size = 0;
140 for(i=0;i<element_number;i++){
141 size += ltt_event_refresh_fields(offsetRoot+size,size,
142 fld->child[0], evD+size);
143 }
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
152 size = 0;
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);
156 }
157 size += size1;
158 }
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;
165 offset2 = 0;
166 for(i=0;i<element_number;i++){
167 size=ltt_event_refresh_fields(offset1,offset2,
168 fld->child[i],evD+offset2);
169 offset1 += size;
170 offset2 += size;
171 }
172 size = offset2;
173 }else size = fld->field_size;
174 }
175 #endif //0
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;
181
182 return size;
183 }
184 #endif //0
185
186
187 /*****************************************************************************
188 *Function name
189 * ltt_event_eventtype_id: get event type id
190 * (base id + position of the event)
191 *Input params
192 * e : an instance of an event type
193 *Return value
194 * unsigned : event type id
195 ****************************************************************************/
196
197 unsigned ltt_event_eventtype_id(const LttEvent *e)
198 {
199 return (unsigned) e->event_id;
200 }
201
202 /*****************************************************************************
203 *Function name
204 * ltt_event_facility : get the facility of the event
205 *Input params
206 * e : an instance of an event type
207 *Return value
208 * LttFacility * : the facility of the event
209 ****************************************************************************/
210
211 LttFacility *ltt_event_facility(const LttEvent *e)
212 {
213 LttTrace * trace = e->tracefile->trace;
214 unsigned id = e->facility_id;
215 LttFacility *facility = ltt_trace_facility_by_id(trace,id);
216
217 g_assert(facility->exists);
218
219 return facility;
220 }
221
222 /*****************************************************************************
223 *Function name
224 * ltt_event_facility_id : get the facility id of the event
225 *Input params
226 * e : an instance of an event type
227 *Return value
228 * unsigned : the facility of the event
229 ****************************************************************************/
230
231 unsigned ltt_event_facility_id(const LttEvent *e)
232 {
233 return e->facility_id;
234 }
235
236 /*****************************************************************************
237 *Function name
238 * ltt_event_eventtype : get the event type of the event
239 *Input params
240 * e : an instance of an event type
241 *Return value
242 * LttEventType * : the event type of the event
243 ****************************************************************************/
244
245 LttEventType *ltt_event_eventtype(const LttEvent *e)
246 {
247 LttFacility* facility = ltt_event_facility(e);
248 if(!facility) return NULL;
249 return &g_array_index(facility->events, LttEventType, e->event_id);
250 }
251
252
253 /*****************************************************************************
254 *Function name
255 * ltt_event_time : get the time of the event
256 *Input params
257 * e : an instance of an event type
258 *Return value
259 * LttTime : the time of the event
260 ****************************************************************************/
261
262 LttTime ltt_event_time(const LttEvent *e)
263 {
264 return e->event_time;
265 }
266
267 /*****************************************************************************
268 *Function name
269 * ltt_event_time : get the cycle count of the event
270 *Input params
271 * e : an instance of an event type
272 *Return value
273 * LttCycleCount : the cycle count of the event
274 ****************************************************************************/
275
276 LttCycleCount ltt_event_cycle_count(const LttEvent *e)
277 {
278 return e->tsc;
279 }
280
281
282
283 /*****************************************************************************
284 *Function name
285 * ltt_event_position_get : get the event position data
286 *Input params
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
292 * tsc : current tsc
293 ****************************************************************************/
294 void ltt_event_position_get(LttEventPosition *ep, LttTracefile **tf,
295 guint *block, guint *offset, guint64 *tsc)
296 {
297 *tf = ep->tracefile;
298 *block = ep->block;
299 *offset = ep->offset;
300 *tsc = ep->tsc;
301 }
302
303
304 /*****************************************************************************
305 *Function name
306 * ltt_event_position : get the event's position
307 *Input params
308 * e : an instance of an event type
309 * ep : a pointer to event's position structure
310 ****************************************************************************/
311
312 void ltt_event_position(LttEvent *e, LttEventPosition *ep)
313 {
314 ep->tracefile = e->tracefile;
315 ep->block = e->block;
316 ep->offset = e->offset;
317 ep->tsc = e->tsc;
318 }
319
320 LttEventPosition * ltt_event_position_new()
321 {
322 return g_new(LttEventPosition, 1);
323 }
324
325
326 /*****************************************************************************
327 * Function name
328 * ltt_event_position_compare : compare two positions
329 * A NULL value is infinite.
330 * Input params
331 * ep1 : a pointer to event's position structure
332 * ep2 : a pointer to event's position structure
333 * Return
334 * -1 is ep1 < ep2
335 * 1 if ep1 > ep2
336 * 0 if ep1 == ep2
337 ****************************************************************************/
338
339
340 gint ltt_event_position_compare(const LttEventPosition *ep1,
341 const LttEventPosition *ep2)
342 {
343 if(ep1 == NULL && ep2 == NULL)
344 return 0;
345 if(ep1 != NULL && ep2 == NULL)
346 return -1;
347 if(ep1 == NULL && ep2 != NULL)
348 return 1;
349
350 if(ep1->tracefile != ep2->tracefile)
351 g_error("ltt_event_position_compare on different tracefiles makes no sense");
352
353 if(ep1->block < ep2->block)
354 return -1;
355 if(ep1->block > ep2->block)
356 return 1;
357 if(ep1->offset < ep2->offset)
358 return -1;
359 if(ep1->offset > ep2->offset)
360 return 1;
361 return 0;
362 }
363
364 /*****************************************************************************
365 * Function name
366 * ltt_event_position_copy : copy position
367 * Input params
368 * src : a pointer to event's position structure source
369 * dest : a pointer to event's position structure dest
370 * Return
371 * void
372 ****************************************************************************/
373 void ltt_event_position_copy(LttEventPosition *dest,
374 const LttEventPosition *src)
375 {
376 if(src == NULL)
377 dest = NULL;
378 else
379 *dest = *src;
380 }
381
382
383
384 LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep)
385 {
386 return ep->tracefile;
387 }
388
389 /*****************************************************************************
390 *Function name
391 * ltt_event_cpu_i: get the cpu id where the event happens
392 *Input params
393 * e : an instance of an event type
394 *Return value
395 * unsigned : the cpu id
396 ****************************************************************************/
397
398 unsigned ltt_event_cpu_id(LttEvent *e)
399 {
400 return e->tracefile->cpu_num;
401 }
402
403 /*****************************************************************************
404 *Function name
405 * ltt_event_data : get the raw data for the event
406 *Input params
407 * e : an instance of an event type
408 *Return value
409 * void * : pointer to the raw data for the event
410 ****************************************************************************/
411
412 void *ltt_event_data(LttEvent *e)
413 {
414 return e->data;
415 }
416
417 /*****************************************************************************
418 *Function name
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.
423 *Input params
424 * e : an instance of an event type
425 * f : a field of the instance
426 *Return value
427 * unsigned : the number of elements for an array/sequence field
428 ****************************************************************************/
429 guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
430 {
431 if(f->field_type.type_class != LTT_ARRAY &&
432 f->field_type.type_class != LTT_SEQUENCE)
433 return 0;
434
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,
438 LttField, 0));
439 }
440
441 /*****************************************************************************
442 *Function name
443 * ltt_event_field_element_select
444 * : Set the currently selected element for a sequence or
445 * array field
446 * O(1) because of offset array.
447 *Input params
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)
454 {
455 gulong element_number;
456 LttField *field;
457 unsigned int k;
458 size_t size;
459 LttEventType *event_type;
460 off_t new_offset;
461
462 if(f->field_type.type_class != LTT_ARRAY &&
463 f->field_type.type_class != LTT_SEQUENCE)
464 return NULL;
465
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
469 */
470 if(i >= element_number) return NULL;
471
472 if(f->field_type.type_class == LTT_ARRAY) {
473 field = &g_array_index(f->field_type.fields, LttField, 0);
474 } else {
475 field = &g_array_index(f->field_type.fields, LttField, 1);
476 }
477
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 */
481 else
482 new_offset = f->array_offset + (i * field->field_size);
483 } else {
484 /* Var. len. child */
485 new_offset = g_array_index(f->dynamic_offsets, off_t, i);
486 }
487 compute_fields_offsets(e->tracefile,
488 ltt_event_facility(e), field, &new_offset, e->data);
489
490 return field;
491 }
492
493
494 off_t ltt_event_field_offset(LttEvent *e, LttField *f)
495 {
496 return f->offset_root;
497 }
498
499
500
501 /*****************************************************************************
502 * These functions extract data from an event after architecture specific
503 * conversions
504 ****************************************************************************/
505 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
506 {
507 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
508
509 LttTypeEnum t = f->field_type.type_class;
510
511 if(f->field_size == 1){
512 guint8 x = *(guint8 *)(e->data + f->offset_root);
513 return (guint32) x;
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);
518 }
519 #if 0
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);
524 else
525 return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);
526 }
527 #endif //0
528 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
529 return 0;
530 }
531
532 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
533 {
534 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
535
536 if(f->field_size == 1){
537 gint8 x = *(gint8 *)(e->data + f->offset_root);
538 return (gint32) x;
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);
543 }
544 #if 0
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);
549 else
550 return (int) (revFlag ? GINT64_FROM_LE(x): x);
551 }
552 #endif //0
553 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
554 return 0;
555 }
556
557 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
558 {
559 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
560
561 LttTypeEnum t = f->field_type.type_class;
562
563 if(f->field_size == 1){
564 guint8 x = *(guint8 *)(e->data + f->offset_root);
565 return (guint64) x;
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);
572 }
573 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
574 return 0;
575 }
576
577 gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
578 {
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);
582
583 if(f->field_size == 1){
584 gint8 x = *(gint8 *)(e->data + f->offset_root);
585 return (gint64) x;
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);
592 }
593 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
594 return 0;
595 }
596
597 float ltt_event_get_float(LttEvent *e, LttField *f)
598 {
599 g_assert(LTT_HAS_FLOAT(e->tracefile));
600 gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
601
602 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 4);
603
604 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
605 else{
606 void *ptr = e->data + f->offset_root;
607 guint32 value = bswap_32(*(guint32*)ptr);
608 return *(float*)&value;
609 }
610 }
611
612 double ltt_event_get_double(LttEvent *e, LttField *f)
613 {
614 g_assert(LTT_HAS_FLOAT(e->tracefile));
615 gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
616
617 if(f->field_size == 4)
618 return ltt_event_get_float(e, f);
619
620 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 8);
621
622 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
623 else {
624 void *ptr = e->data + f->offset_root;
625 guint64 value = bswap_64(*(guint64*)ptr);
626 return *(double*)&value;
627 }
628 }
629
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)
635 {
636 g_assert(f->field_type.type_class == LTT_STRING);
637
638 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
639 }
640
641
642 /*****************************************************************************
643 *Function name
644 * get_field_type_size : set the fixed and dynamic sizes of the field type
645 * from the data read.
646 *Input params
647 * tf : tracefile
648 * event_type : event type
649 * offset_root : offset from the root
650 * offset_parent : offset from the parent
651 * field : field
652 * data : a pointer to the event data.
653 *Returns the field type size.
654 ****************************************************************************/
655 // TODO
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.
659 //
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.
664 //
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.
668
669 #if 0
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)
673 {
674 size_t size = 0;
675 guint i;
676 LttType *type;
677 off_t align;
678
679 g_assert(field->fixed_root != FIELD_UNKNOWN);
680 g_assert(field->fixed_parent != FIELD_UNKNOWN);
681 g_assert(field->fixed_size != FIELD_UNKNOWN);
682
683 field->offset_root = offset_root;
684 field->offset_parent = offset_parent;
685
686 type = field->field_type;
687
688 switch(type->type_class) {
689 case LTT_INT:
690 case LTT_UINT:
691 case LTT_FLOAT:
692 case LTT_ENUM:
693 case LTT_POINTER:
694 case LTT_LONG:
695 case LTT_ULONG:
696 case LTT_SIZE_T:
697 case LTT_SSIZE_T:
698 case LTT_OFF_T:
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;
705 size += align;
706 break;
707 case LTT_SEQUENCE:
708 {
709 /* FIXME : check the type of sequence identifier */
710 gint seqnum = ltt_get_uint(LTT_GET_BO(tf),
711 field->sequ_number_size,
712 data + offset_root);
713
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));
719 } else {
720 size += field->sequ_number_size;
721 for(i=0;i<seqnum;i++) {
722 size_t child_size;
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;
728 size += child_size;
729 }
730 }
731 field->field_size = size;
732 }
733 break;
734 case LTT_STRING:
735 size = strlen((char*)(data+offset_root)) + 1;// length + \0
736 field->field_size = size;
737 break;
738 case LTT_ARRAY:
739 if(field->fixed_size == FIELD_FIXED)
740 size = field->field_size;
741 else {
742 for(i=0;i<field->field_type->element_number;i++) {
743 size_t child_size;
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;
749 size += child_size;
750 }
751 field->field_size = size;
752 }
753 break;
754 case LTT_STRUCT:
755 if(field->fixed_size == FIELD_FIXED)
756 size = field->field_size;
757 else {
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;
767
768 }
769 size = current_offset;
770 field->field_size = size;
771 }
772 break;
773 case LTT_UNION:
774 if(field->fixed_size == FIELD_FIXED)
775 size = field->field_size;
776 else {
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);
784 }
785 field->field_size = size;
786 }
787 break;
788 }
789
790 return size;
791 }
792 #endif //0
793
794
795
796
797
798 /*****************************************************************************
799 *Function name
800 * compute_fields_offsets : set the precomputable offset of the fields
801 *Input params
802 * fac : facility
803 * field : the field
804 * offset : pointer to the current offset, must be incremented
805 ****************************************************************************/
806
807
808 void compute_fields_offsets(LttTracefile *tf,
809 LttFacility *fac, LttField *field, off_t *offset, void *root)
810 {
811 LttType *type = &field->field_type;
812
813 switch(type->type_class) {
814 case LTT_INT_FIXED:
815 case LTT_UINT_FIXED:
816 case LTT_POINTER:
817 case LTT_CHAR:
818 case LTT_UCHAR:
819 case LTT_SHORT:
820 case LTT_USHORT:
821 case LTT_INT:
822 case LTT_UINT:
823 case LTT_LONG:
824 case LTT_ULONG:
825 case LTT_SIZE_T:
826 case LTT_SSIZE_T:
827 case LTT_OFF_T:
828 case LTT_FLOAT:
829 case LTT_ENUM:
830 if(field->fixed_root == FIELD_VARIABLE) {
831 /* Align offset on type size */
832 *offset += ltt_align(*offset, get_alignment(field),
833 fac->alignment);
834 /* remember offset */
835 field->offset_root = *offset;
836 /* Increment offset */
837 *offset += field->field_size;
838 } else {
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);
845 }
846 break;
847 case LTT_STRING:
848 if(field->fixed_root == FIELD_VARIABLE) {
849 field->offset_root = *offset;
850 }
851 *offset += strlen((gchar*)(root+*offset)) + 1;
852 /* Realign the data */
853 *offset += ltt_align(*offset, fac->pointer_size,
854 fac->alignment);
855 break;
856 case LTT_ARRAY:
857 g_assert(type->fields->len == 1);
858 {
859 off_t local_offset;
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),
863 fac->alignment);
864 /* remember offset */
865 field->offset_root = *offset;
866 field->array_offset = *offset;
867 }
868
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;
873 } else {
874 guint i;
875 *offset = field->array_offset;
876 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
877 0);
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);
881 }
882 }
883 // local_offset = field->array_offset;
884 // /* Set the offset at position 0 */
885 // compute_fields_offsets(tf, fac, child, &local_offset, root);
886 }
887 break;
888 case LTT_SEQUENCE:
889 g_assert(type->fields->len == 2);
890 {
891 off_t local_offset;
892 LttField *child;
893 guint i;
894 guint num_elem;
895 if(field->fixed_root == FIELD_VARIABLE) {
896 *offset += ltt_align(*offset, get_alignment(field),
897 fac->alignment);
898 /* remember offset */
899 field->offset_root = *offset;
900
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),
905 fac->alignment);
906 field->array_offset = *offset;
907
908 } else {
909 child = &g_array_index(type->fields, LttField, 1);
910 }
911 *offset = field->array_offset;
912 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
913 0);
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);
918 }
919 g_assert(num_elem == field->dynamic_offsets->len);
920
921 /* Realign the data */
922 *offset += ltt_align(*offset, fac->pointer_size,
923 fac->alignment);
924
925 // local_offset = field->array_offset;
926 // /* Set the offset at position 0 */
927 // compute_fields_offsets(tf, fac, child, &local_offset, root);
928 }
929 break;
930 case LTT_STRUCT:
931 {
932 LttField *child;
933 guint i;
934 gint ret=0;
935 if(field->fixed_root == FIELD_VARIABLE) {
936 *offset += ltt_align(*offset, get_alignment(fac, field),
937 fac->alignment);
938 /* remember offset */
939 field->offset_root = *offset;
940 } else {
941 *offset = field->offset_root;
942 }
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);
946 }
947 }
948 break;
949 case LTT_UNION:
950 {
951 LttField *child;
952 guint i;
953 gint ret=0;
954 if(field->fixed_root == FIELD_VARIABLE) {
955 *offset += ltt_align(*offset, get_alignment(field),
956 fac->alignment);
957 /* remember offset */
958 field->offset_root = *offset;
959 }
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);
964 }
965 *offset = field->offset_root + field->field_size;
966 }
967 break;
968 case LTT_NONE:
969 default:
970 g_error("compute_fields_offsets : unknown type");
971 }
972
973 }
974
975
976 /*****************************************************************************
977 *Function name
978 * compute_offsets : set the dynamically computable offsets of an event type
979 *Input params
980 * tf : tracefile
981 * event : event type
982 *
983 ****************************************************************************/
984 void compute_offsets(LttTracefile *tf, LttFacility *fac,
985 LttEventType *event, off_t *offset, void *root)
986 {
987 guint i;
988
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);
994 }
995
996 }
997
This page took 0.053744 seconds and 5 git commands to generate.