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