many compile fix
[lttv.git] / ltt / branches / poly / ltt / event.c
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 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include <asm/types.h>
24 #include <linux/byteorder/swab.h>
25
26 #include "parser.h"
27 #include <ltt/ltt.h>
28 #include "ltt-private.h"
29 #include <ltt/event.h>
30 #include <ltt/trace.h>
31 #include <ltt/ltt-types.h>
32
33
34 LttEvent *ltt_event_new()
35 {
36 return g_new(LttEvent, 1);
37 }
38
39 void ltt_event_destroy(LttEvent *event)
40 {
41 g_free(event);
42 }
43
44
45 /*****************************************************************************
46 *Function name
47 * ltt_event_refresh_fields : refresh fields of an event
48 *Input params
49 * offsetRoot : offset from the root
50 * offsetParent : offset from the parent
51 * fld : field
52 * evD : event data
53 * reverse_byte_order : 1 or 0
54 *Return value
55 * int : size of the field
56 ****************************************************************************/
57
58 int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
59 LttField * fld, void *evD, gboolean reverse_byte_order)
60 {
61 int size, size1, element_number, i, offset1, offset2;
62 LttType * type = fld->field_type;
63
64 switch(type->type_class) {
65 case LTT_ARRAY:
66 element_number = (int) type->element_number;
67 if(fld->field_fixed == 0){// has string or sequence
68 size = 0;
69 for(i=0;i<element_number;i++){
70 size += ltt_event_refresh_fields(offsetRoot+size,size,
71 fld->child[0], evD+size, reverse_byte_order);
72 }
73 }else size = fld->field_size;
74 break;
75
76 case LTT_SEQUENCE:
77 size1 = fld->sequ_number_size;
78 element_number = getIntNumber(reverse_byte_order,size1,evD);
79 type->element_number = element_number;
80 if(fld->element_size > 0){
81 size = element_number * fld->element_size;
82 }else{//sequence has string or sequence
83 size = 0;
84 for(i=0;i<element_number;i++){
85 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
86 fld->child[0], evD+size+size1, reverse_byte_order);
87 }
88 size += size1;
89 }
90 break;
91
92 case LTT_STRING:
93 size = strlen((char*)evD) + 1; //include end : '\0'
94 break;
95
96 case LTT_STRUCT:
97 element_number = (int) type->element_number;
98 if(fld->field_fixed == 0){
99 offset1 = offsetRoot;
100 offset2 = 0;
101 for(i=0;i<element_number;i++){
102 size=ltt_event_refresh_fields(offset1,offset2,
103 fld->child[i],evD+offset2, reverse_byte_order);
104 offset1 += size;
105 offset2 += size;
106 }
107 size = offset2;
108 }else size = fld->field_size;
109 break;
110
111 case LTT_UNION:
112 size = fld->field_size;
113 break;
114
115 default:
116 size = fld->field_size;
117 }
118
119 #if 0
120 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
121 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
122 size = fld->field_size;
123 }else if(type->type_class == LTT_ARRAY){
124 element_number = (int) type->element_number;
125 if(fld->field_fixed == 0){// has string or sequence
126 size = 0;
127 for(i=0;i<element_number;i++){
128 size += ltt_event_refresh_fields(offsetRoot+size,size,
129 fld->child[0], evD+size);
130 }
131 }else size = fld->field_size;
132 }else if(type->type_class == LTT_SEQUENCE){
133 size1 = fld->sequ_number_size;
134 element_number = getIntNumber(size1,evD);
135 type->element_number = element_number;
136 if(fld->element_size > 0){
137 size = element_number * fld->element_size;
138 }else{//sequence has string or sequence
139 size = 0;
140 for(i=0;i<element_number;i++){
141 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
142 fld->child[0], evD+size+size1);
143 }
144 size += size1;
145 }
146 }else if(type->type_class == LTT_STRING){
147 size = strlen((char*)evD) + 1; //include end : '\0'
148 }else if(type->type_class == LTT_STRUCT){
149 element_number = (int) type->element_number;
150 if(fld->field_fixed == 0){
151 offset1 = offsetRoot;
152 offset2 = 0;
153 for(i=0;i<element_number;i++){
154 size=ltt_event_refresh_fields(offset1,offset2,
155 fld->child[i],evD+offset2);
156 offset1 += size;
157 offset2 += size;
158 }
159 size = offset2;
160 }else size = fld->field_size;
161 }
162 #endif //0
163 fld->offset_root = offsetRoot;
164 fld->offset_parent = offsetParent;
165 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
166 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
167 fld->field_size = size;
168
169 return size;
170 }
171
172 /*****************************************************************************
173 *Function name
174 * ltt_event_eventtype_id: get event type id
175 * (base id + position of the event)
176 *Input params
177 * e : an instance of an event type
178 *Return value
179 * unsigned : event type id
180 ****************************************************************************/
181
182 unsigned ltt_event_eventtype_id(LttEvent *e)
183 {
184 return (unsigned) e->event_id;
185 }
186
187 /*****************************************************************************
188 *Function name
189 * ltt_event_facility : get the facility of the event
190 *Input params
191 * e : an instance of an event type
192 *Return value
193 * LttFacility * : the facility of the event
194 ****************************************************************************/
195
196 LttFacility *ltt_event_facility(LttEvent *e)
197 {
198 LttTrace * trace = e->tracefile->trace;
199 unsigned id = e->event_id;
200 return ltt_trace_facility_by_id(trace,id);
201 }
202
203 /*****************************************************************************
204 *Function name
205 * ltt_event_eventtype : get the event type of the event
206 *Input params
207 * e : an instance of an event type
208 *Return value
209 * LttEventType * : the event type of the event
210 ****************************************************************************/
211
212 LttEventType *ltt_event_eventtype(LttEvent *e)
213 {
214 LttFacility* facility = ltt_event_facility(e);
215 if(!facility) return NULL;
216 return facility->events[e->event_id - facility->base_id];
217 }
218
219 /*****************************************************************************
220 *Function name
221 * ltt_event_field : get the root field of the event
222 *Input params
223 * e : an instance of an event type
224 *Return value
225 * LttField * : the root field of the event
226 ****************************************************************************/
227
228 LttField *ltt_event_field(LttEvent *e)
229 {
230 LttField * field;
231 LttEventType * event_type = ltt_event_eventtype(e);
232 if(unlikely(!event_type)) return NULL;
233 field = event_type->root_field;
234 if(unlikely(!field)) return NULL;
235
236 //check if the field need refresh
237 if(likely(e->which_block != event_type->latest_block ||
238 e->which_event != event_type->latest_event)){
239
240 event_type->latest_block = e->which_block;
241 event_type->latest_event = e->which_event;
242
243 if(unlikely(field->field_fixed != 1))
244 ltt_event_refresh_fields(0, 0, field, e->data,
245 e->tracefile->trace->reverse_byte_order);
246 }
247 return field;
248 }
249
250 /*****************************************************************************
251 *Function name
252 * ltt_event_time : get the time of the event
253 *Input params
254 * e : an instance of an event type
255 *Return value
256 * LttTime : the time of the event
257 ****************************************************************************/
258
259 LttTime ltt_event_time(LttEvent *e)
260 {
261 return e->event_time;
262 }
263
264 /*****************************************************************************
265 *Function name
266 * ltt_event_time : get the cycle count of the event
267 *Input params
268 * e : an instance of an event type
269 *Return value
270 * LttCycleCount : the cycle count of the event
271 ****************************************************************************/
272
273 LttCycleCount ltt_event_cycle_count(LttEvent *e)
274 {
275 return e->event_cycle_count;
276 }
277
278 /*****************************************************************************
279 *Function name
280 * ltt_event_position : get the event's position
281 *Input params
282 * e : an instance of an event type
283 * ep : a pointer to event's position structure
284 ****************************************************************************/
285
286 void ltt_event_position(LttEvent *e, LttEventPosition *ep)
287 {
288 ep->block_num = e->which_block;
289 ep->event_num = e->which_event;
290 ep->event_time = e->event_time;
291 ep->event_cycle_count = e->event_cycle_count;
292 ep->heart_beat_number = e->tracefile->cur_heart_beat_number;
293 ep->old_position = TRUE;
294 ep->event_offset = e->data - e->tracefile->buffer - EVENT_HEADER_SIZE ;
295 ep->tf = e->tracefile;
296 ep->overflow_nsec = e->overflow_nsec;
297 /* This is a workaround for fast position seek */
298 ep->last_event_pos = e->last_event_pos;
299 ep->prev_block_end_time = e->prev_block_end_time;
300 ep->prev_event_time = e->prev_event_time;
301 ep->pre_cycle_count = e->pre_cycle_count;
302 ep->count = e->count;
303 ep->last_heartbeat = e->last_heartbeat;
304
305 /* end of workaround */
306 }
307
308 LttEventPosition * ltt_event_position_new()
309 {
310 return g_new(LttEventPosition, 1);
311 }
312
313 /*****************************************************************************
314 *Function name
315 * ltt_event_position_get : get the block number and index of the event
316 *Input params
317 * ep : a pointer to event's position structure
318 * block_number : the block number of the event
319 * index_in_block : the index of the event within the block
320 ****************************************************************************/
321
322 void ltt_event_position_get(LttEventPosition *ep,
323 unsigned *block_number, unsigned *index_in_block, LttTracefile ** tf)
324 {
325 *block_number = ep->block_num;
326 *index_in_block = ep->event_num;
327 *tf = ep->tf;
328 }
329
330 /*****************************************************************************
331 *Function name
332 * ltt_event_position_set : set the block number and index of the event
333 * It does put the old_position gboolean to FALSE, as it is impossible
334 * to know the quick position to seek in the tracefile.
335 *Input params
336 * ep : a pointer to event's position structure
337 * block_number : the block number of the event
338 * index_in_block : the index of the event within the block
339 ****************************************************************************/
340
341 void ltt_event_position_set(LttEventPosition *ep,
342 unsigned block_number, unsigned index_in_block)
343 {
344 if(ep->block_num != block_number || ep->event_num != index_in_block)
345 ep->old_position = FALSE;
346
347 ep->block_num = block_number;
348 ep->event_num = index_in_block;
349
350 }
351
352 /*****************************************************************************
353 * Function name
354 * ltt_event_position_compare : compare two positions
355 * A NULL value is infinite.
356 * Input params
357 * ep1 : a pointer to event's position structure
358 * ep2 : a pointer to event's position structure
359 * Return
360 * -1 is ep1 < ep2
361 * 1 if ep1 > ep2
362 * 0 if ep1 == ep2
363 ****************************************************************************/
364
365
366 gint ltt_event_position_compare(const LttEventPosition *ep1,
367 const LttEventPosition *ep2)
368 {
369 if(ep1->tf != ep2->tf)
370 g_error("ltt_event_position_compare on different tracefiles makes no sense");
371 if(ep1 == NULL && ep2 == NULL)
372 return 0;
373 if(ep1 != NULL && ep2 == NULL)
374 return -1;
375 if(ep1 == NULL && ep2 != NULL)
376 return 1;
377
378 if(ep1->block_num < ep2->block_num)
379 return -1;
380 if(ep1->block_num > ep2->block_num)
381 return 1;
382 if(ep1->event_num < ep2->event_num)
383 return -1;
384 if(ep1->event_num > ep2->event_num)
385 return 1;
386 return 0;
387 }
388
389 /*****************************************************************************
390 * Function name
391 * ltt_event_event_position_compare : compare two positions, one in event,
392 * other in position opaque structure.
393 * Input params
394 * event : a pointer to event structure
395 * ep : a pointer to event's position structure
396 * Return
397 * -1 is event < ep
398 * 1 if event > ep
399 * 0 if event == ep
400 ****************************************************************************/
401
402 gint ltt_event_event_position_compare(const LttEvent *event,
403 const LttEventPosition *ep)
404 {
405 if(event == NULL && ep == NULL)
406 return 0;
407 if(event != NULL && ep == NULL)
408 return -1;
409 if(event == NULL && ep != NULL)
410 return 1;
411
412 g_assert(event->tracefile == ep->tf);
413
414 if(event->which_block < ep->block_num)
415 return -1;
416 if(event->which_block > ep->block_num)
417 return 1;
418 if(event->which_event < ep->event_num)
419 return -1;
420 if(event->which_event > ep->event_num)
421 return 1;
422 return 0;
423 }
424
425 /*****************************************************************************
426 * Function name
427 * ltt_event_position_copy : copy position
428 * Input params
429 * src : a pointer to event's position structure source
430 * dest : a pointer to event's position structure dest
431 * Return
432 * void
433 ****************************************************************************/
434 void ltt_event_position_copy(LttEventPosition *dest,
435 const LttEventPosition *src)
436 {
437 if(src == NULL)
438 dest = NULL;
439 else
440 *dest = *src;
441 }
442
443
444 /*****************************************************************************
445 *Function name
446 * ltt_event_cpu_i: get the cpu id where the event happens
447 *Input params
448 * e : an instance of an event type
449 *Return value
450 * unsigned : the cpu id
451 ****************************************************************************/
452
453 unsigned ltt_event_cpu_id(LttEvent *e)
454 {
455 char * c1, * c2, * c3;
456 c1 = strrchr(e->tracefile->name,'\\');
457 c2 = strrchr(e->tracefile->name,'/');
458 if(c1 == NULL && c2 == NULL){
459 return (unsigned)atoi(e->tracefile->name);
460 }else if(c1 == NULL){
461 c2++;
462 return (unsigned)atoi(c2);
463 }else if(c2 == NULL){
464 c1++;
465 return (unsigned)atoi(c1);
466 }else{
467 c3 = (c1 > c2) ? c1 : c2;
468 c3++;
469 return (unsigned)atoi(c3);
470 }
471 }
472
473 /*****************************************************************************
474 *Function name
475 * ltt_event_data : get the raw data for the event
476 *Input params
477 * e : an instance of an event type
478 *Return value
479 * void * : pointer to the raw data for the event
480 ****************************************************************************/
481
482 void *ltt_event_data(LttEvent *e)
483 {
484 return e->data;
485 }
486
487 /*****************************************************************************
488 *Function name
489 * ltt_event_field_element_number
490 * : The number of elements in a sequence field is specific
491 * to each event. This function returns the number of
492 * elements for an array or sequence field in an event.
493 *Input params
494 * e : an instance of an event type
495 * f : a field of the instance
496 *Return value
497 * unsigned : the number of elements for an array/sequence field
498 ****************************************************************************/
499
500 unsigned ltt_event_field_element_number(LttEvent *e, LttField *f)
501 {
502 if(f->field_type->type_class != LTT_ARRAY &&
503 f->field_type->type_class != LTT_SEQUENCE)
504 return 0;
505
506 if(f->field_type->type_class == LTT_ARRAY)
507 return f->field_type->element_number;
508 return (unsigned) getIntNumber(e->tracefile->trace->reverse_byte_order,
509 f->sequ_number_size, e + f->offset_root);
510 }
511
512 /*****************************************************************************
513 *Function name
514 * ltt_event_field_element_select
515 * : Set the currently selected element for a sequence or
516 * array field
517 *Input params
518 * e : an instance of an event type
519 * f : a field of the instance
520 * i : the ith element
521 ****************************************************************************/
522
523 void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
524 {
525 unsigned element_number;
526 LttField *fld;
527 unsigned int k;
528 int size;
529 void *evD;
530
531 if(f->field_type->type_class != LTT_ARRAY &&
532 f->field_type->type_class != LTT_SEQUENCE)
533 return ;
534
535 element_number = ltt_event_field_element_number(e,f);
536 /* Sanity check for i : 1..n only, and must be lower or equal element_number
537 */
538 if(element_number < i || i == 0) return;
539
540 fld = f->child[0];
541
542 evD = e->data + f->offset_root;
543 size = 0;
544 for(k=0;k<i;k++){
545 size += ltt_event_refresh_fields(f->offset_root+size,size, fld, evD+size,
546 e->tracefile->trace->reverse_byte_order);
547 }
548 f->current_element = i - 1;
549 }
550
551 /*****************************************************************************
552 * These functions extract data from an event after architecture specific
553 * conversions
554 ****************************************************************************/
555
556 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
557 {
558 //int revFlag = e->tracefile->trace->my_arch_endian ==
559 // e->tracefile->trace->system_description->endian ? 0:1;
560 gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
561
562 LttTypeEnum t = f->field_type->type_class;
563
564 g_assert(t == LTT_UINT || t == LTT_ENUM);
565
566 if(f->field_size == 1){
567 guint8 x = *(guint8 *)(e->data + f->offset_root);
568 return (guint32) x;
569 }else if(f->field_size == 2){
570 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
571 }else if(f->field_size == 4){
572 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
573 }
574 #if 0
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 int) (revFlag ? GUINT64_FROM_BE(x): x);
579 else
580 return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);
581 }
582 #endif //0
583 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
584 return 0;
585 }
586
587 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
588 {
589 gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
590 //int revFlag = e->tracefile->trace->my_arch_endian ==
591 // e->tracefile->trace->system_description->endian ? 0:1;
592
593 g_assert(f->field_type->type_class == LTT_INT);
594
595 if(f->field_size == 1){
596 gint8 x = *(gint8 *)(e->data + f->offset_root);
597 return (gint32) x;
598 }else if(f->field_size == 2){
599 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
600 }else if(f->field_size == 4){
601 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
602 }
603 #if 0
604 else if(f->field_size == 8){
605 gint64 x = *(gint64 *)(e->data + f->offset_root);
606 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
607 return (int) (revFlag ? GINT64_FROM_BE(x): x);
608 else
609 return (int) (revFlag ? GINT64_FROM_LE(x): x);
610 }
611 #endif //0
612 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
613 return 0;
614 }
615
616 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
617 {
618 gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
619 //int revFlag = e->tracefile->trace->my_arch_endian ==
620 // e->tracefile->trace->system_description->endian ? 0:1;
621 LttTypeEnum t = f->field_type->type_class;
622
623 g_assert(t == LTT_UINT || t == LTT_ENUM);
624
625 if(f->field_size == 1){
626 guint8 x = *(guint8 *)(e->data + f->offset_root);
627 return (guint64) x;
628 }else if(f->field_size == 2){
629 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
630 }else if(f->field_size == 4){
631 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
632 }else if(f->field_size == 8){
633 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
634 }
635 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
636 return 0;
637 }
638
639 gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
640 {
641 //int revFlag = e->tracefile->trace->my_arch_endian ==
642 // e->tracefile->trace->system_description->endian ? 0:1;
643 gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
644
645 g_assert( f->field_type->type_class == LTT_INT);
646
647 if(f->field_size == 1){
648 gint8 x = *(gint8 *)(e->data + f->offset_root);
649 return (gint64) x;
650 }else if(f->field_size == 2){
651 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
652 }else if(f->field_size == 4){
653 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
654 }else if(f->field_size == 8){
655 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
656 }
657 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
658 return 0;
659 }
660
661 float ltt_event_get_float(LttEvent *e, LttField *f)
662 {
663 //int revFlag = e->tracefile->trace->my_arch_endian ==
664 // e->tracefile->trace->system_description->endian ? 0:1;
665 gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
666
667 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 4);
668
669 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
670 else{
671 guint32 aInt;
672 memcpy((void*)&aInt, e->data + f->offset_root, 4);
673 aInt = ___swab32(aInt);
674 return ((float)aInt);
675 }
676 }
677
678 double ltt_event_get_double(LttEvent *e, LttField *f)
679 {
680 gboolean reverse_byte_order = e->tracefile->trace->reverse_byte_order;
681 //int revFlag = e->tracefile->trace->my_arch_endian ==
682 // e->tracefile->trace->system_description->endian ? 0:1;
683
684 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 8);
685
686 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
687 else{
688 guint64 aInt;
689 memcpy((void*)&aInt, e->data + f->offset_root, 8);
690 aInt = ___swab64(aInt);
691 return ((double)aInt);
692 }
693 }
694
695 /*****************************************************************************
696 * The string obtained is only valid until the next read from
697 * the same tracefile.
698 ****************************************************************************/
699
700 char *ltt_event_get_string(LttEvent *e, LttField *f)
701 {
702 g_assert(f->field_type->type_class == LTT_STRING);
703
704 return (char*)g_strdup((char*)(e->data + f->offset_root));
705 }
This page took 0.046442 seconds and 4 git commands to generate.