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