449cb9d7 |
1 | /* This file is part of the Linux Trace Toolkit viewer |
2 | * Copyright (C) 2003-2004 Xiangxiu Yang |
1b44b0b5 |
3 | * 2006 Mathieu Desnoyers |
449cb9d7 |
4 | * |
1b44b0b5 |
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. |
449cb9d7 |
8 | * |
1b44b0b5 |
9 | * This library is distributed in the hope that it will be useful, |
449cb9d7 |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1b44b0b5 |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
449cb9d7 |
13 | * |
1b44b0b5 |
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. |
449cb9d7 |
18 | */ |
19 | |
4e4d11b3 |
20 | #ifdef HAVE_CONFIG_H |
21 | #include <config.h> |
22 | #endif |
23 | |
6cd62ccf |
24 | #include <stdio.h> |
8d1e6362 |
25 | #include <string.h> |
26 | #include <stdlib.h> |
3aee1200 |
27 | #include <glib.h> |
8d1e6362 |
28 | |
6cd62ccf |
29 | #include <asm/types.h> |
d4214418 |
30 | #include <byteswap.h> |
a5dcde2f |
31 | |
6cd62ccf |
32 | #include "parser.h" |
a5dcde2f |
33 | #include <ltt/ltt.h> |
34 | #include "ltt-private.h" |
6cd62ccf |
35 | #include <ltt/event.h> |
a5dcde2f |
36 | #include <ltt/trace.h> |
0f7f40c1 |
37 | #include <ltt/ltt-types.h> |
6cd62ccf |
38 | |
2312de30 |
39 | |
40 | |
743e50fd |
41 | void compute_fields_offsets(LttTracefile *tf, |
42 | LttFacility *fac, LttField *field, off_t *offset, void *root); |
2312de30 |
43 | |
44 | |
c02ea99f |
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 | |
6cd62ccf |
56 | /***************************************************************************** |
57 | *Function name |
963b5f2d |
58 | * ltt_event_eventtype_id: get event type id |
59 | * (base id + position of the event) |
6cd62ccf |
60 | *Input params |
963b5f2d |
61 | * e : an instance of an event type |
6cd62ccf |
62 | *Return value |
963b5f2d |
63 | * unsigned : event type id |
6cd62ccf |
64 | ****************************************************************************/ |
65 | |
eed2ef37 |
66 | unsigned ltt_event_eventtype_id(const LttEvent *e) |
6cd62ccf |
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 |
963b5f2d |
77 | * LttFacility * : the facility of the event |
6cd62ccf |
78 | ****************************************************************************/ |
79 | |
eed2ef37 |
80 | LttFacility *ltt_event_facility(const LttEvent *e) |
6cd62ccf |
81 | { |
963b5f2d |
82 | LttTrace * trace = e->tracefile->trace; |
27304273 |
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; |
6cd62ccf |
89 | } |
90 | |
eed2ef37 |
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 | |
6cd62ccf |
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 |
963b5f2d |
111 | * LttEventType * : the event type of the event |
6cd62ccf |
112 | ****************************************************************************/ |
113 | |
eed2ef37 |
114 | LttEventType *ltt_event_eventtype(const LttEvent *e) |
6cd62ccf |
115 | { |
963b5f2d |
116 | LttFacility* facility = ltt_event_facility(e); |
117 | if(!facility) return NULL; |
3aee1200 |
118 | return &g_array_index(facility->events, LttEventType, e->event_id); |
6cd62ccf |
119 | } |
120 | |
6cd62ccf |
121 | |
122 | /***************************************************************************** |
123 | *Function name |
963b5f2d |
124 | * ltt_event_time : get the time of the event |
6cd62ccf |
125 | *Input params |
126 | * e : an instance of an event type |
127 | *Return value |
963b5f2d |
128 | * LttTime : the time of the event |
6cd62ccf |
129 | ****************************************************************************/ |
130 | |
eed2ef37 |
131 | LttTime ltt_event_time(const LttEvent *e) |
6cd62ccf |
132 | { |
963b5f2d |
133 | return e->event_time; |
6cd62ccf |
134 | } |
135 | |
136 | /***************************************************************************** |
137 | *Function name |
963b5f2d |
138 | * ltt_event_time : get the cycle count of the event |
6cd62ccf |
139 | *Input params |
140 | * e : an instance of an event type |
141 | *Return value |
963b5f2d |
142 | * LttCycleCount : the cycle count of the event |
6cd62ccf |
143 | ****************************************************************************/ |
144 | |
eed2ef37 |
145 | LttCycleCount ltt_event_cycle_count(const LttEvent *e) |
6cd62ccf |
146 | { |
3aee1200 |
147 | return e->tsc; |
6cd62ccf |
148 | } |
149 | |
eed2ef37 |
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 | |
80da81ad |
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 | { |
3aee1200 |
183 | ep->tracefile = e->tracefile; |
184 | ep->block = e->block; |
185 | ep->offset = e->offset; |
186 | ep->tsc = e->tsc; |
80da81ad |
187 | } |
188 | |
a5dcde2f |
189 | LttEventPosition * ltt_event_position_new() |
190 | { |
191 | return g_new(LttEventPosition, 1); |
192 | } |
193 | |
80da81ad |
194 | |
96da5c0d |
195 | /***************************************************************************** |
196 | * Function name |
197 | * ltt_event_position_compare : compare two positions |
a00149f6 |
198 | * A NULL value is infinite. |
96da5c0d |
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 | { |
a00149f6 |
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; |
96da5c0d |
218 | |
3aee1200 |
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) |
96da5c0d |
223 | return -1; |
3aee1200 |
224 | if(ep1->block > ep2->block) |
96da5c0d |
225 | return 1; |
3aee1200 |
226 | if(ep1->offset < ep2->offset) |
96da5c0d |
227 | return -1; |
3aee1200 |
228 | if(ep1->offset > ep2->offset) |
96da5c0d |
229 | return 1; |
230 | return 0; |
231 | } |
232 | |
2a74fbf4 |
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 | { |
a00149f6 |
245 | if(src == NULL) |
246 | dest = NULL; |
247 | else |
248 | *dest = *src; |
2a74fbf4 |
249 | } |
96da5c0d |
250 | |
251 | |
27304273 |
252 | |
253 | LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep) |
254 | { |
255 | return ep->tracefile; |
256 | } |
257 | |
6cd62ccf |
258 | /***************************************************************************** |
259 | *Function name |
963b5f2d |
260 | * ltt_event_cpu_i: get the cpu id where the event happens |
6cd62ccf |
261 | *Input params |
262 | * e : an instance of an event type |
263 | *Return value |
963b5f2d |
264 | * unsigned : the cpu id |
6cd62ccf |
265 | ****************************************************************************/ |
266 | |
963b5f2d |
267 | unsigned ltt_event_cpu_id(LttEvent *e) |
3aee1200 |
268 | { |
269 | return e->tracefile->cpu_num; |
6cd62ccf |
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 | |
963b5f2d |
281 | void *ltt_event_data(LttEvent *e) |
6cd62ccf |
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 |
908f42fa |
293 | * e : an instance of an event type |
6cd62ccf |
294 | * f : a field of the instance |
295 | *Return value |
296 | * unsigned : the number of elements for an array/sequence field |
297 | ****************************************************************************/ |
3aee1200 |
298 | guint64 ltt_event_field_element_number(LttEvent *e, LttField *f) |
6cd62ccf |
299 | { |
2312de30 |
300 | if(f->field_type.type_class != LTT_ARRAY && |
301 | f->field_type.type_class != LTT_SEQUENCE) |
6cd62ccf |
302 | return 0; |
908f42fa |
303 | |
2312de30 |
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)); |
6cd62ccf |
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 |
f104d082 |
315 | * O(1) because of offset array. |
6cd62ccf |
316 | *Input params |
908f42fa |
317 | * e : an instance of an event type |
6cd62ccf |
318 | * f : a field of the instance |
3aee1200 |
319 | * i : the ith element (0, ...) |
f104d082 |
320 | *returns : the child field, at the right index, updated. |
6cd62ccf |
321 | ****************************************************************************/ |
f104d082 |
322 | LttField *ltt_event_field_element_select(LttEvent *e, LttField *f, gulong i) |
6cd62ccf |
323 | { |
f104d082 |
324 | gulong element_number; |
3aee1200 |
325 | LttField *field; |
8d1e6362 |
326 | unsigned int k; |
3aee1200 |
327 | size_t size; |
328 | LttEventType *event_type; |
f104d082 |
329 | off_t new_offset; |
908f42fa |
330 | |
2312de30 |
331 | if(f->field_type.type_class != LTT_ARRAY && |
332 | f->field_type.type_class != LTT_SEQUENCE) |
743e50fd |
333 | return NULL; |
908f42fa |
334 | |
335 | element_number = ltt_event_field_element_number(e,f); |
3aee1200 |
336 | event_type = ltt_event_eventtype(e); |
337 | /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number |
8d1e6362 |
338 | */ |
743e50fd |
339 | if(i >= element_number) return NULL; |
f104d082 |
340 | |
2312de30 |
341 | if(f->field_type.type_class == LTT_ARRAY) { |
342 | field = &g_array_index(f->field_type.fields, LttField, 0); |
f104d082 |
343 | } else { |
2312de30 |
344 | field = &g_array_index(f->field_type.fields, LttField, 1); |
f104d082 |
345 | } |
3aee1200 |
346 | |
f104d082 |
347 | if(field->field_size != 0) { |
348 | if(f->array_offset + (i * field->field_size) == field->offset_root) |
743e50fd |
349 | return field; /* fixed length child, already at the right offset */ |
f104d082 |
350 | else |
351 | new_offset = f->array_offset + (i * field->field_size); |
3aee1200 |
352 | } else { |
f104d082 |
353 | /* Var. len. child */ |
354 | new_offset = g_array_index(f->dynamic_offsets, off_t, i); |
908f42fa |
355 | } |
743e50fd |
356 | compute_fields_offsets(e->tracefile, |
357 | ltt_event_facility(e), field, &new_offset, e->data); |
f104d082 |
358 | |
359 | return field; |
6cd62ccf |
360 | } |
361 | |
f2923fb2 |
362 | |
363 | off_t ltt_event_field_offset(LttEvent *e, LttField *f) |
364 | { |
365 | return f->offset_root; |
366 | } |
367 | |
368 | |
369 | |
6cd62ccf |
370 | /***************************************************************************** |
371 | * These functions extract data from an event after architecture specific |
372 | * conversions |
373 | ****************************************************************************/ |
63c35f6c |
374 | guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f) |
6cd62ccf |
375 | { |
3aee1200 |
376 | gboolean reverse_byte_order = LTT_GET_BO(e->tracefile); |
64714253 |
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: |
0f7f40c1 |
386 | return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root); |
64714253 |
387 | break; |
388 | case 4: |
0f7f40c1 |
389 | return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root); |
64714253 |
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; |
63c35f6c |
396 | } |
6cd62ccf |
397 | } |
398 | |
63c35f6c |
399 | gint32 ltt_event_get_int(LttEvent *e, LttField *f) |
6cd62ccf |
400 | { |
3aee1200 |
401 | gboolean reverse_byte_order = LTT_GET_BO(e->tracefile); |
64714253 |
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: |
0f7f40c1 |
411 | return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root); |
64714253 |
412 | break; |
413 | case 4: |
0f7f40c1 |
414 | return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root); |
64714253 |
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; |
63c35f6c |
421 | } |
6cd62ccf |
422 | } |
423 | |
63c35f6c |
424 | guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f) |
6cd62ccf |
425 | { |
3aee1200 |
426 | gboolean reverse_byte_order = LTT_GET_BO(e->tracefile); |
64714253 |
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: |
0f7f40c1 |
436 | return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root); |
64714253 |
437 | break; |
438 | case 4: |
0f7f40c1 |
439 | return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root); |
64714253 |
440 | break; |
441 | case 8: |
0f7f40c1 |
442 | return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root); |
64714253 |
443 | break; |
444 | default: |
445 | g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size); |
446 | return 0; |
447 | break; |
6cd62ccf |
448 | } |
449 | } |
450 | |
63c35f6c |
451 | gint64 ltt_event_get_long_int(LttEvent *e, LttField *f) |
6cd62ccf |
452 | { |
3aee1200 |
453 | gboolean reverse_byte_order = LTT_GET_BO(e->tracefile); |
64714253 |
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: |
0f7f40c1 |
463 | return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root); |
64714253 |
464 | break; |
465 | case 4: |
0f7f40c1 |
466 | return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root); |
64714253 |
467 | break; |
468 | case 8: |
0f7f40c1 |
469 | return ltt_get_int64(reverse_byte_order, e->data + f->offset_root); |
64714253 |
470 | break; |
471 | default: |
472 | g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size); |
473 | return 0; |
474 | break; |
6cd62ccf |
475 | } |
476 | } |
477 | |
963b5f2d |
478 | float ltt_event_get_float(LttEvent *e, LttField *f) |
6cd62ccf |
479 | { |
3b10b765 |
480 | g_assert(LTT_HAS_FLOAT(e->tracefile)); |
481 | gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile); |
6cd62ccf |
482 | |
2312de30 |
483 | g_assert(f->field_type.type_class == LTT_FLOAT && f->field_size == 4); |
6cd62ccf |
484 | |
0f7f40c1 |
485 | if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root); |
6cd62ccf |
486 | else{ |
d4214418 |
487 | void *ptr = e->data + f->offset_root; |
fadf7e8b |
488 | guint32 value = bswap_32(*(guint32*)ptr); |
489 | return *(float*)&value; |
6cd62ccf |
490 | } |
491 | } |
492 | |
963b5f2d |
493 | double ltt_event_get_double(LttEvent *e, LttField *f) |
6cd62ccf |
494 | { |
3b10b765 |
495 | g_assert(LTT_HAS_FLOAT(e->tracefile)); |
496 | gboolean reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile); |
6cd62ccf |
497 | |
2312de30 |
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); |
6cd62ccf |
502 | |
0f7f40c1 |
503 | if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root); |
3b10b765 |
504 | else { |
d4214418 |
505 | void *ptr = e->data + f->offset_root; |
fadf7e8b |
506 | guint64 value = bswap_64(*(guint64*)ptr); |
507 | return *(double*)&value; |
6cd62ccf |
508 | } |
509 | } |
510 | |
511 | /***************************************************************************** |
512 | * The string obtained is only valid until the next read from |
908f42fa |
513 | * the same tracefile. |
6cd62ccf |
514 | ****************************************************************************/ |
963b5f2d |
515 | char *ltt_event_get_string(LttEvent *e, LttField *f) |
6cd62ccf |
516 | { |
2312de30 |
517 | g_assert(f->field_type.type_class == LTT_STRING); |
2a74fbf4 |
518 | |
45e14832 |
519 | return (gchar*)g_strdup((gchar*)(e->data + f->offset_root)); |
6cd62ccf |
520 | } |
eed2ef37 |
521 | |
f104d082 |
522 | /***************************************************************************** |
523 | *Function name |
524 | * compute_fields_offsets : set the precomputable offset of the fields |
525 | *Input params |
743e50fd |
526 | * fac : facility |
f104d082 |
527 | * field : the field |
528 | * offset : pointer to the current offset, must be incremented |
529 | ****************************************************************************/ |
530 | |
531 | |
743e50fd |
532 | void compute_fields_offsets(LttTracefile *tf, |
533 | LttFacility *fac, LttField *field, off_t *offset, void *root) |
f104d082 |
534 | { |
2312de30 |
535 | LttType *type = &field->field_type; |
f104d082 |
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 */ |
743e50fd |
556 | *offset += ltt_align(*offset, get_alignment(field), |
557 | fac->alignment); |
f104d082 |
558 | /* remember offset */ |
559 | field->offset_root = *offset; |
560 | /* Increment offset */ |
561 | *offset += field->field_size; |
743e50fd |
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); |
f104d082 |
569 | } |
f104d082 |
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; |
743e50fd |
576 | /* Realign the data */ |
577 | *offset += ltt_align(*offset, fac->pointer_size, |
578 | fac->alignment); |
f104d082 |
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) { |
743e50fd |
586 | *offset += ltt_align(*offset, get_alignment(field), |
587 | fac->alignment); |
f104d082 |
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); |
743e50fd |
604 | compute_fields_offsets(tf, fac, child, offset, root); |
f104d082 |
605 | } |
606 | } |
607 | // local_offset = field->array_offset; |
608 | // /* Set the offset at position 0 */ |
743e50fd |
609 | // compute_fields_offsets(tf, fac, child, &local_offset, root); |
2312de30 |
610 | } |
611 | break; |
f104d082 |
612 | case LTT_SEQUENCE: |
613 | g_assert(type->fields->len == 2); |
614 | { |
615 | off_t local_offset; |
616 | LttField *child; |
617 | guint i; |
743e50fd |
618 | guint num_elem; |
f104d082 |
619 | if(field->fixed_root == FIELD_VARIABLE) { |
743e50fd |
620 | *offset += ltt_align(*offset, get_alignment(field), |
621 | fac->alignment); |
f104d082 |
622 | /* remember offset */ |
623 | field->offset_root = *offset; |
624 | |
625 | child = &g_array_index(type->fields, LttField, 0); |
743e50fd |
626 | compute_fields_offsets(tf, fac, child, offset, root); |
f104d082 |
627 | child = &g_array_index(type->fields, LttField, 1); |
743e50fd |
628 | *offset += ltt_align(*offset, get_alignment(child), |
629 | fac->alignment); |
f104d082 |
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); |
743e50fd |
638 | num_elem = ltt_event_field_element_number(&tf->event, field); |
639 | for(i=0; i<num_elem; i++) { |
f104d082 |
640 | g_array_append_val(field->dynamic_offsets, *offset); |
743e50fd |
641 | compute_fields_offsets(tf, fac, child, offset, root); |
f104d082 |
642 | } |
743e50fd |
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 | |
f104d082 |
649 | // local_offset = field->array_offset; |
650 | // /* Set the offset at position 0 */ |
743e50fd |
651 | // compute_fields_offsets(tf, fac, child, &local_offset, root); |
f104d082 |
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) { |
743e50fd |
660 | *offset += ltt_align(*offset, get_alignment(fac, field), |
661 | fac->alignment); |
f104d082 |
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); |
743e50fd |
669 | compute_fields_offsets(tf, fac, child, offset, root); |
f104d082 |
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) { |
743e50fd |
679 | *offset += ltt_align(*offset, get_alignment(field), |
680 | fac->alignment); |
f104d082 |
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); |
743e50fd |
687 | compute_fields_offsets(tf, fac, child, offset, root); |
f104d082 |
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 | } |
eed2ef37 |
698 | |
699 | |
f104d082 |
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 | ****************************************************************************/ |
743e50fd |
708 | void compute_offsets(LttTracefile *tf, LttFacility *fac, |
709 | LttEventType *event, off_t *offset, void *root) |
f104d082 |
710 | { |
711 | guint i; |
f104d082 |
712 | |
713 | /* compute all variable offsets */ |
714 | for(i=0; i<event->fields->len; i++) { |
743e50fd |
715 | //g_debug("computing offset %u of %u\n", i, event->fields->len-1); |
f104d082 |
716 | LttField *field = &g_array_index(event->fields, LttField, i); |
743e50fd |
717 | compute_fields_offsets(tf, fac, field, offset, root); |
f104d082 |
718 | } |
719 | |
720 | } |
721 | |