move everything out of trunk
[lttv.git] / lttng-xenomai / LinuxTraceToolkitViewer-0.8.61-xenoltt / 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 void ltt_event_position_set(LttEventPosition *ep, LttTracefile *tf,
174 guint block, guint offset, guint64 tsc)
175 {
176 ep->tracefile = tf;
177 ep->block = block;
178 ep->offset = offset;
179 ep->tsc = tsc;
180 }
181
182
183 /*****************************************************************************
184 *Function name
185 * ltt_event_position : get the event's position
186 *Input params
187 * e : an instance of an event type
188 * ep : a pointer to event's position structure
189 ****************************************************************************/
190
191 void ltt_event_position(LttEvent *e, LttEventPosition *ep)
192 {
193 ep->tracefile = e->tracefile;
194 ep->block = e->block;
195 ep->offset = e->offset;
196 ep->tsc = e->tsc;
197 }
198
199 LttEventPosition * ltt_event_position_new()
200 {
201 return g_new(LttEventPosition, 1);
202 }
203
204
205 /*****************************************************************************
206 * Function name
207 * ltt_event_position_compare : compare two positions
208 * A NULL value is infinite.
209 * Input params
210 * ep1 : a pointer to event's position structure
211 * ep2 : a pointer to event's position structure
212 * Return
213 * -1 is ep1 < ep2
214 * 1 if ep1 > ep2
215 * 0 if ep1 == ep2
216 ****************************************************************************/
217
218
219 gint ltt_event_position_compare(const LttEventPosition *ep1,
220 const LttEventPosition *ep2)
221 {
222 if(ep1 == NULL && ep2 == NULL)
223 return 0;
224 if(ep1 != NULL && ep2 == NULL)
225 return -1;
226 if(ep1 == NULL && ep2 != NULL)
227 return 1;
228
229 if(ep1->tracefile != ep2->tracefile)
230 g_error("ltt_event_position_compare on different tracefiles makes no sense");
231
232 if(ep1->block < ep2->block)
233 return -1;
234 if(ep1->block > ep2->block)
235 return 1;
236 if(ep1->offset < ep2->offset)
237 return -1;
238 if(ep1->offset > ep2->offset)
239 return 1;
240 return 0;
241 }
242
243 /*****************************************************************************
244 * Function name
245 * ltt_event_position_copy : copy position
246 * Input params
247 * src : a pointer to event's position structure source
248 * dest : a pointer to event's position structure dest
249 * Return
250 * void
251 ****************************************************************************/
252 void ltt_event_position_copy(LttEventPosition *dest,
253 const LttEventPosition *src)
254 {
255 if(src == NULL)
256 dest = NULL;
257 else
258 *dest = *src;
259 }
260
261
262
263 LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep)
264 {
265 return ep->tracefile;
266 }
267
268 /*****************************************************************************
269 *Function name
270 * ltt_event_cpu_i: get the cpu id where the event happens
271 *Input params
272 * e : an instance of an event type
273 *Return value
274 * unsigned : the cpu id
275 ****************************************************************************/
276
277 unsigned ltt_event_cpu_id(LttEvent *e)
278 {
279 return e->tracefile->cpu_num;
280 }
281
282 /*****************************************************************************
283 *Function name
284 * ltt_event_data : get the raw data for the event
285 *Input params
286 * e : an instance of an event type
287 *Return value
288 * void * : pointer to the raw data for the event
289 ****************************************************************************/
290
291 void *ltt_event_data(LttEvent *e)
292 {
293 return e->data;
294 }
295
296 /*****************************************************************************
297 *Function name
298 * ltt_event_field_element_number
299 * : The number of elements in a sequence field is specific
300 * to each event. This function returns the number of
301 * elements for an array or sequence field in an event.
302 *Input params
303 * e : an instance of an event type
304 * f : a field of the instance
305 *Return value
306 * unsigned : the number of elements for an array/sequence field
307 ****************************************************************************/
308 guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
309 {
310 if(f->field_type.type_class != LTT_ARRAY &&
311 f->field_type.type_class != LTT_SEQUENCE)
312 return 0;
313
314 if(f->field_type.type_class == LTT_ARRAY)
315 return f->field_type.size;
316 return ltt_event_get_long_unsigned(e, &g_array_index(f->field_type.fields,
317 LttField, 0));
318 }
319
320 /*****************************************************************************
321 *Function name
322 * ltt_event_field_element_select
323 * : Set the currently selected element for a sequence or
324 * array field
325 * O(1) because of offset array.
326 *Input params
327 * e : an instance of an event type
328 * f : a field of the instance
329 * i : the ith element (0, ...)
330 *returns : the child field, at the right index, updated.
331 ****************************************************************************/
332 LttField *ltt_event_field_element_select(LttEvent *e, LttField *f, gulong i)
333 {
334 gulong element_number;
335 LttField *field;
336 unsigned int k;
337 size_t size;
338 LttEventType *event_type;
339 off_t new_offset;
340
341 if(f->field_type.type_class != LTT_ARRAY &&
342 f->field_type.type_class != LTT_SEQUENCE)
343 return NULL;
344
345 element_number = ltt_event_field_element_number(e,f);
346 event_type = ltt_event_eventtype(e);
347 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
348 */
349 if(i >= element_number) return NULL;
350
351 if(f->field_type.type_class == LTT_ARRAY) {
352 field = &g_array_index(f->field_type.fields, LttField, 0);
353 } else {
354 field = &g_array_index(f->field_type.fields, LttField, 1);
355 }
356
357 if(field->field_size != 0) {
358 if(f->array_offset + (i * field->field_size) == field->offset_root)
359 return field; /* fixed length child, already at the right offset */
360 else
361 new_offset = f->array_offset + (i * field->field_size);
362 } else {
363 /* Var. len. child */
364 new_offset = g_array_index(f->dynamic_offsets, off_t, i);
365 }
366 compute_fields_offsets(e->tracefile,
367 ltt_event_facility(e), field, &new_offset, e->data);
368
369 return field;
370 }
371
372
373 off_t ltt_event_field_offset(LttEvent *e, LttField *f)
374 {
375 return f->offset_root;
376 }
377
378
379
380 /*****************************************************************************
381 * These functions extract data from an event after architecture specific
382 * conversions
383 ****************************************************************************/
384 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
385 {
386 gboolean reverse_byte_order;
387 if(unlikely(f->field_type.network)) {
388 reverse_byte_order = (g_ntohs(0x1) != 0x1);
389 } else {
390 reverse_byte_order = LTT_GET_BO(e->tracefile);
391 }
392
393 switch(f->field_size) {
394 case 1:
395 {
396 guint8 x = *(guint8 *)(e->data + f->offset_root);
397 return (guint32) x;
398 }
399 break;
400 case 2:
401 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
402 break;
403 case 4:
404 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
405 break;
406 case 8:
407 default:
408 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
409 return 0;
410 break;
411 }
412 }
413
414 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
415 {
416 gboolean reverse_byte_order;
417 if(unlikely(f->field_type.network)) {
418 reverse_byte_order = (g_ntohs(0x1) != 0x1);
419 } else {
420 reverse_byte_order = LTT_GET_BO(e->tracefile);
421 }
422
423 switch(f->field_size) {
424 case 1:
425 {
426 gint8 x = *(gint8 *)(e->data + f->offset_root);
427 return (gint32) x;
428 }
429 break;
430 case 2:
431 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
432 break;
433 case 4:
434 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
435 break;
436 case 8:
437 default:
438 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
439 return 0;
440 break;
441 }
442 }
443
444 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
445 {
446 gboolean reverse_byte_order;
447 if(unlikely(f->field_type.network)) {
448 reverse_byte_order = (g_ntohs(0x1) != 0x1);
449 } else {
450 reverse_byte_order = LTT_GET_BO(e->tracefile);
451 }
452
453 switch(f->field_size) {
454 case 1:
455 {
456 guint8 x = *(guint8 *)(e->data + f->offset_root);
457 return (guint64) x;
458 }
459 break;
460 case 2:
461 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
462 break;
463 case 4:
464 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
465 break;
466 case 8:
467 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
468 break;
469 default:
470 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
471 return 0;
472 break;
473 }
474 }
475
476 gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
477 {
478 gboolean reverse_byte_order;
479 if(unlikely(f->field_type.network)) {
480 reverse_byte_order = (g_ntohs(0x1) != 0x1);
481 } else {
482 reverse_byte_order = LTT_GET_BO(e->tracefile);
483 }
484
485 switch(f->field_size) {
486 case 1:
487 {
488 gint8 x = *(gint8 *)(e->data + f->offset_root);
489 return (gint64) x;
490 }
491 break;
492 case 2:
493 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
494 break;
495 case 4:
496 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
497 break;
498 case 8:
499 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
500 break;
501 default:
502 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
503 return 0;
504 break;
505 }
506 }
507
508 float ltt_event_get_float(LttEvent *e, LttField *f)
509 {
510 gboolean reverse_byte_order;
511 if(unlikely(f->field_type.network)) {
512 reverse_byte_order = (g_ntohs(0x1) != 0x1);
513 } else {
514 g_assert(LTT_HAS_FLOAT(e->tracefile));
515 reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
516 }
517
518 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 4);
519
520 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
521 else{
522 void *ptr = e->data + f->offset_root;
523 guint32 value = bswap_32(*(guint32*)ptr);
524 return *(float*)&value;
525 }
526 }
527
528 double ltt_event_get_double(LttEvent *e, LttField *f)
529 {
530 gboolean reverse_byte_order;
531 if(unlikely(f->field_type.network)) {
532 reverse_byte_order = (g_ntohs(0x1) != 0x1);
533 } else {
534 g_assert(LTT_HAS_FLOAT(e->tracefile));
535 reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile);
536 }
537
538 if(f->field_size == 4)
539 return ltt_event_get_float(e, f);
540
541 g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 8);
542
543 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
544 else {
545 void *ptr = e->data + f->offset_root;
546 guint64 value = bswap_64(*(guint64*)ptr);
547 return *(double*)&value;
548 }
549 }
550
551 /*****************************************************************************
552 * The string obtained is only valid until the next read from
553 * the same tracefile.
554 ****************************************************************************/
555 char *ltt_event_get_string(LttEvent *e, LttField *f)
556 {
557 g_assert(f->field_type.type_class == LTT_STRING);
558
559 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
560 }
561
562 /*****************************************************************************
563 *Function name
564 * compute_fields_offsets : set the precomputable offset of the fields
565 *Input params
566 * fac : facility
567 * field : the field
568 * offset : pointer to the current offset, must be incremented
569 ****************************************************************************/
570
571
572 void compute_fields_offsets(LttTracefile *tf,
573 LttFacility *fac, LttField *field, off_t *offset, void *root)
574 {
575 LttType *type = &field->field_type;
576
577 switch(type->type_class) {
578 case LTT_INT_FIXED:
579 case LTT_UINT_FIXED:
580 case LTT_POINTER:
581 case LTT_CHAR:
582 case LTT_UCHAR:
583 case LTT_SHORT:
584 case LTT_USHORT:
585 case LTT_INT:
586 case LTT_UINT:
587 case LTT_LONG:
588 case LTT_ULONG:
589 case LTT_SIZE_T:
590 case LTT_SSIZE_T:
591 case LTT_OFF_T:
592 case LTT_FLOAT:
593 case LTT_ENUM:
594 if(field->fixed_root == FIELD_VARIABLE) {
595 /* Align offset on type size */
596 *offset += ltt_align(*offset, get_alignment(field),
597 fac->alignment);
598 /* remember offset */
599 field->offset_root = *offset;
600 /* Increment offset */
601 *offset += field->field_size;
602 } else {
603 //g_debug("type before offset : %llu %llu %u\n", *offset,
604 // field->offset_root,
605 // field->field_size);
606 *offset = field->offset_root;
607 *offset += field->field_size;
608 //g_debug("type after offset : %llu\n", *offset);
609 }
610 break;
611 case LTT_STRING:
612 if(field->fixed_root == FIELD_VARIABLE) {
613 field->offset_root = *offset;
614 }
615 *offset += strlen((gchar*)(root+*offset)) + 1;
616 /* Realign the data */
617 *offset += ltt_align(*offset, fac->pointer_size,
618 fac->alignment);
619 break;
620 case LTT_ARRAY:
621 g_assert(type->fields->len == 1);
622 {
623 off_t local_offset;
624 LttField *child = &g_array_index(type->fields, LttField, 0);
625 if(field->fixed_root == FIELD_VARIABLE) {
626 *offset += ltt_align(*offset, get_alignment(field),
627 fac->alignment);
628 /* remember offset */
629 field->offset_root = *offset;
630 field->array_offset = *offset;
631 }
632
633 if(field->field_size != 0) {
634 /* Increment offset */
635 /* field_size is the array size in bytes */
636 *offset = field->offset_root + field->field_size;
637 } else {
638 guint i;
639 *offset = field->array_offset;
640 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
641 0);
642 for(i=0; i<type->size; i++) {
643 g_array_append_val(field->dynamic_offsets, *offset);
644 compute_fields_offsets(tf, fac, child, offset, root);
645 }
646 }
647 // local_offset = field->array_offset;
648 // /* Set the offset at position 0 */
649 // compute_fields_offsets(tf, fac, child, &local_offset, root);
650 }
651 break;
652 case LTT_SEQUENCE:
653 g_assert(type->fields->len == 2);
654 {
655 off_t local_offset;
656 LttField *child;
657 guint i;
658 guint num_elem;
659 if(field->fixed_root == FIELD_VARIABLE) {
660 *offset += ltt_align(*offset, get_alignment(field),
661 fac->alignment);
662 /* remember offset */
663 field->offset_root = *offset;
664
665 child = &g_array_index(type->fields, LttField, 0);
666 compute_fields_offsets(tf, fac, child, offset, root);
667 child = &g_array_index(type->fields, LttField, 1);
668 *offset += ltt_align(*offset, get_alignment(child),
669 fac->alignment);
670 field->array_offset = *offset;
671
672 } else {
673 child = &g_array_index(type->fields, LttField, 1);
674 }
675 *offset = field->array_offset;
676 field->dynamic_offsets = g_array_set_size(field->dynamic_offsets,
677 0);
678 num_elem = ltt_event_field_element_number(&tf->event, field);
679 for(i=0; i<num_elem; i++) {
680 g_array_append_val(field->dynamic_offsets, *offset);
681 compute_fields_offsets(tf, fac, child, offset, root);
682 }
683 g_assert(num_elem == field->dynamic_offsets->len);
684
685 /* Realign the data */
686 *offset += ltt_align(*offset, fac->pointer_size,
687 fac->alignment);
688
689 // local_offset = field->array_offset;
690 // /* Set the offset at position 0 */
691 // compute_fields_offsets(tf, fac, child, &local_offset, root);
692 }
693 break;
694 case LTT_STRUCT:
695 {
696 LttField *child;
697 guint i;
698 gint ret=0;
699 if(field->fixed_root == FIELD_VARIABLE) {
700 *offset += ltt_align(*offset, get_alignment(field),
701 fac->alignment);
702 /* remember offset */
703 field->offset_root = *offset;
704 } else {
705 *offset = field->offset_root;
706 }
707 for(i=0; i<type->fields->len; i++) {
708 child = &g_array_index(type->fields, LttField, i);
709 compute_fields_offsets(tf, fac, child, offset, root);
710 }
711 }
712 break;
713 case LTT_UNION:
714 {
715 LttField *child;
716 guint i;
717 gint ret=0;
718 if(field->fixed_root == FIELD_VARIABLE) {
719 *offset += ltt_align(*offset, get_alignment(field),
720 fac->alignment);
721 /* remember offset */
722 field->offset_root = *offset;
723 }
724 for(i=0; i<type->fields->len; i++) {
725 *offset = field->offset_root;
726 child = &g_array_index(type->fields, LttField, i);
727 compute_fields_offsets(tf, fac, child, offset, root);
728 }
729 *offset = field->offset_root + field->field_size;
730 }
731 break;
732 case LTT_NONE:
733 default:
734 g_error("compute_fields_offsets : unknown type");
735 }
736
737 }
738
739
740 /*****************************************************************************
741 *Function name
742 * compute_offsets : set the dynamically computable offsets of an event type
743 *Input params
744 * tf : tracefile
745 * event : event type
746 *
747 ****************************************************************************/
748 void compute_offsets(LttTracefile *tf, LttFacility *fac,
749 LttEventType *event, off_t *offset, void *root)
750 {
751 guint i;
752
753 /* compute all variable offsets */
754 for(i=0; i<event->fields->len; i++) {
755 //g_debug("computing offset %u of %u\n", i, event->fields->len-1);
756 LttField *field = &g_array_index(event->fields, LttField, i);
757 compute_fields_offsets(tf, fac, field, offset, root);
758 }
759
760 }
761
This page took 0.058025 seconds and 4 git commands to generate.