fix process names
[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 off_t ltt_event_field_offset(LttEvent *e, LttField *f)
494 {
495 return f->offset_root;
496 }
497
498
499
500 /*****************************************************************************
501 * These functions extract data from an event after architecture specific
502 * conversions
503 ****************************************************************************/
504 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
505 {
506 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
507
508 LttTypeEnum t = f->field_type.type_class;
509
510 if(f->field_size == 1){
511 guint8 x = *(guint8 *)(e->data + f->offset_root);
512 return (guint32) x;
513 }else if(f->field_size == 2){
514 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
515 }else if(f->field_size == 4){
516 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
517 }
518 #if 0
519 else if(f->field_size == 8){
520 guint64 x = *(guint64 *)(e->data + f->offset_root);
521 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
522 return (unsigned int) (revFlag ? GUINT64_FROM_BE(x): x);
523 else
524 return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);
525 }
526 #endif //0
527 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
528 return 0;
529 }
530
531 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
532 {
533 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
534
535 if(f->field_size == 1){
536 gint8 x = *(gint8 *)(e->data + f->offset_root);
537 return (gint32) x;
538 }else if(f->field_size == 2){
539 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
540 }else if(f->field_size == 4){
541 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
542 }
543 #if 0
544 else if(f->field_size == 8){
545 gint64 x = *(gint64 *)(e->data + f->offset_root);
546 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
547 return (int) (revFlag ? GINT64_FROM_BE(x): x);
548 else
549 return (int) (revFlag ? GINT64_FROM_LE(x): x);
550 }
551 #endif //0
552 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
553 return 0;
554 }
555
556 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
557 {
558 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
559
560 LttTypeEnum t = f->field_type.type_class;
561
562 if(f->field_size == 1){
563 guint8 x = *(guint8 *)(e->data + f->offset_root);
564 return (guint64) x;
565 }else if(f->field_size == 2){
566 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
567 }else if(f->field_size == 4){
568 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
569 }else if(f->field_size == 8){
570 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
571 }
572 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
573 return 0;
574 }
575
576 gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
577 {
578 //int revFlag = e->tracefile->trace->my_arch_endian ==
579 // e->tracefile->trace->system_description->endian ? 0:1;
580 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
581
582 if(f->field_size == 1){
583 gint8 x = *(gint8 *)(e->data + f->offset_root);
584 return (gint64) x;
585 }else if(f->field_size == 2){
586 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
587 }else if(f->field_size == 4){
588 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
589 }else if(f->field_size == 8){
590 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
591 }
592 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
593 return 0;
594 }
595
596 float ltt_event_get_float(LttEvent *e, LttField *f)
597 {
598 g_assert(LTT_HAS_FLOAT(e->tracefile));
599 gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
600
601 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 4);
602
603 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
604 else{
605 void *ptr = e->data + f->offset_root;
606 guint32 value = bswap_32(*(guint32*)ptr);
607 return *(float*)&value;
608 }
609 }
610
611 double ltt_event_get_double(LttEvent *e, LttField *f)
612 {
613 g_assert(LTT_HAS_FLOAT(e->tracefile));
614 gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
615
616 if(f->field_size == 4)
617 return ltt_event_get_float(e, f);
618
619 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 8);
620
621 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
622 else {
623 void *ptr = e->data + f->offset_root;
624 guint64 value = bswap_64(*(guint64*)ptr);
625 return *(double*)&value;
626 }
627 }
628
629 /*****************************************************************************
630 * The string obtained is only valid until the next read from
631 * the same tracefile.
632 ****************************************************************************/
633 char *ltt_event_get_string(LttEvent *e, LttField *f)
634 {
635 g_assert(f->field_type.type_class == LTT_STRING);
636
637 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
638 }
639
640
641 /*****************************************************************************
642 *Function name
643 * get_field_type_size : set the fixed and dynamic sizes of the field type
644 * from the data read.
645 *Input params
646 * tf : tracefile
647 * event_type : event type
648 * offset_root : offset from the root
649 * offset_parent : offset from the parent
650 * field : field
651 * data : a pointer to the event data.
652 *Returns the field type size.
653 ****************************************************************************/
654 // TODO
655 // Change this function so it uses a *to offset value incrementation, just like
656 // genevent-new instead of returning a size. What is of interest here is the
657 // offset needed to read each field.
658 //
659 // Precomputed ones can be returned directly. Otherwise, the field is flagged
660 // "VARIABLE OFFSET" and must be computed dynamically. The dynamic processing
661 // of an offset takes the last known fixed offset, and then dynamically
662 // calculates all variable field offsets from it.
663 //
664 // After a VARIABLE SIZE element, all fields have a variable offset.
665 // Also, is an array or a sequence has variable length child, we must pass
666 // through all of them, saving the offsets in the dynamic_offsets array.
667
668 #if 0
669 size_t get_field_type_size(LttTracefile *tf, LttEventType *event_type,
670 off_t offset_root, off_t offset_parent,
671 LttField *field, void *data)
672 {
673 size_t size = 0;
674 guint i;
675 LttType *type;
676 off_t align;
677
678 g_assert(field->fixed_root != FIELD_UNKNOWN);
679 g_assert(field->fixed_parent != FIELD_UNKNOWN);
680 g_assert(field->fixed_size != FIELD_UNKNOWN);
681
682 field->offset_root = offset_root;
683 field->offset_parent = offset_parent;
684
685 type = field->field_type;
686
687 switch(type->type_class) {
688 case LTT_INT:
689 case LTT_UINT:
690 case LTT_FLOAT:
691 case LTT_ENUM:
692 case LTT_POINTER:
693 case LTT_LONG:
694 case LTT_ULONG:
695 case LTT_SIZE_T:
696 case LTT_SSIZE_T:
697 case LTT_OFF_T:
698 g_assert(field->fixed_size == FIELD_FIXED);
699 size = field->field_size;
700 align = ltt_align(field->offset_root,
701 size, event_type->facility->alignment);
702 field->offset_root += align;
703 field->offset_parent += align;
704 size += align;
705 break;
706 case LTT_SEQUENCE:
707 {
708 /* FIXME : check the type of sequence identifier */
709 gint seqnum = ltt_get_uint(LTT_GET_BO(tf),
710 field->sequ_number_size,
711 data + offset_root);
712
713 if(field->child[0]->fixed_size == FIELD_FIXED) {
714 size = field->sequ_number_size +
715 (seqnum * get_field_type_size(tf, event_type,
716 offset_root, offset_parent,
717 field->child[0], data));
718 } else {
719 size += field->sequ_number_size;
720 for(i=0;i<seqnum;i++) {
721 size_t child_size;
722 child_size = get_field_type_size(tf, event_type,
723 offset_root, offset_parent,
724 field->child[0], data);
725 offset_root += child_size;
726 offset_parent += child_size;
727 size += child_size;
728 }
729 }
730 field->field_size = size;
731 }
732 break;
733 case LTT_STRING:
734 size = strlen((char*)(data+offset_root)) + 1;// length + \0
735 field->field_size = size;
736 break;
737 case LTT_ARRAY:
738 if(field->fixed_size == FIELD_FIXED)
739 size = field->field_size;
740 else {
741 for(i=0;i<field->field_type->element_number;i++) {
742 size_t child_size;
743 child_size = get_field_type_size(tf, event_type,
744 offset_root, offset_parent,
745 field->child[0], data);
746 offset_root += child_size;
747 offset_parent += child_size;
748 size += child_size;
749 }
750 field->field_size = size;
751 }
752 break;
753 case LTT_STRUCT:
754 if(field->fixed_size == FIELD_FIXED)
755 size = field->field_size;
756 else {
757 size_t current_root_offset = offset_root;
758 size_t current_offset = 0;
759 size_t child_size = 0;
760 for(i=0;i<type->element_number;i++) {
761 child_size = get_field_type_size(tf,
762 event_type, current_root_offset, current_offset,
763 field->child[i], data);
764 current_offset += child_size;
765 current_root_offset += child_size;
766
767 }
768 size = current_offset;
769 field->field_size = size;
770 }
771 break;
772 case LTT_UNION:
773 if(field->fixed_size == FIELD_FIXED)
774 size = field->field_size;
775 else {
776 size_t current_root_offset = field->offset_root;
777 size_t current_offset = 0;
778 for(i=0;i<type->element_number;i++) {
779 size = get_field_type_size(tf, event_type,
780 current_root_offset, current_offset,
781 field->child[i], data);
782 size = max(size, field->child[i]->field_size);
783 }
784 field->field_size = size;
785 }
786 break;
787 }
788
789 return size;
790 }
791 #endif //0
792
793
794
795
796
797 /*****************************************************************************
798 *Function name
799 * compute_fields_offsets : set the precomputable offset of the fields
800 *Input params
801 * fac : facility
802 * field : the field
803 * offset : pointer to the current offset, must be incremented
804 ****************************************************************************/
805
806
807 void compute_fields_offsets(LttTracefile *tf,
808 LttFacility *fac, LttField *field, off_t *offset, void *root)
809 {
810 LttType *type = &field->field_type;
811
812 switch(type->type_class) {
813 case LTT_INT_FIXED:
814 case LTT_UINT_FIXED:
815 case LTT_POINTER:
816 case LTT_CHAR:
817 case LTT_UCHAR:
818 case LTT_SHORT:
819 case LTT_USHORT:
820 case LTT_INT:
821 case LTT_UINT:
822 case LTT_LONG:
823 case LTT_ULONG:
824 case LTT_SIZE_T:
825 case LTT_SSIZE_T:
826 case LTT_OFF_T:
827 case LTT_FLOAT:
828 case LTT_ENUM:
829 if(field->fixed_root == FIELD_VARIABLE) {
830 /* Align offset on type size */
831 *offset += ltt_align(*offset, get_alignment(field),
832 fac->alignment);
833 /* remember offset */
834 field->offset_root = *offset;
835 /* Increment offset */
836 *offset += field->field_size;
837 } else {
838 //g_debug("type before offset : %llu %llu %u\n", *offset,
839 // field->offset_root,
840 // field->field_size);
841 *offset = field->offset_root;
842 *offset += field->field_size;
843 //g_debug("type after offset : %llu\n", *offset);
844 }
845 break;
846 case LTT_STRING:
847 if(field->fixed_root == FIELD_VARIABLE) {
848 field->offset_root = *offset;
849 }
850 *offset += strlen((gchar*)(root+*offset)) + 1;
851 /* Realign the data */
852 *offset += ltt_align(*offset, fac->pointer_size,
853 fac->alignment);
854 break;
855 case LTT_ARRAY:
856 g_assert(type->fields->len == 1);
857 {
858 off_t local_offset;
859 LttField *child = &g_array_index(type->fields, LttField, 0);
860 if(field->fixed_root == FIELD_VARIABLE) {
861 *offset += ltt_align(*offset, get_alignment(field),
862 fac->alignment);
863 /* remember offset */
864 field->offset_root = *offset;
865 field->array_offset = *offset;
866 }
867
868 if(field->field_size != 0) {
869 /* Increment offset */
870 /* field_size is the array size in bytes */
871 *offset = field->offset_root + field->field_size;
872 } else {
873 guint i;
874 *offset = field->array_offset;
875 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
876 0);
877 for(i=0; i<type->size; i++) {
878 g_array_append_val(field->dynamic_offsets, *offset);
879 compute_fields_offsets(tf, fac, child, offset, root);
880 }
881 }
882 // local_offset = field->array_offset;
883 // /* Set the offset at position 0 */
884 // compute_fields_offsets(tf, fac, child, &local_offset, root);
885 }
886 break;
887 case LTT_SEQUENCE:
888 g_assert(type->fields->len == 2);
889 {
890 off_t local_offset;
891 LttField *child;
892 guint i;
893 guint num_elem;
894 if(field->fixed_root == FIELD_VARIABLE) {
895 *offset += ltt_align(*offset, get_alignment(field),
896 fac->alignment);
897 /* remember offset */
898 field->offset_root = *offset;
899
900 child = &g_array_index(type->fields, LttField, 0);
901 compute_fields_offsets(tf, fac, child, offset, root);
902 child = &g_array_index(type->fields, LttField, 1);
903 *offset += ltt_align(*offset, get_alignment(child),
904 fac->alignment);
905 field->array_offset = *offset;
906
907 } else {
908 child = &g_array_index(type->fields, LttField, 1);
909 }
910 *offset = field->array_offset;
911 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
912 0);
913 num_elem = ltt_event_field_element_number(&tf->event, field);
914 for(i=0; i<num_elem; i++) {
915 g_array_append_val(field->dynamic_offsets, *offset);
916 compute_fields_offsets(tf, fac, child, offset, root);
917 }
918 g_assert(num_elem == field->dynamic_offsets->len);
919
920 /* Realign the data */
921 *offset += ltt_align(*offset, fac->pointer_size,
922 fac->alignment);
923
924 // local_offset = field->array_offset;
925 // /* Set the offset at position 0 */
926 // compute_fields_offsets(tf, fac, child, &local_offset, root);
927 }
928 break;
929 case LTT_STRUCT:
930 {
931 LttField *child;
932 guint i;
933 gint ret=0;
934 if(field->fixed_root == FIELD_VARIABLE) {
935 *offset += ltt_align(*offset, get_alignment(fac, field),
936 fac->alignment);
937 /* remember offset */
938 field->offset_root = *offset;
939 } else {
940 *offset = field->offset_root;
941 }
942 for(i=0; i<type->fields->len; i++) {
943 child = &g_array_index(type->fields, LttField, i);
944 compute_fields_offsets(tf, fac, child, offset, root);
945 }
946 }
947 break;
948 case LTT_UNION:
949 {
950 LttField *child;
951 guint i;
952 gint ret=0;
953 if(field->fixed_root == FIELD_VARIABLE) {
954 *offset += ltt_align(*offset, get_alignment(field),
955 fac->alignment);
956 /* remember offset */
957 field->offset_root = *offset;
958 }
959 for(i=0; i<type->fields->len; i++) {
960 *offset = field->offset_root;
961 child = &g_array_index(type->fields, LttField, i);
962 compute_fields_offsets(tf, fac, child, offset, root);
963 }
964 *offset = field->offset_root + field->field_size;
965 }
966 break;
967 case LTT_NONE:
968 default:
969 g_error("compute_fields_offsets : unknown type");
970 }
971
972 }
973
974
975 /*****************************************************************************
976 *Function name
977 * compute_offsets : set the dynamically computable offsets of an event type
978 *Input params
979 * tf : tracefile
980 * event : event type
981 *
982 ****************************************************************************/
983 void compute_offsets(LttTracefile *tf, LttFacility *fac,
984 LttEventType *event, off_t *offset, void *root)
985 {
986 guint i;
987
988 /* compute all variable offsets */
989 for(i=0; i<event->fields->len; i++) {
990 //g_debug("computing offset %u of %u\n", i, event->fields->len-1);
991 LttField *field = &g_array_index(event->fields, LttField, i);
992 compute_fields_offsets(tf, fac, field, offset, root);
993 }
994
995 }
996
This page took 0.051502 seconds and 5 git commands to generate.