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