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