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