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