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