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