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