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,
23 #include <asm/types.h>
24 #include <linux/byteorder/swab.h>
28 #include "ltt-private.h"
29 #include <ltt/event.h>
30 #include <ltt/trace.h>
33 LttEvent
*ltt_event_new()
35 return g_new(LttEvent
, 1);
38 void ltt_event_destroy(LttEvent
*event
)
44 /*****************************************************************************
46 * ltt_event_refresh_fields : refresh fields of an event
48 * offsetRoot : offset from the root
49 * offsetParent : offset from the parent
53 * int : size of the field
54 ****************************************************************************/
56 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
57 LttField
* fld
, void *evD
)
59 int size
, size1
, element_number
, i
, offset1
, offset2
;
60 LttType
* type
= fld
->field_type
;
62 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
63 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
64 size
= fld
->field_size
;
65 }else if(type
->type_class
== LTT_ARRAY
){
66 element_number
= (int) type
->element_number
;
67 if(fld
->field_fixed
== 0){// has string or sequence
69 for(i
=0;i
<element_number
;i
++){
70 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
71 fld
->child
[0], evD
+size
);
73 }else size
= fld
->field_size
;
74 }else if(type
->type_class
== LTT_SEQUENCE
){
75 size1
= fld
->sequ_number_size
;
76 element_number
= getIntNumber(size1
,evD
);
77 type
->element_number
= element_number
;
78 if(fld
->element_size
> 0){
79 size
= element_number
* fld
->element_size
;
80 }else{//sequence has string or sequence
82 for(i
=0;i
<element_number
;i
++){
83 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
84 fld
->child
[0], evD
+size
+size1
);
88 }else if(type
->type_class
== LTT_STRING
){
89 size
= strlen((char*)evD
) + 1; //include end : '\0'
90 }else if(type
->type_class
== LTT_STRUCT
){
91 element_number
= (int) type
->element_number
;
92 if(fld
->field_fixed
== 0){
95 for(i
=0;i
<element_number
;i
++){
96 size
=ltt_event_refresh_fields(offset1
,offset2
,fld
->child
[i
],evD
+offset2
);
101 }else size
= fld
->field_size
;
104 fld
->offset_root
= offsetRoot
;
105 fld
->offset_parent
= offsetParent
;
106 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
107 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
108 fld
->field_size
= size
;
113 /*****************************************************************************
115 * ltt_event_eventtype_id: get event type id
116 * (base id + position of the event)
118 * e : an instance of an event type
120 * unsigned : event type id
121 ****************************************************************************/
123 unsigned ltt_event_eventtype_id(LttEvent
*e
)
125 return (unsigned) e
->event_id
;
128 /*****************************************************************************
130 * ltt_event_facility : get the facility of the event
132 * e : an instance of an event type
134 * LttFacility * : the facility of the event
135 ****************************************************************************/
137 LttFacility
*ltt_event_facility(LttEvent
*e
)
139 LttTrace
* trace
= e
->tracefile
->trace
;
140 unsigned id
= e
->event_id
;
141 return ltt_trace_facility_by_id(trace
,id
);
144 /*****************************************************************************
146 * ltt_event_eventtype : get the event type of the event
148 * e : an instance of an event type
150 * LttEventType * : the event type of the event
151 ****************************************************************************/
153 LttEventType
*ltt_event_eventtype(LttEvent
*e
)
155 LttFacility
* facility
= ltt_event_facility(e
);
156 if(!facility
) return NULL
;
157 return facility
->events
[e
->event_id
- facility
->base_id
];
160 /*****************************************************************************
162 * ltt_event_field : get the root field of the event
164 * e : an instance of an event type
166 * LttField * : the root field of the event
167 ****************************************************************************/
169 LttField
*ltt_event_field(LttEvent
*e
)
172 LttEventType
* event_type
= ltt_event_eventtype(e
);
173 if(!event_type
) return NULL
;
174 field
= event_type
->root_field
;
175 if(!field
) return NULL
;
177 //check if the field need refresh
178 if(e
->which_block
!= event_type
->latest_block
||
179 e
->which_event
!= event_type
->latest_event
){
181 event_type
->latest_block
= e
->which_block
;
182 event_type
->latest_event
= e
->which_event
;
184 if(field
->field_fixed
== 1)return field
;
187 ltt_event_refresh_fields(0, 0, field
, e
->data
);
192 /*****************************************************************************
194 * ltt_event_time : get the time of the event
196 * e : an instance of an event type
198 * LttTime : the time of the event
199 ****************************************************************************/
201 LttTime
ltt_event_time(LttEvent
*e
)
203 return e
->event_time
;
206 /*****************************************************************************
208 * ltt_event_time : get the cycle count of the event
210 * e : an instance of an event type
212 * LttCycleCount : the cycle count of the event
213 ****************************************************************************/
215 LttCycleCount
ltt_event_cycle_count(LttEvent
*e
)
217 return e
->event_cycle_count
;
220 /*****************************************************************************
222 * ltt_event_position : get the event's position
224 * e : an instance of an event type
225 * ep : a pointer to event's position structure
226 ****************************************************************************/
228 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
230 ep
->block_num
= e
->which_block
;
231 ep
->event_num
= e
->which_event
;
232 ep
->event_time
= e
->event_time
;
233 ep
->event_cycle_count
= e
->event_cycle_count
;
234 ep
->heart_beat_number
= e
->tracefile
->cur_heart_beat_number
;
235 ep
->old_position
= TRUE
;
236 ep
->event_offset
= e
->data
- e
->tracefile
->buffer
- EVENT_HEADER_SIZE
;
237 ep
->tf
= e
->tracefile
;
239 /* This is a workaround for fast position seek */
240 ep
->last_event_pos
= e
->last_event_pos
;
241 ep
->prev_block_end_time
= e
->prev_block_end_time
;
242 ep
->prev_event_time
= e
->prev_event_time
;
243 ep
->pre_cycle_count
= e
->pre_cycle_count
;
244 ep
->count
= e
->count
;
245 /* end of workaround */
248 LttEventPosition
* ltt_event_position_new()
250 return g_new(LttEventPosition
, 1);
253 /*****************************************************************************
255 * ltt_event_position_get : get the block number and index of the event
257 * ep : a pointer to event's position structure
258 * block_number : the block number of the event
259 * index_in_block : the index of the event within the block
260 ****************************************************************************/
262 void ltt_event_position_get(LttEventPosition
*ep
,
263 unsigned *block_number
, unsigned *index_in_block
, LttTracefile
** tf
)
265 *block_number
= ep
->block_num
;
266 *index_in_block
= ep
->event_num
;
270 /*****************************************************************************
272 * ltt_event_position_set : set the block number and index of the event
273 * It does put the old_position gboolean to FALSE, as it is impossible
274 * to know the quick position to seek in the tracefile.
276 * ep : a pointer to event's position structure
277 * block_number : the block number of the event
278 * index_in_block : the index of the event within the block
279 ****************************************************************************/
281 void ltt_event_position_set(LttEventPosition
*ep
,
282 unsigned block_number
, unsigned index_in_block
)
284 if(ep
->block_num
!= block_number
|| ep
->event_num
!= index_in_block
)
285 ep
->old_position
= FALSE
;
287 ep
->block_num
= block_number
;
288 ep
->event_num
= index_in_block
;
292 /*****************************************************************************
294 * ltt_event_position_compare : compare two positions
295 * A NULL value is infinite.
297 * ep1 : a pointer to event's position structure
298 * ep2 : a pointer to event's position structure
303 ****************************************************************************/
306 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
307 const LttEventPosition
*ep2
)
309 if(ep1
->tf
!= ep2
->tf
)
310 g_error("ltt_event_position_compare on different tracefiles makes no sense");
311 if(ep1
== NULL
&& ep2
== NULL
)
313 if(ep1
!= NULL
&& ep2
== NULL
)
315 if(ep1
== NULL
&& ep2
!= NULL
)
318 if(ep1
->block_num
< ep2
->block_num
)
320 if(ep1
->block_num
> ep2
->block_num
)
322 if(ep1
->event_num
< ep2
->event_num
)
324 if(ep1
->event_num
> ep2
->event_num
)
329 /*****************************************************************************
331 * ltt_event_event_position_compare : compare two positions, one in event,
332 * other in position opaque structure.
334 * event : a pointer to event structure
335 * ep : a pointer to event's position structure
340 ****************************************************************************/
342 gint
ltt_event_event_position_compare(const LttEvent
*event
,
343 const LttEventPosition
*ep
)
345 if(event
== NULL
&& ep
== NULL
)
347 if(event
!= NULL
&& ep
== NULL
)
349 if(event
== NULL
&& ep
!= NULL
)
352 g_assert(event
->tracefile
== ep
->tf
);
354 if(event
->which_block
< ep
->block_num
)
356 if(event
->which_block
> ep
->block_num
)
358 if(event
->which_event
< ep
->event_num
)
360 if(event
->which_event
> ep
->event_num
)
365 /*****************************************************************************
367 * ltt_event_position_copy : copy position
369 * src : a pointer to event's position structure source
370 * dest : a pointer to event's position structure dest
373 ****************************************************************************/
374 void ltt_event_position_copy(LttEventPosition
*dest
,
375 const LttEventPosition
*src
)
384 /*****************************************************************************
386 * ltt_event_cpu_i: get the cpu id where the event happens
388 * e : an instance of an event type
390 * unsigned : the cpu id
391 ****************************************************************************/
393 unsigned ltt_event_cpu_id(LttEvent
*e
)
395 char * c1
, * c2
, * c3
;
396 c1
= strrchr(e
->tracefile
->name
,'\\');
397 c2
= strrchr(e
->tracefile
->name
,'/');
398 if(c1
== NULL
&& c2
== NULL
){
399 return (unsigned)atoi(e
->tracefile
->name
);
400 }else if(c1
== NULL
){
402 return (unsigned)atoi(c2
);
403 }else if(c2
== NULL
){
405 return (unsigned)atoi(c1
);
407 c3
= (c1
> c2
) ? c1
: c2
;
409 return (unsigned)atoi(c3
);
413 /*****************************************************************************
415 * ltt_event_data : get the raw data for the event
417 * e : an instance of an event type
419 * void * : pointer to the raw data for the event
420 ****************************************************************************/
422 void *ltt_event_data(LttEvent
*e
)
427 /*****************************************************************************
429 * ltt_event_field_element_number
430 * : The number of elements in a sequence field is specific
431 * to each event. This function returns the number of
432 * elements for an array or sequence field in an event.
434 * e : an instance of an event type
435 * f : a field of the instance
437 * unsigned : the number of elements for an array/sequence field
438 ****************************************************************************/
440 unsigned ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
442 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
443 f
->field_type
->type_class
!= LTT_SEQUENCE
)
446 if(f
->field_type
->type_class
== LTT_ARRAY
)
447 return f
->field_type
->element_number
;
448 return (unsigned) getIntNumber(f
->sequ_number_size
, e
+ f
->offset_root
);
451 /*****************************************************************************
453 * ltt_event_field_element_select
454 * : Set the currently selected element for a sequence or
457 * e : an instance of an event type
458 * f : a field of the instance
459 * i : the ith element
460 ****************************************************************************/
462 void ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, unsigned i
)
464 unsigned element_number
;
470 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
471 f
->field_type
->type_class
!= LTT_SEQUENCE
)
474 element_number
= ltt_event_field_element_number(e
,f
);
475 /* Sanity check for i : 1..n only, and must be lower or equal element_number
477 if(element_number
< i
|| i
== 0) return;
481 evD
= e
->data
+ f
->offset_root
;
484 size
+= ltt_event_refresh_fields(f
->offset_root
+size
,size
, fld
, evD
+size
);
486 f
->current_element
= i
- 1;
489 /*****************************************************************************
490 * These functions extract data from an event after architecture specific
492 ****************************************************************************/
494 unsigned ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
496 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
497 e
->tracefile
->trace
->system_description
->endian
? 0:1;
498 LttTypeEnum t
= f
->field_type
->type_class
;
500 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
502 if(f
->field_size
== 1){
503 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
504 return (unsigned int) x
;
505 }else if(f
->field_size
== 2){
506 guint16 x
= *(guint16
*)(e
->data
+ f
->offset_root
);
507 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
508 return (unsigned int) (revFlag
? GUINT16_FROM_BE(x
): x
);
510 return (unsigned int) (revFlag
? GUINT16_FROM_LE(x
): x
);
511 }else if(f
->field_size
== 4){
512 guint32 x
= *(guint32
*)(e
->data
+ f
->offset_root
);
513 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
514 return (unsigned int) (revFlag
? GUINT32_FROM_BE(x
): x
);
516 return (unsigned int) (revFlag
? GUINT32_FROM_LE(x
): x
);
517 }else if(f
->field_size
== 8){
518 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
519 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
520 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
522 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
524 g_critical("ltt_event_get_unsigned : field size %i unknown", f
->field_size
);
528 int ltt_event_get_int(LttEvent
*e
, LttField
*f
)
530 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
531 e
->tracefile
->trace
->system_description
->endian
? 0:1;
533 g_assert(f
->field_type
->type_class
== LTT_INT
);
535 if(f
->field_size
== 1){
536 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
538 }else if(f
->field_size
== 2){
539 gint16 x
= *(gint16
*)(e
->data
+ f
->offset_root
);
540 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
541 return (int) (revFlag
? GINT16_FROM_BE(x
): x
);
543 return (int) (revFlag
? GINT16_FROM_LE(x
): x
);
544 }else if(f
->field_size
== 4){
545 gint32 x
= *(gint32
*)(e
->data
+ f
->offset_root
);
546 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
547 return (int) (revFlag
? GINT32_FROM_BE(x
): x
);
549 return (int) (revFlag
? GINT32_FROM_LE(x
): x
);
550 }else if(f
->field_size
== 8){
551 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
552 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
553 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
555 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
557 g_critical("ltt_event_get_int : field size %i unknown", f
->field_size
);
561 unsigned long ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
563 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
564 e
->tracefile
->trace
->system_description
->endian
? 0:1;
565 LttTypeEnum t
= f
->field_type
->type_class
;
567 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
569 if(f
->field_size
== 1){
570 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
571 return (unsigned long) x
;
572 }else if(f
->field_size
== 2){
573 guint16 x
= *(guint16
*)(e
->data
+ f
->offset_root
);
574 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
575 return (unsigned long) (revFlag
? GUINT16_FROM_BE(x
): x
);
577 return (unsigned long) (revFlag
? GUINT16_FROM_LE(x
): x
);
578 }else if(f
->field_size
== 4){
579 guint32 x
= *(guint32
*)(e
->data
+ f
->offset_root
);
580 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
581 return (unsigned long) (revFlag
? GUINT32_FROM_BE(x
): x
);
583 return (unsigned long) (revFlag
? GUINT32_FROM_LE(x
): x
);
584 }else if(f
->field_size
== 8){
585 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
586 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
587 return (unsigned long) (revFlag
? GUINT64_FROM_BE(x
): x
);
589 return (unsigned long) (revFlag
? GUINT64_FROM_LE(x
): x
);
591 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f
->field_size
);
595 long int ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
597 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
598 e
->tracefile
->trace
->system_description
->endian
? 0:1;
600 g_assert( f
->field_type
->type_class
== LTT_INT
);
602 if(f
->field_size
== 1){
603 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
605 }else if(f
->field_size
== 2){
606 gint16 x
= *(gint16
*)(e
->data
+ f
->offset_root
);
607 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
608 return (long) (revFlag
? GINT16_FROM_BE(x
): x
);
610 return (long) (revFlag
? GINT16_FROM_LE(x
): x
);
611 }else if(f
->field_size
== 4){
612 gint32 x
= *(gint32
*)(e
->data
+ f
->offset_root
);
613 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
614 return (long) (revFlag
? GINT32_FROM_BE(x
): x
);
616 return (long) (revFlag
? GINT32_FROM_LE(x
): x
);
617 }else if(f
->field_size
== 8){
618 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
619 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
620 return (long) (revFlag
? GINT64_FROM_BE(x
): x
);
622 return (long) (revFlag
? GINT64_FROM_LE(x
): x
);
624 g_critical("ltt_event_get_long_int : field size %i unknown", f
->field_size
);
628 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
630 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
631 e
->tracefile
->trace
->system_description
->endian
? 0:1;
633 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 4);
635 if(revFlag
== 0) return *(float *)(e
->data
+ f
->offset_root
);
638 memcpy((void*)&aInt
, e
->data
+ f
->offset_root
, 4);
639 aInt
= ___swab32(aInt
);
640 return *((float*)&aInt
);
644 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
646 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
647 e
->tracefile
->trace
->system_description
->endian
? 0:1;
649 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 8);
651 if(revFlag
== 0) return *(double *)(e
->data
+ f
->offset_root
);
654 memcpy((void*)&aInt
, e
->data
+ f
->offset_root
, 8);
655 aInt
= ___swab64(aInt
);
656 return *((double *)&aInt
);
660 /*****************************************************************************
661 * The string obtained is only valid until the next read from
662 * the same tracefile.
663 ****************************************************************************/
665 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
667 g_assert(f
->field_type
->type_class
== LTT_STRING
);
669 return (char*)g_strdup((char*)(e
->data
+ f
->offset_root
));
This page took 0.106149 seconds and 4 git commands to generate.