git-svn-id: http://ltt.polymtl.ca/svn@460 04897980-b3bd-0310-b5e0-8ef037075253
[lttv.git] / ltt / branches / poly / ltt / event.c
CommitLineData
6cd62ccf 1#include <stdio.h>
2#include <asm/types.h>
3#include <linux/byteorder/swab.h>
a5dcde2f 4
6cd62ccf 5#include "parser.h"
a5dcde2f 6#include <ltt/ltt.h>
7#include "ltt-private.h"
6cd62ccf 8#include <ltt/event.h>
a5dcde2f 9#include <ltt/trace.h>
6cd62ccf 10
908f42fa 11/*****************************************************************************
12 *Function name
13 * ltt_event_refresh_fields : refresh fields of an event
14 *Input params
15 * offsetRoot : offset from the root
16 * offsetParent : offset from the parrent
17 * fld : field
18 * evD : event data
19 *Return value
20 * int : size of the field
21 ****************************************************************************/
22
23int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
24 LttField * fld, void *evD)
25{
26 int size, size1, element_number, i, offset1, offset2;
27 LttType * type = fld->field_type;
28
29 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
30 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
31 size = fld->field_size;
32 }else if(type->type_class == LTT_ARRAY){
33 element_number = (int) type->element_number;
34 if(fld->field_fixed == 0){// has string or sequence
35 size = 0;
36 for(i=0;i<element_number;i++){
37 size += ltt_event_refresh_fields(offsetRoot+size,size,
38 fld->child[0], evD+size);
39 }
40 }else size = fld->field_size;
41 }else if(type->type_class == LTT_SEQUENCE){
42 size1 = fld->sequ_number_size;
43 element_number = getIntNumber(size1,evD);
44 type->element_number = element_number;
45 if(fld->element_size > 0){
46 size = element_number * fld->element_size;
47 }else{//sequence has string or sequence
48 size = 0;
49 for(i=0;i<element_number;i++){
50 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
51 fld->child[0], evD+size+size1);
52 }
53 size += size1;
54 }
55 }else if(type->type_class == LTT_STRING){
56 size = strlen((char*)evD) + 1; //include end : '\0'
57 }else if(type->type_class == LTT_STRUCT){
58 element_number = (int) type->element_number;
59 if(fld->field_fixed == 0){
60 offset1 = offsetRoot;
61 offset2 = 0;
62 for(i=0;i<element_number;i++){
63 size=ltt_event_refresh_fields(offset1,offset2,fld->child[i],evD+offset2);
64 offset1 += size;
65 offset2 += size;
66 }
67 size = offset2;
68 }else size = fld->field_size;
69 }
70
71 fld->offset_root = offsetRoot;
72 fld->offset_parent = offsetParent;
73 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
74 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
75 fld->field_size = size;
76
77 return size;
78}
79
6cd62ccf 80/*****************************************************************************
81 *Function name
963b5f2d 82 * ltt_event_eventtype_id: get event type id
83 * (base id + position of the event)
6cd62ccf 84 *Input params
963b5f2d 85 * e : an instance of an event type
6cd62ccf 86 *Return value
963b5f2d 87 * unsigned : event type id
6cd62ccf 88 ****************************************************************************/
89
963b5f2d 90unsigned ltt_event_eventtype_id(LttEvent *e)
6cd62ccf 91{
92 return (unsigned) e->event_id;
93}
94
95/*****************************************************************************
96 *Function name
97 * ltt_event_facility : get the facility of the event
98 *Input params
99 * e : an instance of an event type
100 *Return value
963b5f2d 101 * LttFacility * : the facility of the event
6cd62ccf 102 ****************************************************************************/
103
963b5f2d 104LttFacility *ltt_event_facility(LttEvent *e)
6cd62ccf 105{
963b5f2d 106 LttTrace * trace = e->tracefile->trace;
107 unsigned id = e->event_id;
108 return ltt_trace_facility_by_id(trace,id);
6cd62ccf 109}
110
111/*****************************************************************************
112 *Function name
113 * ltt_event_eventtype : get the event type of the event
114 *Input params
115 * e : an instance of an event type
116 *Return value
963b5f2d 117 * LttEventType * : the event type of the event
6cd62ccf 118 ****************************************************************************/
119
963b5f2d 120LttEventType *ltt_event_eventtype(LttEvent *e)
6cd62ccf 121{
963b5f2d 122 LttFacility* facility = ltt_event_facility(e);
123 if(!facility) return NULL;
124 return facility->events[e->event_id - facility->base_id];
6cd62ccf 125}
126
127/*****************************************************************************
128 *Function name
963b5f2d 129 * ltt_event_field : get the root field of the event
6cd62ccf 130 *Input params
963b5f2d 131 * e : an instance of an event type
6cd62ccf 132 *Return value
963b5f2d 133 * LttField * : the root field of the event
6cd62ccf 134 ****************************************************************************/
135
963b5f2d 136LttField *ltt_event_field(LttEvent *e)
6cd62ccf 137{
908f42fa 138 LttField * field;
963b5f2d 139 LttEventType * event_type = ltt_event_eventtype(e);
140 if(!event_type) return NULL;
908f42fa 141 field = event_type->root_field;
a2331fa0 142 if(!field) return NULL;
908f42fa 143
144 //check if the field need refresh
145 if(e->which_block != event_type->latest_block ||
146 e->which_event != event_type->latest_event){
147
148 event_type->latest_block = e->which_block;
149 event_type->latest_event = e->which_event;
150
151 if(field->field_fixed == 1)return field;
152
153 //refresh the field
154 ltt_event_refresh_fields(0, 0, field, e->data);
155 }
156 return field;
6cd62ccf 157}
158
159/*****************************************************************************
160 *Function name
963b5f2d 161 * ltt_event_time : get the time of the event
6cd62ccf 162 *Input params
163 * e : an instance of an event type
164 *Return value
963b5f2d 165 * LttTime : the time of the event
6cd62ccf 166 ****************************************************************************/
167
963b5f2d 168LttTime ltt_event_time(LttEvent *e)
6cd62ccf 169{
963b5f2d 170 return e->event_time;
6cd62ccf 171}
172
173/*****************************************************************************
174 *Function name
963b5f2d 175 * ltt_event_time : get the cycle count of the event
6cd62ccf 176 *Input params
177 * e : an instance of an event type
178 *Return value
963b5f2d 179 * LttCycleCount : the cycle count of the event
6cd62ccf 180 ****************************************************************************/
181
963b5f2d 182LttCycleCount ltt_event_cycle_count(LttEvent *e)
6cd62ccf 183{
963b5f2d 184 return e->event_cycle_count;
6cd62ccf 185}
186
80da81ad 187/*****************************************************************************
188 *Function name
189 * ltt_event_position : get the event's position
190 *Input params
191 * e : an instance of an event type
192 * ep : a pointer to event's position structure
193 ****************************************************************************/
194
195void ltt_event_position(LttEvent *e, LttEventPosition *ep)
196{
197 ep->block_num = e->which_block;
198 ep->event_num = e->which_event;
199 ep->event_time = e->event_time;
200 ep->event_cycle_count = e->event_cycle_count;
201 ep->heart_beat_number = e->tracefile->cur_heart_beat_number;
e4eced0f 202 ep->old_position = FALSE;
80da81ad 203 ep->event_offset = e->data - e->tracefile->buffer - EVENT_HEADER_SIZE ;
e4eced0f 204 ep->tf = e->tracefile;
80da81ad 205}
206
a5dcde2f 207LttEventPosition * ltt_event_position_new()
208{
209 return g_new(LttEventPosition, 1);
210}
211
80da81ad 212/*****************************************************************************
213 *Function name
214 * ltt_event_position_get : get the block number and index of the event
215 *Input params
216 * ep : a pointer to event's position structure
217 * block_number : the block number of the event
218 * index_in_block : the index of the event within the block
219 ****************************************************************************/
220
221void ltt_event_position_get(LttEventPosition *ep,
e4eced0f 222 unsigned *block_number, unsigned *index_in_block, LttTracefile ** tf)
80da81ad 223{
224 *block_number = ep->block_num;
225 *index_in_block = ep->event_num;
e4eced0f 226 *tf = ep->tf;
80da81ad 227}
228
229/*****************************************************************************
230 *Function name
231 * ltt_event_position_set : set the block number and index of the event
232 *Input params
233 * ep : a pointer to event's position structure
234 * block_number : the block number of the event
235 * index_in_block : the index of the event within the block
236 ****************************************************************************/
237
238void ltt_event_position_set(LttEventPosition *ep,
239 unsigned block_number, unsigned index_in_block)
240{
241 ep->block_num = block_number;
e4eced0f 242 ep->event_num = index_in_block;
80da81ad 243}
244
6cd62ccf 245/*****************************************************************************
246 *Function name
963b5f2d 247 * ltt_event_cpu_i: get the cpu id where the event happens
6cd62ccf 248 *Input params
249 * e : an instance of an event type
250 *Return value
963b5f2d 251 * unsigned : the cpu id
6cd62ccf 252 ****************************************************************************/
253
963b5f2d 254unsigned ltt_event_cpu_id(LttEvent *e)
dd691a2e 255{
256 char * c1, * c2, * c3;
257 c1 = strrchr(e->tracefile->name,'\\');
258 c2 = strrchr(e->tracefile->name,'/');
259 if(c1 == NULL && c2 == NULL){
260 return (unsigned)atoi(e->tracefile->name);
261 }else if(c1 == NULL){
262 c2++;
263 return (unsigned)atoi(c2);
264 }else if(c2 == NULL){
265 c1++;
266 return (unsigned)atoi(c1);
267 }else{
268 c3 = (c1 > c2) ? c1 : c2;
269 c3++;
270 return (unsigned)atoi(c3);
271 }
6cd62ccf 272}
273
274/*****************************************************************************
275 *Function name
276 * ltt_event_data : get the raw data for the event
277 *Input params
278 * e : an instance of an event type
279 *Return value
280 * void * : pointer to the raw data for the event
281 ****************************************************************************/
282
963b5f2d 283void *ltt_event_data(LttEvent *e)
6cd62ccf 284{
285 return e->data;
286}
287
288/*****************************************************************************
289 *Function name
290 * ltt_event_field_element_number
291 * : The number of elements in a sequence field is specific
292 * to each event. This function returns the number of
293 * elements for an array or sequence field in an event.
294 *Input params
908f42fa 295 * e : an instance of an event type
6cd62ccf 296 * f : a field of the instance
297 *Return value
298 * unsigned : the number of elements for an array/sequence field
299 ****************************************************************************/
300
963b5f2d 301unsigned ltt_event_field_element_number(LttEvent *e, LttField *f)
6cd62ccf 302{
303 if(f->field_type->type_class != LTT_ARRAY &&
304 f->field_type->type_class != LTT_SEQUENCE)
305 return 0;
908f42fa 306
307 if(f->field_type->type_class == LTT_ARRAY)
308 return f->field_type->element_number;
309 return (unsigned) getIntNumber(f->sequ_number_size, e + f->offset_root);
6cd62ccf 310}
311
312/*****************************************************************************
313 *Function name
314 * ltt_event_field_element_select
315 * : Set the currently selected element for a sequence or
316 * array field
317 *Input params
908f42fa 318 * e : an instance of an event type
6cd62ccf 319 * f : a field of the instance
320 * i : the ith element
6cd62ccf 321 ****************************************************************************/
322
963b5f2d 323void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
6cd62ccf 324{
908f42fa 325 unsigned element_number;
326 LttField *fld;
327 int k, size;
328 void *evD;
329
330 if(f->field_type->type_class != LTT_ARRAY &&
6cd62ccf 331 f->field_type->type_class != LTT_SEQUENCE)
908f42fa 332 return ;
333
334 element_number = ltt_event_field_element_number(e,f);
89d4760c 335 if((element_number-1) < i || i < 0) return;
908f42fa 336
337 fld = f->child[0];
338
339 evD = e->data + f->offset_root;
340 size = 0;
341 for(k=0;k<i;k++){
342 size += ltt_event_refresh_fields(f->offset_root+size,size, fld, evD+size);
343 }
6cd62ccf 344
908f42fa 345 f->current_element = i - 1;
6cd62ccf 346}
347
348/*****************************************************************************
349 * These functions extract data from an event after architecture specific
350 * conversions
351 ****************************************************************************/
352
963b5f2d 353unsigned ltt_event_get_unsigned(LttEvent *e, LttField *f)
6cd62ccf 354{
963b5f2d 355 int revFlag = e->tracefile->trace->my_arch_endian ==
356 e->tracefile->trace->system_description->endian ? 0:1;
357 LttTypeEnum t = f->field_type->type_class;
6cd62ccf 358
c687f6c8 359 if(t != LTT_UINT && t != LTT_ENUM)
6cd62ccf 360 g_error("The type of the field is not unsigned int\n");
361
b7b36242 362 if(f->field_size == 1){
cbd41522 363 guint8 x = *(guint8 *)(e->data + f->offset_root);
b7b36242 364 return (unsigned int) x;
365 }else if(f->field_size == 2){
cbd41522 366 guint16 x = *(guint16 *)(e->data + f->offset_root);
367 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
368 return (unsigned int) (revFlag ? GUINT16_FROM_BE(x): x);
369 else
370 return (unsigned int) (revFlag ? GUINT16_FROM_LE(x): x);
b7b36242 371 }else if(f->field_size == 4){
cbd41522 372 guint32 x = *(guint32 *)(e->data + f->offset_root);
373 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
374 return (unsigned int) (revFlag ? GUINT32_FROM_BE(x): x);
375 else
376 return (unsigned int) (revFlag ? GUINT32_FROM_LE(x): x);
b7b36242 377 }else if(f->field_size == 8){
cbd41522 378 guint64 x = *(guint64 *)(e->data + f->offset_root);
379 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
380 return (unsigned int) (revFlag ? GUINT64_FROM_BE(x): x);
381 else
382 return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);
6cd62ccf 383 }
384}
385
963b5f2d 386int ltt_event_get_int(LttEvent *e, LttField *f)
6cd62ccf 387{
963b5f2d 388 int revFlag = e->tracefile->trace->my_arch_endian ==
389 e->tracefile->trace->system_description->endian ? 0:1;
6cd62ccf 390
391 if(f->field_type->type_class != LTT_INT)
392 g_error("The type of the field is not int\n");
393
b7b36242 394 if(f->field_size == 1){
cbd41522 395 gint8 x = *(gint8 *)(e->data + f->offset_root);
b7b36242 396 return (int) x;
397 }else if(f->field_size == 2){
cbd41522 398 gint16 x = *(gint16 *)(e->data + f->offset_root);
399 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
400 return (int) (revFlag ? GINT16_FROM_BE(x): x);
401 else
402 return (int) (revFlag ? GINT16_FROM_LE(x): x);
b7b36242 403 }else if(f->field_size == 4){
cbd41522 404 gint32 x = *(gint32 *)(e->data + f->offset_root);
405 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
406 return (int) (revFlag ? GINT32_FROM_BE(x): x);
407 else
408 return (int) (revFlag ? GINT32_FROM_LE(x): x);
b7b36242 409 }else if(f->field_size == 8){
cbd41522 410 gint64 x = *(gint64 *)(e->data + f->offset_root);
411 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
412 return (int) (revFlag ? GINT64_FROM_BE(x): x);
413 else
414 return (int) (revFlag ? GINT64_FROM_LE(x): x);
6cd62ccf 415 }
416}
417
963b5f2d 418unsigned long ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
6cd62ccf 419{
963b5f2d 420 int revFlag = e->tracefile->trace->my_arch_endian ==
421 e->tracefile->trace->system_description->endian ? 0:1;
422 LttTypeEnum t = f->field_type->type_class;
6cd62ccf 423
c687f6c8 424 if(t != LTT_UINT && t != LTT_ENUM)
6cd62ccf 425 g_error("The type of the field is not unsigned long\n");
426
b7b36242 427 if(f->field_size == 1){
cbd41522 428 guint8 x = *(guint8 *)(e->data + f->offset_root);
b7b36242 429 return (unsigned long) x;
430 }else if(f->field_size == 2){
cbd41522 431 guint16 x = *(guint16 *)(e->data + f->offset_root);
432 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
433 return (unsigned long) (revFlag ? GUINT16_FROM_BE(x): x);
434 else
435 return (unsigned long) (revFlag ? GUINT16_FROM_LE(x): x);
b7b36242 436 }else if(f->field_size == 4){
cbd41522 437 guint32 x = *(guint32 *)(e->data + f->offset_root);
438 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
439 return (unsigned long) (revFlag ? GUINT32_FROM_BE(x): x);
440 else
441 return (unsigned long) (revFlag ? GUINT32_FROM_LE(x): x);
b7b36242 442 }else if(f->field_size == 8){
cbd41522 443 guint64 x = *(guint64 *)(e->data + f->offset_root);
444 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
445 return (unsigned long) (revFlag ? GUINT64_FROM_BE(x): x);
446 else
447 return (unsigned long) (revFlag ? GUINT64_FROM_LE(x): x);
6cd62ccf 448 }
449}
450
963b5f2d 451long int ltt_event_get_long_int(LttEvent *e, LttField *f)
6cd62ccf 452{
963b5f2d 453 int revFlag = e->tracefile->trace->my_arch_endian ==
454 e->tracefile->trace->system_description->endian ? 0:1;
6cd62ccf 455
456 if( f->field_type->type_class != LTT_INT)
457 g_error("The type of the field is not long int\n");
458
b7b36242 459 if(f->field_size == 1){
cbd41522 460 gint8 x = *(gint8 *)(e->data + f->offset_root);
b7b36242 461 return (long) x;
462 }else if(f->field_size == 2){
cbd41522 463 gint16 x = *(gint16 *)(e->data + f->offset_root);
464 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
465 return (long) (revFlag ? GINT16_FROM_BE(x): x);
466 else
467 return (long) (revFlag ? GINT16_FROM_LE(x): x);
b7b36242 468 }else if(f->field_size == 4){
cbd41522 469 gint32 x = *(gint32 *)(e->data + f->offset_root);
470 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
471 return (long) (revFlag ? GINT32_FROM_BE(x): x);
472 else
473 return (long) (revFlag ? GINT32_FROM_LE(x): x);
b7b36242 474 }else if(f->field_size == 8){
cbd41522 475 gint64 x = *(gint64 *)(e->data + f->offset_root);
476 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
477 return (long) (revFlag ? GINT64_FROM_BE(x): x);
478 else
479 return (long) (revFlag ? GINT64_FROM_LE(x): x);
6cd62ccf 480 }
481}
482
963b5f2d 483float ltt_event_get_float(LttEvent *e, LttField *f)
6cd62ccf 484{
963b5f2d 485 int revFlag = e->tracefile->trace->my_arch_endian ==
486 e->tracefile->trace->system_description->endian ? 0:1;
6cd62ccf 487
488 if(f->field_type->type_class != LTT_FLOAT ||
489 (f->field_type->type_class == LTT_FLOAT && f->field_size != 4))
490 g_error("The type of the field is not float\n");
491
492 if(revFlag == 0) return *(float *)(e->data + f->offset_root);
493 else{
cbd41522 494 guint32 aInt;
6cd62ccf 495 memcpy((void*)&aInt, e->data + f->offset_root, 4);
496 aInt = ___swab32(aInt);
497 return *((float*)&aInt);
498 }
499}
500
963b5f2d 501double ltt_event_get_double(LttEvent *e, LttField *f)
6cd62ccf 502{
963b5f2d 503 int revFlag = e->tracefile->trace->my_arch_endian ==
504 e->tracefile->trace->system_description->endian ? 0:1;
6cd62ccf 505
506 if(f->field_type->type_class != LTT_FLOAT ||
507 (f->field_type->type_class == LTT_FLOAT && f->field_size != 8))
508 g_error("The type of the field is not double\n");
509
510 if(revFlag == 0) return *(double *)(e->data + f->offset_root);
511 else{
cbd41522 512 guint64 aInt;
6cd62ccf 513 memcpy((void*)&aInt, e->data + f->offset_root, 8);
514 aInt = ___swab64(aInt);
515 return *((double *)&aInt);
516 }
517}
518
519/*****************************************************************************
520 * The string obtained is only valid until the next read from
908f42fa 521 * the same tracefile.
6cd62ccf 522 ****************************************************************************/
523
963b5f2d 524char *ltt_event_get_string(LttEvent *e, LttField *f)
6cd62ccf 525{
526 if(f->field_type->type_class != LTT_STRING)
527 g_error("The field contains no string\n");
528 return (char*)g_strdup((char*)(e->data + f->offset_root));
529}
This page took 0.048846 seconds and 4 git commands to generate.