genevent for 0.1.99.1
[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>
29#include <linux/byteorder/swab.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 38
39LttEvent *ltt_event_new()
40{
41 return g_new(LttEvent, 1);
42}
43
44void ltt_event_destroy(LttEvent *event)
45{
46 g_free(event);
47}
48
49
3aee1200 50#if 0
51/* Use get_field_type_size instead */
908f42fa 52/*****************************************************************************
53 *Function name
54 * ltt_event_refresh_fields : refresh fields of an event
55 *Input params
56 * offsetRoot : offset from the root
18206708 57 * offsetParent : offset from the parent
908f42fa 58 * fld : field
59 * evD : event data
0f7f40c1 60 * reverse_byte_order : 1 or 0
908f42fa 61 *Return value
62 * int : size of the field
63 ****************************************************************************/
64
65int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
0f7f40c1 66 LttField * fld, void *evD, gboolean reverse_byte_order)
908f42fa 67{
68 int size, size1, element_number, i, offset1, offset2;
69 LttType * type = fld->field_type;
70
cf74a6f1 71 switch(type->type_class) {
72 case LTT_ARRAY:
73 element_number = (int) type->element_number;
74 if(fld->field_fixed == 0){// has string or sequence
75 size = 0;
76 for(i=0;i<element_number;i++){
77 size += ltt_event_refresh_fields(offsetRoot+size,size,
0f7f40c1 78 fld->child[0], evD+size, reverse_byte_order);
cf74a6f1 79 }
80 }else size = fld->field_size;
81 break;
82
83 case LTT_SEQUENCE:
84 size1 = fld->sequ_number_size;
0f7f40c1 85 element_number = getIntNumber(reverse_byte_order,size1,evD);
cf74a6f1 86 type->element_number = element_number;
87 if(fld->element_size > 0){
88 size = element_number * fld->element_size;
89 }else{//sequence has string or sequence
90 size = 0;
91 for(i=0;i<element_number;i++){
92 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
0f7f40c1 93 fld->child[0], evD+size+size1, reverse_byte_order);
cf74a6f1 94 }
95 size += size1;
96 }
97 break;
98
99 case LTT_STRING:
45e14832 100 size = strlen((gchar*)evD) + 1; //include end : '\0'
cf74a6f1 101 break;
102
103 case LTT_STRUCT:
104 element_number = (int) type->element_number;
105 if(fld->field_fixed == 0){
106 offset1 = offsetRoot;
107 offset2 = 0;
108 for(i=0;i<element_number;i++){
109 size=ltt_event_refresh_fields(offset1,offset2,
0f7f40c1 110 fld->child[i],evD+offset2, reverse_byte_order);
cf74a6f1 111 offset1 += size;
112 offset2 += size;
113 }
114 size = offset2;
115 }else size = fld->field_size;
116 break;
e52d9126 117
118 case LTT_UNION:
119 size = fld->field_size;
120 break;
cf74a6f1 121
122 default:
123 size = fld->field_size;
124 }
125
126#if 0
908f42fa 127 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
128 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
129 size = fld->field_size;
130 }else if(type->type_class == LTT_ARRAY){
131 element_number = (int) type->element_number;
132 if(fld->field_fixed == 0){// has string or sequence
133 size = 0;
134 for(i=0;i<element_number;i++){
cf74a6f1 135 size += ltt_event_refresh_fields(offsetRoot+size,size,
908f42fa 136 fld->child[0], evD+size);
cf74a6f1 137 }
908f42fa 138 }else size = fld->field_size;
139 }else if(type->type_class == LTT_SEQUENCE){
140 size1 = fld->sequ_number_size;
141 element_number = getIntNumber(size1,evD);
142 type->element_number = element_number;
143 if(fld->element_size > 0){
144 size = element_number * fld->element_size;
145 }else{//sequence has string or sequence
146 size = 0;
147 for(i=0;i<element_number;i++){
cf74a6f1 148 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
149 fld->child[0], evD+size+size1);
908f42fa 150 }
151 size += size1;
152 }
153 }else if(type->type_class == LTT_STRING){
154 size = strlen((char*)evD) + 1; //include end : '\0'
155 }else if(type->type_class == LTT_STRUCT){
156 element_number = (int) type->element_number;
157 if(fld->field_fixed == 0){
158 offset1 = offsetRoot;
159 offset2 = 0;
160 for(i=0;i<element_number;i++){
cf74a6f1 161 size=ltt_event_refresh_fields(offset1,offset2,
162 fld->child[i],evD+offset2);
163 offset1 += size;
164 offset2 += size;
908f42fa 165 }
166 size = offset2;
167 }else size = fld->field_size;
168 }
cf74a6f1 169#endif //0
908f42fa 170 fld->offset_root = offsetRoot;
171 fld->offset_parent = offsetParent;
172 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
173 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
174 fld->field_size = size;
175
176 return size;
177}
3aee1200 178#endif //0
179
908f42fa 180
6cd62ccf 181/*****************************************************************************
182 *Function name
963b5f2d 183 * ltt_event_eventtype_id: get event type id
184 * (base id + position of the event)
6cd62ccf 185 *Input params
963b5f2d 186 * e : an instance of an event type
6cd62ccf 187 *Return value
963b5f2d 188 * unsigned : event type id
6cd62ccf 189 ****************************************************************************/
190
963b5f2d 191unsigned ltt_event_eventtype_id(LttEvent *e)
6cd62ccf 192{
193 return (unsigned) e->event_id;
194}
195
196/*****************************************************************************
197 *Function name
198 * ltt_event_facility : get the facility of the event
199 *Input params
200 * e : an instance of an event type
201 *Return value
963b5f2d 202 * LttFacility * : the facility of the event
6cd62ccf 203 ****************************************************************************/
204
963b5f2d 205LttFacility *ltt_event_facility(LttEvent *e)
6cd62ccf 206{
963b5f2d 207 LttTrace * trace = e->tracefile->trace;
208 unsigned id = e->event_id;
209 return ltt_trace_facility_by_id(trace,id);
6cd62ccf 210}
211
212/*****************************************************************************
213 *Function name
214 * ltt_event_eventtype : get the event type of the event
215 *Input params
216 * e : an instance of an event type
217 *Return value
963b5f2d 218 * LttEventType * : the event type of the event
6cd62ccf 219 ****************************************************************************/
220
963b5f2d 221LttEventType *ltt_event_eventtype(LttEvent *e)
6cd62ccf 222{
963b5f2d 223 LttFacility* facility = ltt_event_facility(e);
224 if(!facility) return NULL;
3aee1200 225 return &g_array_index(facility->events, LttEventType, e->event_id);
6cd62ccf 226}
227
228/*****************************************************************************
229 *Function name
963b5f2d 230 * ltt_event_field : get the root field of the event
6cd62ccf 231 *Input params
963b5f2d 232 * e : an instance of an event type
6cd62ccf 233 *Return value
963b5f2d 234 * LttField * : the root field of the event
6cd62ccf 235 ****************************************************************************/
236
963b5f2d 237LttField *ltt_event_field(LttEvent *e)
6cd62ccf 238{
908f42fa 239 LttField * field;
963b5f2d 240 LttEventType * event_type = ltt_event_eventtype(e);
1d1df11d 241 if(unlikely(!event_type)) return NULL;
908f42fa 242 field = event_type->root_field;
1d1df11d 243 if(unlikely(!field)) return NULL;
908f42fa 244
3aee1200 245 get_field_type_size(e->tracefile, event_type, 0, 0,
246 field, e->data);
247
908f42fa 248 return field;
6cd62ccf 249}
250
251/*****************************************************************************
252 *Function name
963b5f2d 253 * ltt_event_time : get the time of the event
6cd62ccf 254 *Input params
255 * e : an instance of an event type
256 *Return value
963b5f2d 257 * LttTime : the time of the event
6cd62ccf 258 ****************************************************************************/
259
963b5f2d 260LttTime ltt_event_time(LttEvent *e)
6cd62ccf 261{
963b5f2d 262 return e->event_time;
6cd62ccf 263}
264
265/*****************************************************************************
266 *Function name
963b5f2d 267 * ltt_event_time : get the cycle count of the event
6cd62ccf 268 *Input params
269 * e : an instance of an event type
270 *Return value
963b5f2d 271 * LttCycleCount : the cycle count of the event
6cd62ccf 272 ****************************************************************************/
273
963b5f2d 274LttCycleCount ltt_event_cycle_count(LttEvent *e)
6cd62ccf 275{
3aee1200 276 return e->tsc;
6cd62ccf 277}
278
80da81ad 279/*****************************************************************************
280 *Function name
281 * ltt_event_position : get the event's position
282 *Input params
283 * e : an instance of an event type
284 * ep : a pointer to event's position structure
285 ****************************************************************************/
286
287void ltt_event_position(LttEvent *e, LttEventPosition *ep)
288{
3aee1200 289 ep->tracefile = e->tracefile;
290 ep->block = e->block;
291 ep->offset = e->offset;
292 ep->tsc = e->tsc;
80da81ad 293}
294
a5dcde2f 295LttEventPosition * ltt_event_position_new()
296{
297 return g_new(LttEventPosition, 1);
298}
299
80da81ad 300
96da5c0d 301/*****************************************************************************
302 * Function name
303 * ltt_event_position_compare : compare two positions
a00149f6 304 * A NULL value is infinite.
96da5c0d 305 * Input params
306 * ep1 : a pointer to event's position structure
307 * ep2 : a pointer to event's position structure
308 * Return
309 * -1 is ep1 < ep2
310 * 1 if ep1 > ep2
311 * 0 if ep1 == ep2
312 ****************************************************************************/
313
314
315gint ltt_event_position_compare(const LttEventPosition *ep1,
316 const LttEventPosition *ep2)
317{
a00149f6 318 if(ep1 == NULL && ep2 == NULL)
319 return 0;
320 if(ep1 != NULL && ep2 == NULL)
321 return -1;
322 if(ep1 == NULL && ep2 != NULL)
323 return 1;
96da5c0d 324
3aee1200 325 if(ep1->tracefile != ep2->tracefile)
326 g_error("ltt_event_position_compare on different tracefiles makes no sense");
327
328 if(ep1->block < ep2->block)
96da5c0d 329 return -1;
3aee1200 330 if(ep1->block > ep2->block)
96da5c0d 331 return 1;
3aee1200 332 if(ep1->offset < ep2->offset)
96da5c0d 333 return -1;
3aee1200 334 if(ep1->offset > ep2->offset)
96da5c0d 335 return 1;
336 return 0;
337}
338
2a74fbf4 339/*****************************************************************************
340 * Function name
341 * ltt_event_position_copy : copy position
342 * Input params
343 * src : a pointer to event's position structure source
344 * dest : a pointer to event's position structure dest
345 * Return
346 * void
347 ****************************************************************************/
348void ltt_event_position_copy(LttEventPosition *dest,
349 const LttEventPosition *src)
350{
a00149f6 351 if(src == NULL)
352 dest = NULL;
353 else
354 *dest = *src;
2a74fbf4 355}
96da5c0d 356
357
6cd62ccf 358/*****************************************************************************
359 *Function name
963b5f2d 360 * ltt_event_cpu_i: get the cpu id where the event happens
6cd62ccf 361 *Input params
362 * e : an instance of an event type
363 *Return value
963b5f2d 364 * unsigned : the cpu id
6cd62ccf 365 ****************************************************************************/
366
963b5f2d 367unsigned ltt_event_cpu_id(LttEvent *e)
3aee1200 368{
369 return e->tracefile->cpu_num;
6cd62ccf 370}
371
372/*****************************************************************************
373 *Function name
374 * ltt_event_data : get the raw data for the event
375 *Input params
376 * e : an instance of an event type
377 *Return value
378 * void * : pointer to the raw data for the event
379 ****************************************************************************/
380
963b5f2d 381void *ltt_event_data(LttEvent *e)
6cd62ccf 382{
383 return e->data;
384}
385
386/*****************************************************************************
387 *Function name
388 * ltt_event_field_element_number
389 * : The number of elements in a sequence field is specific
390 * to each event. This function returns the number of
391 * elements for an array or sequence field in an event.
392 *Input params
908f42fa 393 * e : an instance of an event type
6cd62ccf 394 * f : a field of the instance
395 *Return value
396 * unsigned : the number of elements for an array/sequence field
397 ****************************************************************************/
3aee1200 398guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
6cd62ccf 399{
400 if(f->field_type->type_class != LTT_ARRAY &&
401 f->field_type->type_class != LTT_SEQUENCE)
402 return 0;
908f42fa 403
404 if(f->field_type->type_class == LTT_ARRAY)
405 return f->field_type->element_number;
3aee1200 406 return get_unsigned(LTT_GET_BO(e->tracefile), f->sequ_number_size,
407 e + f->offset_root);
6cd62ccf 408}
409
410/*****************************************************************************
411 *Function name
412 * ltt_event_field_element_select
413 * : Set the currently selected element for a sequence or
414 * array field
3aee1200 415 * O(1) if fields are of fixed size, else O(n) if fields are
416 * of variable size.
6cd62ccf 417 *Input params
908f42fa 418 * e : an instance of an event type
6cd62ccf 419 * f : a field of the instance
3aee1200 420 * i : the ith element (0, ...)
6cd62ccf 421 ****************************************************************************/
963b5f2d 422void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
6cd62ccf 423{
908f42fa 424 unsigned element_number;
3aee1200 425 LttField *field;
8d1e6362 426 unsigned int k;
3aee1200 427 size_t size;
428 LttEventType *event_type;
908f42fa 429
430 if(f->field_type->type_class != LTT_ARRAY &&
6cd62ccf 431 f->field_type->type_class != LTT_SEQUENCE)
908f42fa 432 return ;
433
434 element_number = ltt_event_field_element_number(e,f);
3aee1200 435 event_type = ltt_event_eventtype(e);
436 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
8d1e6362 437 */
3aee1200 438 if(i >= element_number) return;
908f42fa 439
3aee1200 440 field = f->child[0];
441
442 if(f->field_type->type_class == LTT_SEQUENCE)
443 size = f->sequ_number_size;
444 else
445 size = 0;
908f42fa 446
3aee1200 447 if(field->fixed_size == FIELD_FIXED) {
448 size += field->field_size * i;
449
450 get_field_type_size(e->tracefile, event_type,
451 f->offset_root+size, size, field, e->data);
452
453 } else {
454 for(k=0;k<=i;k++){
455 size += get_field_type_size(e->tracefile, event_type,
456 f->offset_root+size, size, field, e->data);
457 }
908f42fa 458 }
3aee1200 459 f->current_element = i;
6cd62ccf 460}
461
462/*****************************************************************************
463 * These functions extract data from an event after architecture specific
464 * conversions
465 ****************************************************************************/
63c35f6c 466guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
6cd62ccf 467{
3aee1200 468 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
0f7f40c1 469
963b5f2d 470 LttTypeEnum t = f->field_type->type_class;
6cd62ccf 471
2a74fbf4 472 g_assert(t == LTT_UINT || t == LTT_ENUM);
6cd62ccf 473
b7b36242 474 if(f->field_size == 1){
cbd41522 475 guint8 x = *(guint8 *)(e->data + f->offset_root);
63c35f6c 476 return (guint32) x;
b7b36242 477 }else if(f->field_size == 2){
0f7f40c1 478 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
b7b36242 479 }else if(f->field_size == 4){
0f7f40c1 480 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
63c35f6c 481 }
482#if 0
483 else if(f->field_size == 8){
cbd41522 484 guint64 x = *(guint64 *)(e->data + f->offset_root);
485 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
486 return (unsigned int) (revFlag ? GUINT64_FROM_BE(x): x);
487 else
488 return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);
6cd62ccf 489 }
63c35f6c 490#endif //0
8d1e6362 491 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
492 return 0;
6cd62ccf 493}
494
63c35f6c 495gint32 ltt_event_get_int(LttEvent *e, LttField *f)
6cd62ccf 496{
3aee1200 497 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
6cd62ccf 498
2a74fbf4 499 g_assert(f->field_type->type_class == LTT_INT);
6cd62ccf 500
b7b36242 501 if(f->field_size == 1){
cbd41522 502 gint8 x = *(gint8 *)(e->data + f->offset_root);
63c35f6c 503 return (gint32) x;
b7b36242 504 }else if(f->field_size == 2){
0f7f40c1 505 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
b7b36242 506 }else if(f->field_size == 4){
0f7f40c1 507 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
63c35f6c 508 }
509#if 0
510 else if(f->field_size == 8){
cbd41522 511 gint64 x = *(gint64 *)(e->data + f->offset_root);
512 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
513 return (int) (revFlag ? GINT64_FROM_BE(x): x);
514 else
515 return (int) (revFlag ? GINT64_FROM_LE(x): x);
6cd62ccf 516 }
63c35f6c 517#endif //0
8d1e6362 518 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
519 return 0;
6cd62ccf 520}
521
63c35f6c 522guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
6cd62ccf 523{
3aee1200 524 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
525
963b5f2d 526 LttTypeEnum t = f->field_type->type_class;
6cd62ccf 527
2a74fbf4 528 g_assert(t == LTT_UINT || t == LTT_ENUM);
6cd62ccf 529
b7b36242 530 if(f->field_size == 1){
cbd41522 531 guint8 x = *(guint8 *)(e->data + f->offset_root);
63c35f6c 532 return (guint64) x;
b7b36242 533 }else if(f->field_size == 2){
0f7f40c1 534 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
b7b36242 535 }else if(f->field_size == 4){
0f7f40c1 536 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
b7b36242 537 }else if(f->field_size == 8){
0f7f40c1 538 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
6cd62ccf 539 }
8d1e6362 540 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
541 return 0;
6cd62ccf 542}
543
63c35f6c 544gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
6cd62ccf 545{
0f7f40c1 546 //int revFlag = e->tracefile->trace->my_arch_endian ==
547 // e->tracefile->trace->system_description->endian ? 0:1;
3aee1200 548 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
6cd62ccf 549
2a74fbf4 550 g_assert( f->field_type->type_class == LTT_INT);
6cd62ccf 551
b7b36242 552 if(f->field_size == 1){
cbd41522 553 gint8 x = *(gint8 *)(e->data + f->offset_root);
63c35f6c 554 return (gint64) x;
b7b36242 555 }else if(f->field_size == 2){
0f7f40c1 556 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
b7b36242 557 }else if(f->field_size == 4){
0f7f40c1 558 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
b7b36242 559 }else if(f->field_size == 8){
0f7f40c1 560 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
6cd62ccf 561 }
8d1e6362 562 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
563 return 0;
6cd62ccf 564}
565
963b5f2d 566float ltt_event_get_float(LttEvent *e, LttField *f)
6cd62ccf 567{
3aee1200 568 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
6cd62ccf 569
2a74fbf4 570 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 4);
6cd62ccf 571
0f7f40c1 572 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
6cd62ccf 573 else{
cbd41522 574 guint32 aInt;
6cd62ccf 575 memcpy((void*)&aInt, e->data + f->offset_root, 4);
576 aInt = ___swab32(aInt);
cf74a6f1 577 return ((float)aInt);
6cd62ccf 578 }
579}
580
963b5f2d 581double ltt_event_get_double(LttEvent *e, LttField *f)
6cd62ccf 582{
3aee1200 583 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
6cd62ccf 584
2a74fbf4 585 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 8);
6cd62ccf 586
0f7f40c1 587 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
6cd62ccf 588 else{
cbd41522 589 guint64 aInt;
6cd62ccf 590 memcpy((void*)&aInt, e->data + f->offset_root, 8);
591 aInt = ___swab64(aInt);
cf74a6f1 592 return ((double)aInt);
6cd62ccf 593 }
594}
595
596/*****************************************************************************
597 * The string obtained is only valid until the next read from
908f42fa 598 * the same tracefile.
6cd62ccf 599 ****************************************************************************/
963b5f2d 600char *ltt_event_get_string(LttEvent *e, LttField *f)
6cd62ccf 601{
2a74fbf4 602 g_assert(f->field_type->type_class == LTT_STRING);
603
45e14832 604 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
6cd62ccf 605}
This page took 0.059722 seconds and 4 git commands to generate.