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>
30 LttEvent
*ltt_event_new()
32 return g_new(LttEvent
, 1);
35 void ltt_event_destroy(LttEvent
*event
)
41 /*****************************************************************************
43 * ltt_event_refresh_fields : refresh fields of an event
45 * offsetRoot : offset from the root
46 * offsetParent : offset from the parent
50 * int : size of the field
51 ****************************************************************************/
53 int ltt_event_refresh_fields(int offsetRoot
,int offsetParent
,
54 LttField
* fld
, void *evD
)
56 int size
, size1
, element_number
, i
, offset1
, offset2
;
57 LttType
* type
= fld
->field_type
;
59 if(type
->type_class
!= LTT_STRUCT
&& type
->type_class
!= LTT_ARRAY
&&
60 type
->type_class
!= LTT_SEQUENCE
&& type
->type_class
!= LTT_STRING
){
61 size
= fld
->field_size
;
62 }else if(type
->type_class
== LTT_ARRAY
){
63 element_number
= (int) type
->element_number
;
64 if(fld
->field_fixed
== 0){// has string or sequence
66 for(i
=0;i
<element_number
;i
++){
67 size
+= ltt_event_refresh_fields(offsetRoot
+size
,size
,
68 fld
->child
[0], evD
+size
);
70 }else size
= fld
->field_size
;
71 }else if(type
->type_class
== LTT_SEQUENCE
){
72 size1
= fld
->sequ_number_size
;
73 element_number
= getIntNumber(size1
,evD
);
74 type
->element_number
= element_number
;
75 if(fld
->element_size
> 0){
76 size
= element_number
* fld
->element_size
;
77 }else{//sequence has string or sequence
79 for(i
=0;i
<element_number
;i
++){
80 size
+= ltt_event_refresh_fields(offsetRoot
+size
+size1
,size
+size1
,
81 fld
->child
[0], evD
+size
+size1
);
85 }else if(type
->type_class
== LTT_STRING
){
86 size
= strlen((char*)evD
) + 1; //include end : '\0'
87 }else if(type
->type_class
== LTT_STRUCT
){
88 element_number
= (int) type
->element_number
;
89 if(fld
->field_fixed
== 0){
92 for(i
=0;i
<element_number
;i
++){
93 size
=ltt_event_refresh_fields(offset1
,offset2
,fld
->child
[i
],evD
+offset2
);
98 }else size
= fld
->field_size
;
101 fld
->offset_root
= offsetRoot
;
102 fld
->offset_parent
= offsetParent
;
103 fld
->fixed_root
= (offsetRoot
==-1) ? 0 : 1;
104 fld
->fixed_parent
= (offsetParent
==-1) ? 0 : 1;
105 fld
->field_size
= size
;
110 /*****************************************************************************
112 * ltt_event_eventtype_id: get event type id
113 * (base id + position of the event)
115 * e : an instance of an event type
117 * unsigned : event type id
118 ****************************************************************************/
120 unsigned ltt_event_eventtype_id(LttEvent
*e
)
122 return (unsigned) e
->event_id
;
125 /*****************************************************************************
127 * ltt_event_facility : get the facility of the event
129 * e : an instance of an event type
131 * LttFacility * : the facility of the event
132 ****************************************************************************/
134 LttFacility
*ltt_event_facility(LttEvent
*e
)
136 LttTrace
* trace
= e
->tracefile
->trace
;
137 unsigned id
= e
->event_id
;
138 return ltt_trace_facility_by_id(trace
,id
);
141 /*****************************************************************************
143 * ltt_event_eventtype : get the event type of the event
145 * e : an instance of an event type
147 * LttEventType * : the event type of the event
148 ****************************************************************************/
150 LttEventType
*ltt_event_eventtype(LttEvent
*e
)
152 LttFacility
* facility
= ltt_event_facility(e
);
153 if(!facility
) return NULL
;
154 return facility
->events
[e
->event_id
- facility
->base_id
];
157 /*****************************************************************************
159 * ltt_event_field : get the root field of the event
161 * e : an instance of an event type
163 * LttField * : the root field of the event
164 ****************************************************************************/
166 LttField
*ltt_event_field(LttEvent
*e
)
169 LttEventType
* event_type
= ltt_event_eventtype(e
);
170 if(!event_type
) return NULL
;
171 field
= event_type
->root_field
;
172 if(!field
) return NULL
;
174 //check if the field need refresh
175 if(e
->which_block
!= event_type
->latest_block
||
176 e
->which_event
!= event_type
->latest_event
){
178 event_type
->latest_block
= e
->which_block
;
179 event_type
->latest_event
= e
->which_event
;
181 if(field
->field_fixed
== 1)return field
;
184 ltt_event_refresh_fields(0, 0, field
, e
->data
);
189 /*****************************************************************************
191 * ltt_event_time : get the time of the event
193 * e : an instance of an event type
195 * LttTime : the time of the event
196 ****************************************************************************/
198 LttTime
ltt_event_time(LttEvent
*e
)
200 return e
->event_time
;
203 /*****************************************************************************
205 * ltt_event_time : get the cycle count of the event
207 * e : an instance of an event type
209 * LttCycleCount : the cycle count of the event
210 ****************************************************************************/
212 LttCycleCount
ltt_event_cycle_count(LttEvent
*e
)
214 return e
->event_cycle_count
;
217 /*****************************************************************************
219 * ltt_event_position : get the event's position
221 * e : an instance of an event type
222 * ep : a pointer to event's position structure
223 ****************************************************************************/
225 void ltt_event_position(LttEvent
*e
, LttEventPosition
*ep
)
227 ep
->block_num
= e
->which_block
;
228 ep
->event_num
= e
->which_event
;
229 ep
->event_time
= e
->event_time
;
230 ep
->event_cycle_count
= e
->event_cycle_count
;
231 ep
->heart_beat_number
= e
->tracefile
->cur_heart_beat_number
;
232 ep
->old_position
= TRUE
;
233 ep
->event_offset
= e
->data
- e
->tracefile
->buffer
- EVENT_HEADER_SIZE
;
234 ep
->tf
= e
->tracefile
;
236 /* This is a workaround for fast position seek */
237 ep
->last_event_pos
= e
->last_event_pos
;
238 ep
->prev_block_end_time
= e
->prev_block_end_time
;
239 ep
->prev_event_time
= e
->prev_event_time
;
240 ep
->pre_cycle_count
= e
->pre_cycle_count
;
241 ep
->count
= e
->count
;
242 /* end of workaround */
245 LttEventPosition
* ltt_event_position_new()
247 return g_new(LttEventPosition
, 1);
250 /*****************************************************************************
252 * ltt_event_position_get : get the block number and index of the event
254 * ep : a pointer to event's position structure
255 * block_number : the block number of the event
256 * index_in_block : the index of the event within the block
257 ****************************************************************************/
259 void ltt_event_position_get(LttEventPosition
*ep
,
260 unsigned *block_number
, unsigned *index_in_block
, LttTracefile
** tf
)
262 *block_number
= ep
->block_num
;
263 *index_in_block
= ep
->event_num
;
267 /*****************************************************************************
269 * ltt_event_position_set : set the block number and index of the event
270 * It does put the old_position gboolean to FALSE, as it is impossible
271 * to know the quick position to seek in the tracefile.
273 * ep : a pointer to event's position structure
274 * block_number : the block number of the event
275 * index_in_block : the index of the event within the block
276 ****************************************************************************/
278 void ltt_event_position_set(LttEventPosition
*ep
,
279 unsigned block_number
, unsigned index_in_block
)
281 if(ep
->block_num
!= block_number
|| ep
->event_num
!= index_in_block
)
282 ep
->old_position
= FALSE
;
284 ep
->block_num
= block_number
;
285 ep
->event_num
= index_in_block
;
289 /*****************************************************************************
291 * ltt_event_position_compare : compare two positions
292 * A NULL value is infinite.
294 * ep1 : a pointer to event's position structure
295 * ep2 : a pointer to event's position structure
300 ****************************************************************************/
303 gint
ltt_event_position_compare(const LttEventPosition
*ep1
,
304 const LttEventPosition
*ep2
)
306 if(ep1
->tf
!= ep2
->tf
)
307 g_error("ltt_event_position_compare on different tracefiles makes no sense");
308 if(ep1
== NULL
&& ep2
== NULL
)
310 if(ep1
!= NULL
&& ep2
== NULL
)
312 if(ep1
== NULL
&& ep2
!= NULL
)
315 if(ep1
->block_num
< ep2
->block_num
)
317 if(ep1
->block_num
> ep2
->block_num
)
319 if(ep1
->event_num
< ep2
->event_num
)
321 if(ep1
->event_num
> ep2
->event_num
)
326 /*****************************************************************************
328 * ltt_event_event_position_compare : compare two positions, one in event,
329 * other in position opaque structure.
331 * event : a pointer to event structure
332 * ep : a pointer to event's position structure
337 ****************************************************************************/
339 gint
ltt_event_event_position_compare(const LttEvent
*event
,
340 const LttEventPosition
*ep
)
342 if(event
== NULL
&& ep
== NULL
)
344 if(event
!= NULL
&& ep
== NULL
)
346 if(event
== NULL
&& ep
!= NULL
)
349 g_assert(event
->tracefile
== ep
->tf
);
351 if(event
->which_block
< ep
->block_num
)
353 if(event
->which_block
> ep
->block_num
)
355 if(event
->which_event
< ep
->event_num
)
357 if(event
->which_event
> ep
->event_num
)
362 /*****************************************************************************
364 * ltt_event_position_copy : copy position
366 * src : a pointer to event's position structure source
367 * dest : a pointer to event's position structure dest
370 ****************************************************************************/
371 void ltt_event_position_copy(LttEventPosition
*dest
,
372 const LttEventPosition
*src
)
381 /*****************************************************************************
383 * ltt_event_cpu_i: get the cpu id where the event happens
385 * e : an instance of an event type
387 * unsigned : the cpu id
388 ****************************************************************************/
390 unsigned ltt_event_cpu_id(LttEvent
*e
)
392 char * c1
, * c2
, * c3
;
393 c1
= strrchr(e
->tracefile
->name
,'\\');
394 c2
= strrchr(e
->tracefile
->name
,'/');
395 if(c1
== NULL
&& c2
== NULL
){
396 return (unsigned)atoi(e
->tracefile
->name
);
397 }else if(c1
== NULL
){
399 return (unsigned)atoi(c2
);
400 }else if(c2
== NULL
){
402 return (unsigned)atoi(c1
);
404 c3
= (c1
> c2
) ? c1
: c2
;
406 return (unsigned)atoi(c3
);
410 /*****************************************************************************
412 * ltt_event_data : get the raw data for the event
414 * e : an instance of an event type
416 * void * : pointer to the raw data for the event
417 ****************************************************************************/
419 void *ltt_event_data(LttEvent
*e
)
424 /*****************************************************************************
426 * ltt_event_field_element_number
427 * : The number of elements in a sequence field is specific
428 * to each event. This function returns the number of
429 * elements for an array or sequence field in an event.
431 * e : an instance of an event type
432 * f : a field of the instance
434 * unsigned : the number of elements for an array/sequence field
435 ****************************************************************************/
437 unsigned ltt_event_field_element_number(LttEvent
*e
, LttField
*f
)
439 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
440 f
->field_type
->type_class
!= LTT_SEQUENCE
)
443 if(f
->field_type
->type_class
== LTT_ARRAY
)
444 return f
->field_type
->element_number
;
445 return (unsigned) getIntNumber(f
->sequ_number_size
, e
+ f
->offset_root
);
448 /*****************************************************************************
450 * ltt_event_field_element_select
451 * : Set the currently selected element for a sequence or
454 * e : an instance of an event type
455 * f : a field of the instance
456 * i : the ith element
457 ****************************************************************************/
459 void ltt_event_field_element_select(LttEvent
*e
, LttField
*f
, unsigned i
)
461 unsigned element_number
;
466 if(f
->field_type
->type_class
!= LTT_ARRAY
&&
467 f
->field_type
->type_class
!= LTT_SEQUENCE
)
470 element_number
= ltt_event_field_element_number(e
,f
);
471 if((element_number
-1) < i
|| i
< 0) return;
475 evD
= e
->data
+ f
->offset_root
;
478 size
+= ltt_event_refresh_fields(f
->offset_root
+size
,size
, fld
, evD
+size
);
481 f
->current_element
= i
- 1;
484 /*****************************************************************************
485 * These functions extract data from an event after architecture specific
487 ****************************************************************************/
489 unsigned ltt_event_get_unsigned(LttEvent
*e
, LttField
*f
)
491 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
492 e
->tracefile
->trace
->system_description
->endian
? 0:1;
493 LttTypeEnum t
= f
->field_type
->type_class
;
495 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
497 if(f
->field_size
== 1){
498 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
499 return (unsigned int) x
;
500 }else if(f
->field_size
== 2){
501 guint16 x
= *(guint16
*)(e
->data
+ f
->offset_root
);
502 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
503 return (unsigned int) (revFlag
? GUINT16_FROM_BE(x
): x
);
505 return (unsigned int) (revFlag
? GUINT16_FROM_LE(x
): x
);
506 }else if(f
->field_size
== 4){
507 guint32 x
= *(guint32
*)(e
->data
+ f
->offset_root
);
508 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
509 return (unsigned int) (revFlag
? GUINT32_FROM_BE(x
): x
);
511 return (unsigned int) (revFlag
? GUINT32_FROM_LE(x
): x
);
512 }else if(f
->field_size
== 8){
513 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
514 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
515 return (unsigned int) (revFlag
? GUINT64_FROM_BE(x
): x
);
517 return (unsigned int) (revFlag
? GUINT64_FROM_LE(x
): x
);
521 int ltt_event_get_int(LttEvent
*e
, LttField
*f
)
523 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
524 e
->tracefile
->trace
->system_description
->endian
? 0:1;
526 g_assert(f
->field_type
->type_class
== LTT_INT
);
528 if(f
->field_size
== 1){
529 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
531 }else if(f
->field_size
== 2){
532 gint16 x
= *(gint16
*)(e
->data
+ f
->offset_root
);
533 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
534 return (int) (revFlag
? GINT16_FROM_BE(x
): x
);
536 return (int) (revFlag
? GINT16_FROM_LE(x
): x
);
537 }else if(f
->field_size
== 4){
538 gint32 x
= *(gint32
*)(e
->data
+ f
->offset_root
);
539 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
540 return (int) (revFlag
? GINT32_FROM_BE(x
): x
);
542 return (int) (revFlag
? GINT32_FROM_LE(x
): x
);
543 }else if(f
->field_size
== 8){
544 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
545 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
546 return (int) (revFlag
? GINT64_FROM_BE(x
): x
);
548 return (int) (revFlag
? GINT64_FROM_LE(x
): x
);
552 unsigned long ltt_event_get_long_unsigned(LttEvent
*e
, LttField
*f
)
554 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
555 e
->tracefile
->trace
->system_description
->endian
? 0:1;
556 LttTypeEnum t
= f
->field_type
->type_class
;
558 g_assert(t
== LTT_UINT
|| t
== LTT_ENUM
);
560 if(f
->field_size
== 1){
561 guint8 x
= *(guint8
*)(e
->data
+ f
->offset_root
);
562 return (unsigned long) x
;
563 }else if(f
->field_size
== 2){
564 guint16 x
= *(guint16
*)(e
->data
+ f
->offset_root
);
565 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
566 return (unsigned long) (revFlag
? GUINT16_FROM_BE(x
): x
);
568 return (unsigned long) (revFlag
? GUINT16_FROM_LE(x
): x
);
569 }else if(f
->field_size
== 4){
570 guint32 x
= *(guint32
*)(e
->data
+ f
->offset_root
);
571 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
572 return (unsigned long) (revFlag
? GUINT32_FROM_BE(x
): x
);
574 return (unsigned long) (revFlag
? GUINT32_FROM_LE(x
): x
);
575 }else if(f
->field_size
== 8){
576 guint64 x
= *(guint64
*)(e
->data
+ f
->offset_root
);
577 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
578 return (unsigned long) (revFlag
? GUINT64_FROM_BE(x
): x
);
580 return (unsigned long) (revFlag
? GUINT64_FROM_LE(x
): x
);
584 long int ltt_event_get_long_int(LttEvent
*e
, LttField
*f
)
586 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
587 e
->tracefile
->trace
->system_description
->endian
? 0:1;
589 g_assert( f
->field_type
->type_class
== LTT_INT
);
591 if(f
->field_size
== 1){
592 gint8 x
= *(gint8
*)(e
->data
+ f
->offset_root
);
594 }else if(f
->field_size
== 2){
595 gint16 x
= *(gint16
*)(e
->data
+ f
->offset_root
);
596 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
597 return (long) (revFlag
? GINT16_FROM_BE(x
): x
);
599 return (long) (revFlag
? GINT16_FROM_LE(x
): x
);
600 }else if(f
->field_size
== 4){
601 gint32 x
= *(gint32
*)(e
->data
+ f
->offset_root
);
602 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
603 return (long) (revFlag
? GINT32_FROM_BE(x
): x
);
605 return (long) (revFlag
? GINT32_FROM_LE(x
): x
);
606 }else if(f
->field_size
== 8){
607 gint64 x
= *(gint64
*)(e
->data
+ f
->offset_root
);
608 if(e
->tracefile
->trace
->my_arch_endian
== LTT_LITTLE_ENDIAN
)
609 return (long) (revFlag
? GINT64_FROM_BE(x
): x
);
611 return (long) (revFlag
? GINT64_FROM_LE(x
): x
);
615 float ltt_event_get_float(LttEvent
*e
, LttField
*f
)
617 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
618 e
->tracefile
->trace
->system_description
->endian
? 0:1;
620 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 4);
622 if(revFlag
== 0) return *(float *)(e
->data
+ f
->offset_root
);
625 memcpy((void*)&aInt
, e
->data
+ f
->offset_root
, 4);
626 aInt
= ___swab32(aInt
);
627 return *((float*)&aInt
);
631 double ltt_event_get_double(LttEvent
*e
, LttField
*f
)
633 int revFlag
= e
->tracefile
->trace
->my_arch_endian
==
634 e
->tracefile
->trace
->system_description
->endian
? 0:1;
636 g_assert(f
->field_type
->type_class
== LTT_FLOAT
&& f
->field_size
== 8);
638 if(revFlag
== 0) return *(double *)(e
->data
+ f
->offset_root
);
641 memcpy((void*)&aInt
, e
->data
+ f
->offset_root
, 8);
642 aInt
= ___swab64(aInt
);
643 return *((double *)&aInt
);
647 /*****************************************************************************
648 * The string obtained is only valid until the next read from
649 * the same tracefile.
650 ****************************************************************************/
652 char *ltt_event_get_string(LttEvent
*e
, LttField
*f
)
654 g_assert(f
->field_type
->type_class
== LTT_STRING
);
656 return (char*)g_strdup((char*)(e
->data
+ f
->offset_root
));
This page took 0.059606 seconds and 4 git commands to generate.