1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
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;
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.
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,
20 #include <asm/types.h>
21 #include <linux/byteorder/swab.h>
25 #include "ltt-private.h"
26 #include <ltt/event.h>
27 #include <ltt/trace.h>
29 /*****************************************************************************
31 * ltt_event_refresh_fields : refresh fields of an event
33 * offsetRoot : offset from the root
34 * offsetParent : offset from the parrent
38 * int : size of the field
39 ****************************************************************************/
41 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
42 LttField
* fld
, void *evD
)
44 int size
, size1
, element_number
, i
, offset1
, offset2
;
45 LttType
* type
= fld
->field_type
;
47 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
48 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
49 size
= fld
->field_size
;
50 }else if(type
->type_class
== LTT_ARRAY
){
51 element_number
= (int) type
->element_number
;
52 if(fld
->field_fixed
== 0){// has string or sequence
54 for(i
=0;i
<element_number
;i
++){
55 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
56 fld
->child
[0], evD
+size
);
58 }else size
= fld
->field_size
;
59 }else if(type
->type_class
== LTT_SEQUENCE
){
60 size1
= fld
->sequ_number_size
;
61 element_number
= getIntNumber(size1
,evD
);
62 type
->element_number
= element_number
;
63 if(fld
->element_size
> 0){
64 size
= element_number
* fld
->element_size
;
65 }else{//sequence has string or sequence
67 for(i
=0;i
<element_number
;i
++){
68 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
69 fld
->child
[0], evD
+size
+size1
);
73 }else if(type
->type_class
== LTT_STRING
){
74 size
= strlen((char*)evD
) + 1; //include end : '\0'
75 }else if(type
->type_class
== LTT_STRUCT
){
76 element_number
= (int) type
->element_number
;
77 if(fld
->field_fixed
== 0){
80 for(i
=0;i
<element_number
;i
++){
81 size
=ltt_event_refresh_fields(offset1
,offset2
,fld
->child
[i
],evD
+offset2
);
86 }else size
= fld
->field_size
;
89 fld
->offset_root
= offsetRoot
;
90 fld
->offset_parent
= offsetParent
;
91 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
92 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
93 fld
->field_size
= size
;
98 /*****************************************************************************
100 * ltt_event_eventtype_id: get event type id
101 * (base id + position of the event)
103 * e : an instance of an event type
105 * unsigned : event type id
106 ****************************************************************************/
108 unsigned ltt_event_eventtype_id(LttEvent
*e
)
110 return (unsigned) e
->event_id
;
113 /*****************************************************************************
115 * ltt_event_facility : get the facility of the event
117 * e : an instance of an event type
119 * LttFacility * : the facility of the event
120 ****************************************************************************/
122 LttFacility
*ltt_event_facility(LttEvent
*e
)
124 LttTrace
* trace
= e
->tracefile
->trace
;
125 unsigned id
= e
->event_id
;
126 return ltt_trace_facility_by_id(trace
,id
);
129 /*****************************************************************************
131 * ltt_event_eventtype : get the event type of the event
133 * e : an instance of an event type
135 * LttEventType * : the event type of the event
136 ****************************************************************************/
138 LttEventType
*ltt_event_eventtype(LttEvent
*e
)
140 LttFacility
* facility
= ltt_event_facility(e
);
141 if(!facility
) return NULL
;
142 return facility
->events
[e
->event_id
- facility
->base_id
];
145 /*****************************************************************************
147 * ltt_event_field : get the root field of the event
149 * e : an instance of an event type
151 * LttField * : the root field of the event
152 ****************************************************************************/
154 LttField
*ltt_event_field(LttEvent
*e
)
157 LttEventType
* event_type
= ltt_event_eventtype(e
);
158 if(!event_type
) return NULL
;
159 field
= event_type
->root_field
;
160 if(!field
) return NULL
;
162 //check if the field need refresh
163 if(e
->which_block
!= event_type
->latest_block
||
164 e
->which_event
!= event_type
->latest_event
){
166 event_type
->latest_block
= e
->which_block
;
167 event_type
->latest_event
= e
->which_event
;
169 if(field
->field_fixed
== 1)return field
;
172 ltt_event_refresh_fields(0, 0, field
, e
->data
);
177 /*****************************************************************************
179 * ltt_event_time : get the time of the event
181 * e : an instance of an event type
183 * LttTime : the time of the event
184 ****************************************************************************/
186 LttTime
ltt_event_time(LttEvent
*e
)
188 return e
->event_time
;
191 /*****************************************************************************
193 * ltt_event_time : get the cycle count of the event
195 * e : an instance of an event type
197 * LttCycleCount : the cycle count of the event
198 ****************************************************************************/
200 LttCycleCount
ltt_event_cycle_count(LttEvent
*e
)
202 return e
->event_cycle_count
;
205 /*****************************************************************************
207 * ltt_event_position : get the event's position
209 * e : an instance of an event type
210 * ep : a pointer to event's position structure
211 ****************************************************************************/
213 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
215 ep
->block_num
= e
->which_block
;
216 ep
->event_num
= e
->which_event
;
217 ep
->event_time
= e
->event_time
;
218 ep
->event_cycle_count
= e
->event_cycle_count
;
219 ep
->heart_beat_number
= e
->tracefile
->cur_heart_beat_number
;
220 ep
->old_position
= FALSE
;
221 ep
->event_offset
= e
->data
- e
->tracefile
->buffer
- EVENT_HEADER_SIZE
;
222 ep
->tf
= e
->tracefile
;
225 LttEventPosition
* ltt_event_position_new()
227 return g_new(LttEventPosition
, 1);
230 /*****************************************************************************
232 * ltt_event_position_get : get the block number and index of the event
234 * ep : a pointer to event's position structure
235 * block_number : the block number of the event
236 * index_in_block : the index of the event within the block
237 ****************************************************************************/
239 void ltt_event_position_get(LttEventPosition
*ep
,
240 unsigned *block_number
, unsigned *index_in_block
, LttTracefile
** tf
)
242 *block_number
= ep
->block_num
;
243 *index_in_block
= ep
->event_num
;
247 /*****************************************************************************
249 * ltt_event_position_set : set the block number and index of the event
251 * ep : a pointer to event's position structure
252 * block_number : the block number of the event
253 * index_in_block : the index of the event within the block
254 ****************************************************************************/
256 void ltt_event_position_set(LttEventPosition
*ep
,
257 unsigned block_number
, unsigned index_in_block
)
259 ep
->block_num
= block_number
;
260 ep
->event_num
= index_in_block
;
263 /*****************************************************************************
265 * ltt_event_position_compare : compare two positions
266 * A NULL value is infinite.
268 * ep1 : a pointer to event's position structure
269 * ep2 : a pointer to event's position structure
274 ****************************************************************************/
277 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
278 const LttEventPosition
*ep2
)
280 if(ep1
->tf
!= ep2
->tf
)
281 g_error("ltt_event_position_compare on different tracefiles makes no sense");
282 if(ep1
== NULL
&& ep2
== NULL
)
284 if(ep1
!= NULL
&& ep2
== NULL
)
286 if(ep1
== NULL
&& ep2
!= NULL
)
289 if(ep1
->block_num
< ep2
->block_num
)
291 if(ep1
->block_num
> ep2
->block_num
)
293 if(ep1
->event_num
< ep2
->event_num
)
295 if(ep1
->event_num
> ep2
->event_num
)
300 /*****************************************************************************
302 * ltt_event_event_position_compare : compare two positions, one in event,
303 * other in position opaque structure.
305 * event : a pointer to event structure
306 * ep : a pointer to event's position structure
311 ****************************************************************************/
313 gint
ltt_event_event_position_compare(const LttEvent
*event
,
314 const LttEventPosition
*ep
)
316 if(event
== NULL
&& ep
== NULL
)
318 if(event
!= NULL
&& ep
== NULL
)
320 if(event
== NULL
&& ep
!= NULL
)
323 g_assert(event
->tracefile
== ep
->tf
);
325 if(event
->which_block
< ep
->block_num
)
327 if(event
->which_block
> ep
->block_num
)
329 if(event
->which_event
< ep
->event_num
)
331 if(event
->which_event
> ep
->event_num
)
336 /*****************************************************************************
338 * ltt_event_position_copy : copy position
340 * src : a pointer to event's position structure source
341 * dest : a pointer to event's position structure dest
344 ****************************************************************************/
345 void ltt_event_position_copy(LttEventPosition
*dest
,
346 const LttEventPosition
*src
)
355 /*****************************************************************************
357 * ltt_event_cpu_i: get the cpu id where the event happens
359 * e : an instance of an event type
361 * unsigned : the cpu id
362 ****************************************************************************/
364 unsigned ltt_event_cpu_id(LttEvent
*e
)
366 char * c1
, * c2
, * c3
;
367 c1
= strrchr(e
->tracefile
->name
,'\\');
368 c2
= strrchr(e
->tracefile
->name
,'/');
369 if(c1
== NULL
&& c2
== NULL
){
370 return (unsigned)atoi(e
->tracefile
->name
);
371 }else if(c1
== NULL
){
373 return (unsigned)atoi(c2
);
374 }else if(c2
== NULL
){
376 return (unsigned)atoi(c1
);
378 c3
= (c1
> c2
) ? c1
: c2
;
380 return (unsigned)atoi(c3
);
384 /*****************************************************************************
386 * ltt_event_data : get the raw data for the event
388 * e : an instance of an event type
390 * void * : pointer to the raw data for the event
391 ****************************************************************************/
393 void *ltt_event_data(LttEvent
*e
)
398 /*****************************************************************************
400 * ltt_event_field_element_number
401 * : The number of elements in a sequence field is specific
402 * to each event. This function returns the number of
403 * elements for an array or sequence field in an event.
405 * e : an instance of an event type
406 * f : a field of the instance
408 * unsigned : the number of elements for an array/sequence field
409 ****************************************************************************/
411 unsigned ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
413 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
414 f
->field_type
->type_class
!= LTT_SEQUENCE
)
417 if(f
->field_type
->type_class
== LTT_ARRAY
)
418 return f
->field_type
->element_number
;
419 return (unsigned) getIntNumber(f
->sequ_number_size
, e
+ f
->offset_root
);
422 /*****************************************************************************
424 * ltt_event_field_element_select
425 * : Set the currently selected element for a sequence or
428 * e : an instance of an event type
429 * f : a field of the instance
430 * i : the ith element
431 ****************************************************************************/
433 void ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, unsigned i
)
435 unsigned element_number
;
440 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
441 f
->field_type
->type_class
!= LTT_SEQUENCE
)
444 element_number
= ltt_event_field_element_number(e
,f
);
445 if((element_number
-1) < i
|| i
< 0) return;
449 evD
= e
->data
+ f
->offset_root
;
452 size
+= ltt_event_refresh_fields(f
->offset_root
+size
,size
, fld
, evD
+size
);
455 f
->current_element
= i
- 1;
458 /*****************************************************************************
459 * These functions extract data from an event after architecture specific
461 ****************************************************************************/
463 unsigned ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
465 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
466 e
->tracefile
->trace
->system_description
->endian
? 0:1;
467 LttTypeEnum t
= f
->field_type
->type_class
;
469 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
471 if(f
->field_size
== 1){
472 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
473 return (unsigned int) x
;
474 }else if(f
->field_size
== 2){
475 guint16 x
= *(guint16
*)(e
->data
+ f
->offset_root
);
476 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
477 return (unsigned int) (revFlag
? GUINT16_FROM_BE(x
): x
);
479 return (unsigned int) (revFlag
? GUINT16_FROM_LE(x
): x
);
480 }else if(f
->field_size
== 4){
481 guint32 x
= *(guint32
*)(e
->data
+ f
->offset_root
);
482 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
483 return (unsigned int) (revFlag
? GUINT32_FROM_BE(x
): x
);
485 return (unsigned int) (revFlag
? GUINT32_FROM_LE(x
): x
);
486 }else if(f
->field_size
== 8){
487 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
488 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
489 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
491 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
495 int ltt_event_get_int(LttEvent
*e
, LttField
*f
)
497 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
498 e
->tracefile
->trace
->system_description
->endian
? 0:1;
500 g_assert(f
->field_type
->type_class
== LTT_INT
);
502 if(f
->field_size
== 1){
503 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
505 }else if(f
->field_size
== 2){
506 gint16 x
= *(gint16
*)(e
->data
+ f
->offset_root
);
507 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
508 return (int) (revFlag
? GINT16_FROM_BE(x
): x
);
510 return (int) (revFlag
? GINT16_FROM_LE(x
): x
);
511 }else if(f
->field_size
== 4){
512 gint32 x
= *(gint32
*)(e
->data
+ f
->offset_root
);
513 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
514 return (int) (revFlag
? GINT32_FROM_BE(x
): x
);
516 return (int) (revFlag
? GINT32_FROM_LE(x
): x
);
517 }else if(f
->field_size
== 8){
518 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
519 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
520 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
522 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
526 unsigned long ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
528 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
529 e
->tracefile
->trace
->system_description
->endian
? 0:1;
530 LttTypeEnum t
= f
->field_type
->type_class
;
532 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
534 if(f
->field_size
== 1){
535 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
536 return (unsigned long) x
;
537 }else if(f
->field_size
== 2){
538 guint16 x
= *(guint16
*)(e
->data
+ f
->offset_root
);
539 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
540 return (unsigned long) (revFlag
? GUINT16_FROM_BE(x
): x
);
542 return (unsigned long) (revFlag
? GUINT16_FROM_LE(x
): x
);
543 }else if(f
->field_size
== 4){
544 guint32 x
= *(guint32
*)(e
->data
+ f
->offset_root
);
545 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
546 return (unsigned long) (revFlag
? GUINT32_FROM_BE(x
): x
);
548 return (unsigned long) (revFlag
? GUINT32_FROM_LE(x
): x
);
549 }else if(f
->field_size
== 8){
550 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
551 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
552 return (unsigned long) (revFlag
? GUINT64_FROM_BE(x
): x
);
554 return (unsigned long) (revFlag
? GUINT64_FROM_LE(x
): x
);
558 long int ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
560 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
561 e
->tracefile
->trace
->system_description
->endian
? 0:1;
563 g_assert( f
->field_type
->type_class
== LTT_INT
);
565 if(f
->field_size
== 1){
566 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
568 }else if(f
->field_size
== 2){
569 gint16 x
= *(gint16
*)(e
->data
+ f
->offset_root
);
570 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
571 return (long) (revFlag
? GINT16_FROM_BE(x
): x
);
573 return (long) (revFlag
? GINT16_FROM_LE(x
): x
);
574 }else if(f
->field_size
== 4){
575 gint32 x
= *(gint32
*)(e
->data
+ f
->offset_root
);
576 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
577 return (long) (revFlag
? GINT32_FROM_BE(x
): x
);
579 return (long) (revFlag
? GINT32_FROM_LE(x
): x
);
580 }else if(f
->field_size
== 8){
581 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
582 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
583 return (long) (revFlag
? GINT64_FROM_BE(x
): x
);
585 return (long) (revFlag
? GINT64_FROM_LE(x
): x
);
589 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
591 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
592 e
->tracefile
->trace
->system_description
->endian
? 0:1;
594 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 4);
596 if(revFlag
== 0) return *(float *)(e
->data
+ f
->offset_root
);
599 memcpy((void*)&aInt
, e
->data
+ f
->offset_root
, 4);
600 aInt
= ___swab32(aInt
);
601 return *((float*)&aInt
);
605 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
607 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
608 e
->tracefile
->trace
->system_description
->endian
? 0:1;
610 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 8);
612 if(revFlag
== 0) return *(double *)(e
->data
+ f
->offset_root
);
615 memcpy((void*)&aInt
, e
->data
+ f
->offset_root
, 8);
616 aInt
= ___swab64(aInt
);
617 return *((double *)&aInt
);
621 /*****************************************************************************
622 * The string obtained is only valid until the next read from
623 * the same tracefile.
624 ****************************************************************************/
626 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
628 g_assert(f
->field_type
->type_class
== LTT_STRING
);
630 return (char*)g_strdup((char*)(e
->data
+ f
->offset_root
));
This page took 0.064462 seconds and 4 git commands to generate.