int get int/unsigned, change if/else for switch
[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 * 2006 Mathieu Desnoyers
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License Version 2.1 as published by the Free Software Foundation.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <glib.h>
28
29 #include <asm/types.h>
30 #include <byteswap.h>
31
32 #include "parser.h"
33 #include <ltt/ltt.h>
34 #include "ltt-private.h"
35 #include <ltt/event.h>
36 #include <ltt/trace.h>
37 #include <ltt/ltt-types.h>
38
39
40
41 void compute_fields_offsets(LttTracefile *tf,
42 LttFacility *fac, LttField *field, off_t *offset, void *root);
43
44
45 LttEvent *ltt_event_new()
46 {
47 return g_new(LttEvent, 1);
48 }
49
50 void ltt_event_destroy(LttEvent *event)
51 {
52 g_free(event);
53 }
54
55
56 /*****************************************************************************
57 *Function name
58 * ltt_event_eventtype_id: get event type id
59 * (base id + position of the event)
60 *Input params
61 * e : an instance of an event type
62 *Return value
63 * unsigned : event type id
64 ****************************************************************************/
65
66 unsigned ltt_event_eventtype_id(const LttEvent *e)
67 {
68 return (unsigned) e->event_id;
69 }
70
71 /*****************************************************************************
72 *Function name
73 * ltt_event_facility : get the facility of the event
74 *Input params
75 * e : an instance of an event type
76 *Return value
77 * LttFacility * : the facility of the event
78 ****************************************************************************/
79
80 LttFacility *ltt_event_facility(const LttEvent *e)
81 {
82 LttTrace * trace = e->tracefile->trace;
83 unsigned id = e->facility_id;
84 LttFacility *facility = ltt_trace_facility_by_id(trace,id);
85
86 g_assert(facility->exists);
87
88 return facility;
89 }
90
91 /*****************************************************************************
92 *Function name
93 * ltt_event_facility_id : get the facility id of the event
94 *Input params
95 * e : an instance of an event type
96 *Return value
97 * unsigned : the facility of the event
98 ****************************************************************************/
99
100 unsigned ltt_event_facility_id(const LttEvent *e)
101 {
102 return e->facility_id;
103 }
104
105 /*****************************************************************************
106 *Function name
107 * ltt_event_eventtype : get the event type of the event
108 *Input params
109 * e : an instance of an event type
110 *Return value
111 * LttEventType * : the event type of the event
112 ****************************************************************************/
113
114 LttEventType *ltt_event_eventtype(const LttEvent *e)
115 {
116 LttFacility* facility = ltt_event_facility(e);
117 if(!facility) return NULL;
118 return &g_array_index(facility->events, LttEventType, e->event_id);
119 }
120
121
122 /*****************************************************************************
123 *Function name
124 * ltt_event_time : get the time of the event
125 *Input params
126 * e : an instance of an event type
127 *Return value
128 * LttTime : the time of the event
129 ****************************************************************************/
130
131 LttTime ltt_event_time(const LttEvent *e)
132 {
133 return e->event_time;
134 }
135
136 /*****************************************************************************
137 *Function name
138 * ltt_event_time : get the cycle count of the event
139 *Input params
140 * e : an instance of an event type
141 *Return value
142 * LttCycleCount : the cycle count of the event
143 ****************************************************************************/
144
145 LttCycleCount ltt_event_cycle_count(const LttEvent *e)
146 {
147 return e->tsc;
148 }
149
150
151
152 /*****************************************************************************
153 *Function name
154 * ltt_event_position_get : get the event position data
155 *Input params
156 * e : an instance of an event type
157 * ep : a pointer to event's position structure
158 * tf : tracefile pointer
159 * block : current block
160 * offset : current offset
161 * tsc : current tsc
162 ****************************************************************************/
163 void ltt_event_position_get(LttEventPosition *ep, LttTracefile **tf,
164 guint *block, guint *offset, guint64 *tsc)
165 {
166 *tf = ep->tracefile;
167 *block = ep->block;
168 *offset = ep->offset;
169 *tsc = ep->tsc;
170 }
171
172
173 /*****************************************************************************
174 *Function name
175 * ltt_event_position : get the event's position
176 *Input params
177 * e : an instance of an event type
178 * ep : a pointer to event's position structure
179 ****************************************************************************/
180
181 void ltt_event_position(LttEvent *e, LttEventPosition *ep)
182 {
183 ep->tracefile = e->tracefile;
184 ep->block = e->block;
185 ep->offset = e->offset;
186 ep->tsc = e->tsc;
187 }
188
189 LttEventPosition * ltt_event_position_new()
190 {
191 return g_new(LttEventPosition, 1);
192 }
193
194
195 /*****************************************************************************
196 * Function name
197 * ltt_event_position_compare : compare two positions
198 * A NULL value is infinite.
199 * Input params
200 * ep1 : a pointer to event's position structure
201 * ep2 : a pointer to event's position structure
202 * Return
203 * -1 is ep1 < ep2
204 * 1 if ep1 > ep2
205 * 0 if ep1 == ep2
206 ****************************************************************************/
207
208
209 gint ltt_event_position_compare(const LttEventPosition *ep1,
210 const LttEventPosition *ep2)
211 {
212 if(ep1 == NULL && ep2 == NULL)
213 return 0;
214 if(ep1 != NULL && ep2 == NULL)
215 return -1;
216 if(ep1 == NULL && ep2 != NULL)
217 return 1;
218
219 if(ep1->tracefile != ep2->tracefile)
220 g_error("ltt_event_position_compare on different tracefiles makes no sense");
221
222 if(ep1->block < ep2->block)
223 return -1;
224 if(ep1->block > ep2->block)
225 return 1;
226 if(ep1->offset < ep2->offset)
227 return -1;
228 if(ep1->offset > ep2->offset)
229 return 1;
230 return 0;
231 }
232
233 /*****************************************************************************
234 * Function name
235 * ltt_event_position_copy : copy position
236 * Input params
237 * src : a pointer to event's position structure source
238 * dest : a pointer to event's position structure dest
239 * Return
240 * void
241 ****************************************************************************/
242 void ltt_event_position_copy(LttEventPosition *dest,
243 const LttEventPosition *src)
244 {
245 if(src == NULL)
246 dest = NULL;
247 else
248 *dest = *src;
249 }
250
251
252
253 LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep)
254 {
255 return ep->tracefile;
256 }
257
258 /*****************************************************************************
259 *Function name
260 * ltt_event_cpu_i: get the cpu id where the event happens
261 *Input params
262 * e : an instance of an event type
263 *Return value
264 * unsigned : the cpu id
265 ****************************************************************************/
266
267 unsigned ltt_event_cpu_id(LttEvent *e)
268 {
269 return e->tracefile->cpu_num;
270 }
271
272 /*****************************************************************************
273 *Function name
274 * ltt_event_data : get the raw data for the event
275 *Input params
276 * e : an instance of an event type
277 *Return value
278 * void * : pointer to the raw data for the event
279 ****************************************************************************/
280
281 void *ltt_event_data(LttEvent *e)
282 {
283 return e->data;
284 }
285
286 /*****************************************************************************
287 *Function name
288 * ltt_event_field_element_number
289 * : The number of elements in a sequence field is specific
290 * to each event. This function returns the number of
291 * elements for an array or sequence field in an event.
292 *Input params
293 * e : an instance of an event type
294 * f : a field of the instance
295 *Return value
296 * unsigned : the number of elements for an array/sequence field
297 ****************************************************************************/
298 guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
299 {
300 if(f->field_type.type_class != LTT_ARRAY &&
301 f->field_type.type_class != LTT_SEQUENCE)
302 return 0;
303
304 if(f->field_type.type_class == LTT_ARRAY)
305 return f->field_type.size;
306 return ltt_event_get_long_unsigned(e, &g_array_index(f->field_type.fields,
307 LttField, 0));
308 }
309
310 /*****************************************************************************
311 *Function name
312 * ltt_event_field_element_select
313 * : Set the currently selected element for a sequence or
314 * array field
315 * O(1) because of offset array.
316 *Input params
317 * e : an instance of an event type
318 * f : a field of the instance
319 * i : the ith element (0, ...)
320 *returns : the child field, at the right index, updated.
321 ****************************************************************************/
322 LttField *ltt_event_field_element_select(LttEvent *e, LttField *f, gulong i)
323 {
324 gulong element_number;
325 LttField *field;
326 unsigned int k;
327 size_t size;
328 LttEventType *event_type;
329 off_t new_offset;
330
331 if(f->field_type.type_class != LTT_ARRAY &&
332 f->field_type.type_class != LTT_SEQUENCE)
333 return NULL;
334
335 element_number = ltt_event_field_element_number(e,f);
336 event_type = ltt_event_eventtype(e);
337 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
338 */
339 if(i >= element_number) return NULL;
340
341 if(f->field_type.type_class == LTT_ARRAY) {
342 field = &g_array_index(f->field_type.fields, LttField, 0);
343 } else {
344 field = &g_array_index(f->field_type.fields, LttField, 1);
345 }
346
347 if(field->field_size != 0) {
348 if(f->array_offset + (i * field->field_size) == field->offset_root)
349 return field; /* fixed length child, already at the right offset */
350 else
351 new_offset = f->array_offset + (i * field->field_size);
352 } else {
353 /* Var. len. child */
354 new_offset = g_array_index(f->dynamic_offsets, off_t, i);
355 }
356 compute_fields_offsets(e->tracefile,
357 ltt_event_facility(e), field, &new_offset, e->data);
358
359 return field;
360 }
361
362
363 off_t ltt_event_field_offset(LttEvent *e, LttField *f)
364 {
365 return f->offset_root;
366 }
367
368
369
370 /*****************************************************************************
371 * These functions extract data from an event after architecture specific
372 * conversions
373 ****************************************************************************/
374 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
375 {
376 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
377
378 switch(f->field_size) {
379 case 1:
380 {
381 guint8 x = *(guint8 *)(e->data + f->offset_root);
382 return (guint32) x;
383 }
384 break;
385 case 2:
386 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
387 break;
388 case 4:
389 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
390 break;
391 case 8:
392 default:
393 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
394 return 0;
395 break;
396 }
397 }
398
399 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
400 {
401 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
402
403 switch(f->field_size) {
404 case 1:
405 {
406 gint8 x = *(gint8 *)(e->data + f->offset_root);
407 return (gint32) x;
408 }
409 break;
410 case 2:
411 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
412 break;
413 case 4:
414 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
415 break;
416 case 8:
417 default:
418 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
419 return 0;
420 break;
421 }
422 }
423
424 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
425 {
426 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
427
428 switch(f->field_size) {
429 case 1:
430 {
431 guint8 x = *(guint8 *)(e->data + f->offset_root);
432 return (guint64) x;
433 }
434 break;
435 case 2:
436 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
437 break;
438 case 4:
439 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
440 break;
441 case 8:
442 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
443 break;
444 default:
445 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
446 return 0;
447 break;
448 }
449 }
450
451 gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
452 {
453 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
454
455 switch(f->field_size) {
456 case 1:
457 {
458 gint8 x = *(gint8 *)(e->data + f->offset_root);
459 return (gint64) x;
460 }
461 break;
462 case 2:
463 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
464 break;
465 case 4:
466 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
467 break;
468 case 8:
469 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
470 break;
471 default:
472 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
473 return 0;
474 break;
475 }
476 }
477
478 float ltt_event_get_float(LttEvent *e, LttField *f)
479 {
480 g_assert(LTT_HAS_FLOAT(e->tracefile));
481 gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
482
483 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 4);
484
485 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
486 else{
487 void *ptr = e->data + f->offset_root;
488 guint32 value = bswap_32(*(guint32*)ptr);
489 return *(float*)&value;
490 }
491 }
492
493 double ltt_event_get_double(LttEvent *e, LttField *f)
494 {
495 g_assert(LTT_HAS_FLOAT(e->tracefile));
496 gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
497
498 if(f->field_size == 4)
499 return ltt_event_get_float(e, f);
500
501 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 8);
502
503 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
504 else {
505 void *ptr = e->data + f->offset_root;
506 guint64 value = bswap_64(*(guint64*)ptr);
507 return *(double*)&value;
508 }
509 }
510
511 /*****************************************************************************
512 * The string obtained is only valid until the next read from
513 * the same tracefile.
514 ****************************************************************************/
515 char *ltt_event_get_string(LttEvent *e, LttField *f)
516 {
517 g_assert(f->field_type.type_class == LTT_STRING);
518
519 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
520 }
521
522 /*****************************************************************************
523 *Function name
524 * compute_fields_offsets : set the precomputable offset of the fields
525 *Input params
526 * fac : facility
527 * field : the field
528 * offset : pointer to the current offset, must be incremented
529 ****************************************************************************/
530
531
532 void compute_fields_offsets(LttTracefile *tf,
533 LttFacility *fac, LttField *field, off_t *offset, void *root)
534 {
535 LttType *type = &field->field_type;
536
537 switch(type->type_class) {
538 case LTT_INT_FIXED:
539 case LTT_UINT_FIXED:
540 case LTT_POINTER:
541 case LTT_CHAR:
542 case LTT_UCHAR:
543 case LTT_SHORT:
544 case LTT_USHORT:
545 case LTT_INT:
546 case LTT_UINT:
547 case LTT_LONG:
548 case LTT_ULONG:
549 case LTT_SIZE_T:
550 case LTT_SSIZE_T:
551 case LTT_OFF_T:
552 case LTT_FLOAT:
553 case LTT_ENUM:
554 if(field->fixed_root == FIELD_VARIABLE) {
555 /* Align offset on type size */
556 *offset += ltt_align(*offset, get_alignment(field),
557 fac->alignment);
558 /* remember offset */
559 field->offset_root = *offset;
560 /* Increment offset */
561 *offset += field->field_size;
562 } else {
563 //g_debug("type before offset : %llu %llu %u\n", *offset,
564 // field->offset_root,
565 // field->field_size);
566 *offset = field->offset_root;
567 *offset += field->field_size;
568 //g_debug("type after offset : %llu\n", *offset);
569 }
570 break;
571 case LTT_STRING:
572 if(field->fixed_root == FIELD_VARIABLE) {
573 field->offset_root = *offset;
574 }
575 *offset += strlen((gchar*)(root+*offset)) + 1;
576 /* Realign the data */
577 *offset += ltt_align(*offset, fac->pointer_size,
578 fac->alignment);
579 break;
580 case LTT_ARRAY:
581 g_assert(type->fields->len == 1);
582 {
583 off_t local_offset;
584 LttField *child = &g_array_index(type->fields, LttField, 0);
585 if(field->fixed_root == FIELD_VARIABLE) {
586 *offset += ltt_align(*offset, get_alignment(field),
587 fac->alignment);
588 /* remember offset */
589 field->offset_root = *offset;
590 field->array_offset = *offset;
591 }
592
593 if(field->field_size != 0) {
594 /* Increment offset */
595 /* field_size is the array size in bytes */
596 *offset = field->offset_root + field->field_size;
597 } else {
598 guint i;
599 *offset = field->array_offset;
600 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
601 0);
602 for(i=0; i<type->size; i++) {
603 g_array_append_val(field->dynamic_offsets, *offset);
604 compute_fields_offsets(tf, fac, child, offset, root);
605 }
606 }
607 // local_offset = field->array_offset;
608 // /* Set the offset at position 0 */
609 // compute_fields_offsets(tf, fac, child, &local_offset, root);
610 }
611 break;
612 case LTT_SEQUENCE:
613 g_assert(type->fields->len == 2);
614 {
615 off_t local_offset;
616 LttField *child;
617 guint i;
618 guint num_elem;
619 if(field->fixed_root == FIELD_VARIABLE) {
620 *offset += ltt_align(*offset, get_alignment(field),
621 fac->alignment);
622 /* remember offset */
623 field->offset_root = *offset;
624
625 child = &g_array_index(type->fields, LttField, 0);
626 compute_fields_offsets(tf, fac, child, offset, root);
627 child = &g_array_index(type->fields, LttField, 1);
628 *offset += ltt_align(*offset, get_alignment(child),
629 fac->alignment);
630 field->array_offset = *offset;
631
632 } else {
633 child = &g_array_index(type->fields, LttField, 1);
634 }
635 *offset = field->array_offset;
636 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
637 0);
638 num_elem = ltt_event_field_element_number(&tf->event, field);
639 for(i=0; i<num_elem; i++) {
640 g_array_append_val(field->dynamic_offsets, *offset);
641 compute_fields_offsets(tf, fac, child, offset, root);
642 }
643 g_assert(num_elem == field->dynamic_offsets->len);
644
645 /* Realign the data */
646 *offset += ltt_align(*offset, fac->pointer_size,
647 fac->alignment);
648
649 // local_offset = field->array_offset;
650 // /* Set the offset at position 0 */
651 // compute_fields_offsets(tf, fac, child, &local_offset, root);
652 }
653 break;
654 case LTT_STRUCT:
655 {
656 LttField *child;
657 guint i;
658 gint ret=0;
659 if(field->fixed_root == FIELD_VARIABLE) {
660 *offset += ltt_align(*offset, get_alignment(fac, field),
661 fac->alignment);
662 /* remember offset */
663 field->offset_root = *offset;
664 } else {
665 *offset = field->offset_root;
666 }
667 for(i=0; i<type->fields->len; i++) {
668 child = &g_array_index(type->fields, LttField, i);
669 compute_fields_offsets(tf, fac, child, offset, root);
670 }
671 }
672 break;
673 case LTT_UNION:
674 {
675 LttField *child;
676 guint i;
677 gint ret=0;
678 if(field->fixed_root == FIELD_VARIABLE) {
679 *offset += ltt_align(*offset, get_alignment(field),
680 fac->alignment);
681 /* remember offset */
682 field->offset_root = *offset;
683 }
684 for(i=0; i<type->fields->len; i++) {
685 *offset = field->offset_root;
686 child = &g_array_index(type->fields, LttField, i);
687 compute_fields_offsets(tf, fac, child, offset, root);
688 }
689 *offset = field->offset_root + field->field_size;
690 }
691 break;
692 case LTT_NONE:
693 default:
694 g_error("compute_fields_offsets : unknown type");
695 }
696
697 }
698
699
700 /*****************************************************************************
701 *Function name
702 * compute_offsets : set the dynamically computable offsets of an event type
703 *Input params
704 * tf : tracefile
705 * event : event type
706 *
707 ****************************************************************************/
708 void compute_offsets(LttTracefile *tf, LttFacility *fac,
709 LttEventType *event, off_t *offset, void *root)
710 {
711 guint i;
712
713 /* compute all variable offsets */
714 for(i=0; i<event->fields->len; i++) {
715 //g_debug("computing offset %u of %u\n", i, event->fields->len-1);
716 LttField *field = &g_array_index(event->fields, LttField, i);
717 compute_fields_offsets(tf, fac, field, offset, root);
718 }
719
720 }
721
This page took 0.045532 seconds and 5 git commands to generate.