genevent for 0.1.99.1
[lttv.git] / ltt / branches / poly / ltt-newlib / event.c
CommitLineData
54ecbf38 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
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
6fd96dfe 26#include <glib.h>
54ecbf38 27
28#include <asm/types.h>
29#include <linux/byteorder/swab.h>
30
31#include "parser.h"
32#include <ltt/ltt.h>
33#include "ltt-private.h"
34#include <ltt/event.h>
35#include <ltt/trace.h>
36#include <ltt/ltt-types.h>
37
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
b59cd2f8 50#if 0
51/* Use get_field_type_size instead */
54ecbf38 52/*****************************************************************************
53 *Function name
54 * ltt_event_refresh_fields : refresh fields of an event
55 *Input params
56 * offsetRoot : offset from the root
57 * offsetParent : offset from the parent
58 * fld : field
59 * evD : event data
60 * reverse_byte_order : 1 or 0
61 *Return value
62 * int : size of the field
63 ****************************************************************************/
64
65int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
66 LttField * fld, void *evD, gboolean reverse_byte_order)
67{
68 int size, size1, element_number, i, offset1, offset2;
69 LttType * type = fld->field_type;
70
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,
78 fld->child[0], evD+size, reverse_byte_order);
79 }
80 }else size = fld->field_size;
81 break;
82
83 case LTT_SEQUENCE:
84 size1 = fld->sequ_number_size;
85 element_number = getIntNumber(reverse_byte_order,size1,evD);
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,
93 fld->child[0], evD+size+size1, reverse_byte_order);
94 }
95 size += size1;
96 }
97 break;
98
99 case LTT_STRING:
100 size = strlen((gchar*)evD) + 1; //include end : '\0'
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,
110 fld->child[i],evD+offset2, reverse_byte_order);
111 offset1 += size;
112 offset2 += size;
113 }
114 size = offset2;
115 }else size = fld->field_size;
116 break;
117
118 case LTT_UNION:
119 size = fld->field_size;
120 break;
121
122 default:
123 size = fld->field_size;
124 }
125
126#if 0
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++){
135 size += ltt_event_refresh_fields(offsetRoot+size,size,
136 fld->child[0], evD+size);
137 }
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++){
148 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
149 fld->child[0], evD+size+size1);
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++){
161 size=ltt_event_refresh_fields(offset1,offset2,
162 fld->child[i],evD+offset2);
163 offset1 += size;
164 offset2 += size;
165 }
166 size = offset2;
167 }else size = fld->field_size;
168 }
169#endif //0
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}
b59cd2f8 178#endif //0
179
54ecbf38 180
181/*****************************************************************************
182 *Function name
183 * ltt_event_eventtype_id: get event type id
184 * (base id + position of the event)
185 *Input params
186 * e : an instance of an event type
187 *Return value
188 * unsigned : event type id
189 ****************************************************************************/
190
191unsigned ltt_event_eventtype_id(LttEvent *e)
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
202 * LttFacility * : the facility of the event
203 ****************************************************************************/
204
205LttFacility *ltt_event_facility(LttEvent *e)
206{
207 LttTrace * trace = e->tracefile->trace;
208 unsigned id = e->event_id;
209 return ltt_trace_facility_by_id(trace,id);
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
218 * LttEventType * : the event type of the event
219 ****************************************************************************/
220
221LttEventType *ltt_event_eventtype(LttEvent *e)
222{
223 LttFacility* facility = ltt_event_facility(e);
224 if(!facility) return NULL;
b59cd2f8 225 return &g_array_index(facility->events, LttEventType, e->event_id);
54ecbf38 226}
227
228/*****************************************************************************
229 *Function name
230 * ltt_event_field : get the root field of the event
231 *Input params
232 * e : an instance of an event type
233 *Return value
234 * LttField * : the root field of the event
235 ****************************************************************************/
236
237LttField *ltt_event_field(LttEvent *e)
238{
239 LttField * field;
240 LttEventType * event_type = ltt_event_eventtype(e);
241 if(unlikely(!event_type)) return NULL;
242 field = event_type->root_field;
243 if(unlikely(!field)) return NULL;
244
57b66efc 245 get_field_type_size(e->tracefile, event_type, 0, 0,
246 field, e->data);
247
54ecbf38 248 return field;
249}
250
251/*****************************************************************************
252 *Function name
253 * ltt_event_time : get the time of the event
254 *Input params
255 * e : an instance of an event type
256 *Return value
257 * LttTime : the time of the event
258 ****************************************************************************/
259
260LttTime ltt_event_time(LttEvent *e)
261{
262 return e->event_time;
263}
264
265/*****************************************************************************
266 *Function name
267 * ltt_event_time : get the cycle count of the event
268 *Input params
269 * e : an instance of an event type
270 *Return value
271 * LttCycleCount : the cycle count of the event
272 ****************************************************************************/
273
274LttCycleCount ltt_event_cycle_count(LttEvent *e)
275{
b59cd2f8 276 return e->tsc;
54ecbf38 277}
278
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{
b59cd2f8 289 ep->tracefile = e->tracefile;
290 ep->block = e->block;
291 ep->offset = e->offset;
292 ep->tsc = e->tsc;
54ecbf38 293}
294
295LttEventPosition * ltt_event_position_new()
296{
297 return g_new(LttEventPosition, 1);
298}
299
54ecbf38 300
301/*****************************************************************************
302 * Function name
303 * ltt_event_position_compare : compare two positions
304 * A NULL value is infinite.
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{
54ecbf38 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;
54ecbf38 324
b59cd2f8 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)
54ecbf38 329 return -1;
b59cd2f8 330 if(ep1->block > ep2->block)
54ecbf38 331 return 1;
b59cd2f8 332 if(ep1->offset < ep2->offset)
54ecbf38 333 return -1;
b59cd2f8 334 if(ep1->offset > ep2->offset)
54ecbf38 335 return 1;
336 return 0;
337}
338
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{
351 if(src == NULL)
352 dest = NULL;
353 else
354 *dest = *src;
355}
356
357
358/*****************************************************************************
359 *Function name
360 * ltt_event_cpu_i: get the cpu id where the event happens
361 *Input params
362 * e : an instance of an event type
363 *Return value
364 * unsigned : the cpu id
365 ****************************************************************************/
366
367unsigned ltt_event_cpu_id(LttEvent *e)
b59cd2f8 368{
369 return e->tracefile->cpu_num;
54ecbf38 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
381void *ltt_event_data(LttEvent *e)
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
393 * e : an instance of an event type
394 * f : a field of the instance
395 *Return value
396 * unsigned : the number of elements for an array/sequence field
397 ****************************************************************************/
57b66efc 398guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
54ecbf38 399{
400 if(f->field_type->type_class != LTT_ARRAY &&
401 f->field_type->type_class != LTT_SEQUENCE)
402 return 0;
403
404 if(f->field_type->type_class == LTT_ARRAY)
405 return f->field_type->element_number;
57b66efc 406 return get_unsigned(LTT_GET_BO(e->tracefile), f->sequ_number_size,
407 e + f->offset_root);
54ecbf38 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
6fd96dfe 415 * O(1) if fields are of fixed size, else O(n) if fields are
416 * of variable size.
54ecbf38 417 *Input params
418 * e : an instance of an event type
419 * f : a field of the instance
57b66efc 420 * i : the ith element (0, ...)
54ecbf38 421 ****************************************************************************/
54ecbf38 422void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
423{
424 unsigned element_number;
57b66efc 425 LttField *field;
54ecbf38 426 unsigned int k;
b59cd2f8 427 size_t size;
6fd96dfe 428 LttEventType *event_type;
54ecbf38 429
430 if(f->field_type->type_class != LTT_ARRAY &&
431 f->field_type->type_class != LTT_SEQUENCE)
432 return ;
433
434 element_number = ltt_event_field_element_number(e,f);
6fd96dfe 435 event_type = ltt_event_eventtype(e);
57b66efc 436 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
54ecbf38 437 */
57b66efc 438 if(i >= element_number) return;
54ecbf38 439
57b66efc 440 field = f->child[0];
54ecbf38 441
57b66efc 442 if(f->field_type->type_class == LTT_SEQUENCE)
443 size = f->sequ_number_size;
444 else
445 size = 0;
6fd96dfe 446
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);
57b66efc 452
6fd96dfe 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 }
54ecbf38 458 }
57b66efc 459 f->current_element = i;
54ecbf38 460}
461
462/*****************************************************************************
463 * These functions extract data from an event after architecture specific
464 * conversions
465 ****************************************************************************/
54ecbf38 466guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
467{
b59cd2f8 468 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
54ecbf38 469
470 LttTypeEnum t = f->field_type->type_class;
471
472 g_assert(t == LTT_UINT || t == LTT_ENUM);
473
474 if(f->field_size == 1){
475 guint8 x = *(guint8 *)(e->data + f->offset_root);
476 return (guint32) x;
477 }else if(f->field_size == 2){
478 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
479 }else if(f->field_size == 4){
480 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
481 }
482#if 0
483 else if(f->field_size == 8){
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);
489 }
490#endif //0
491 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
492 return 0;
493}
494
495gint32 ltt_event_get_int(LttEvent *e, LttField *f)
496{
b59cd2f8 497 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
54ecbf38 498
499 g_assert(f->field_type->type_class == LTT_INT);
500
501 if(f->field_size == 1){
502 gint8 x = *(gint8 *)(e->data + f->offset_root);
503 return (gint32) x;
504 }else if(f->field_size == 2){
505 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
506 }else if(f->field_size == 4){
507 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
508 }
509#if 0
510 else if(f->field_size == 8){
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);
516 }
517#endif //0
518 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
519 return 0;
520}
521
522guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
523{
b59cd2f8 524 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
525
54ecbf38 526 LttTypeEnum t = f->field_type->type_class;
527
528 g_assert(t == LTT_UINT || t == LTT_ENUM);
529
530 if(f->field_size == 1){
531 guint8 x = *(guint8 *)(e->data + f->offset_root);
532 return (guint64) x;
533 }else if(f->field_size == 2){
534 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
535 }else if(f->field_size == 4){
536 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
537 }else if(f->field_size == 8){
538 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
539 }
540 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
541 return 0;
542}
543
544gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
545{
546 //int revFlag = e->tracefile->trace->my_arch_endian ==
547 // e->tracefile->trace->system_description->endian ? 0:1;
b59cd2f8 548 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
54ecbf38 549
550 g_assert( f->field_type->type_class == LTT_INT);
551
552 if(f->field_size == 1){
553 gint8 x = *(gint8 *)(e->data + f->offset_root);
554 return (gint64) x;
555 }else if(f->field_size == 2){
556 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
557 }else if(f->field_size == 4){
558 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
559 }else if(f->field_size == 8){
560 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
561 }
562 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
563 return 0;
564}
565
566float ltt_event_get_float(LttEvent *e, LttField *f)
567{
b59cd2f8 568 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
54ecbf38 569
570 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 4);
571
572 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
573 else{
574 guint32 aInt;
575 memcpy((void*)&aInt, e->data + f->offset_root, 4);
576 aInt = ___swab32(aInt);
577 return ((float)aInt);
578 }
579}
580
581double ltt_event_get_double(LttEvent *e, LttField *f)
582{
b59cd2f8 583 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
54ecbf38 584
585 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 8);
586
587 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
588 else{
589 guint64 aInt;
590 memcpy((void*)&aInt, e->data + f->offset_root, 8);
591 aInt = ___swab64(aInt);
592 return ((double)aInt);
593 }
594}
595
596/*****************************************************************************
597 * The string obtained is only valid until the next read from
598 * the same tracefile.
599 ****************************************************************************/
54ecbf38 600char *ltt_event_get_string(LttEvent *e, LttField *f)
601{
602 g_assert(f->field_type->type_class == LTT_STRING);
603
604 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
605}
This page took 0.044711 seconds and 4 git commands to generate.