f2a74ed3 |
1 | /* This file is part of the Linux Trace Toolkit viewer |
2 | * Copyright (C) 2007 Mathieu Desnoyers |
3 | * |
4 | * Complete rewrite from the original version made by XangXiu Yang. |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License Version 2.1 as published by the Free Software Foundation. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Lesser General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Lesser General Public |
16 | * License along with this library; if not, write to the |
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. |
19 | */ |
20 | |
21 | #ifdef HAVE_CONFIG_H |
22 | #include <config.h> |
23 | #endif |
24 | |
25 | #include <glib.h> |
449cb9d7 |
26 | |
6cd62ccf |
27 | #include <ltt/event.h> |
d27446d1 |
28 | #include <ltt/ltt-types.h> |
a7074914 |
29 | #include <ltt/ltt-private.h> |
f4e57537 |
30 | #include <ltt/marker.h> |
31 | #include <ltt/marker-field.h> |
6cd62ccf |
32 | |
eed2ef37 |
33 | /***************************************************************************** |
34 | *Function name |
35 | * ltt_event_position_get : get the event position data |
36 | *Input params |
37 | * e : an instance of an event type |
38 | * ep : a pointer to event's position structure |
39 | * tf : tracefile pointer |
40 | * block : current block |
41 | * offset : current offset |
42 | * tsc : current tsc |
43 | ****************************************************************************/ |
44 | void ltt_event_position_get(LttEventPosition *ep, LttTracefile **tf, |
45 | guint *block, guint *offset, guint64 *tsc) |
46 | { |
47 | *tf = ep->tracefile; |
48 | *block = ep->block; |
49 | *offset = ep->offset; |
50 | *tsc = ep->tsc; |
51 | } |
52 | |
53 | |
6d0cdf22 |
54 | void ltt_event_position_set(LttEventPosition *ep, LttTracefile *tf, |
55 | guint block, guint offset, guint64 tsc) |
56 | { |
57 | ep->tracefile = tf; |
58 | ep->block = block; |
59 | ep->offset = offset; |
60 | ep->tsc = tsc; |
61 | } |
62 | |
63 | |
80da81ad |
64 | /***************************************************************************** |
65 | *Function name |
66 | * ltt_event_position : get the event's position |
67 | *Input params |
68 | * e : an instance of an event type |
69 | * ep : a pointer to event's position structure |
70 | ****************************************************************************/ |
71 | |
72 | void ltt_event_position(LttEvent *e, LttEventPosition *ep) |
73 | { |
3aee1200 |
74 | ep->tracefile = e->tracefile; |
75 | ep->block = e->block; |
76 | ep->offset = e->offset; |
77 | ep->tsc = e->tsc; |
80da81ad |
78 | } |
79 | |
a5dcde2f |
80 | LttEventPosition * ltt_event_position_new() |
81 | { |
82 | return g_new(LttEventPosition, 1); |
83 | } |
84 | |
80da81ad |
85 | |
96da5c0d |
86 | /***************************************************************************** |
87 | * Function name |
88 | * ltt_event_position_compare : compare two positions |
a00149f6 |
89 | * A NULL value is infinite. |
96da5c0d |
90 | * Input params |
91 | * ep1 : a pointer to event's position structure |
92 | * ep2 : a pointer to event's position structure |
93 | * Return |
94 | * -1 is ep1 < ep2 |
95 | * 1 if ep1 > ep2 |
96 | * 0 if ep1 == ep2 |
97 | ****************************************************************************/ |
98 | |
99 | |
100 | gint ltt_event_position_compare(const LttEventPosition *ep1, |
101 | const LttEventPosition *ep2) |
102 | { |
a00149f6 |
103 | if(ep1 == NULL && ep2 == NULL) |
104 | return 0; |
105 | if(ep1 != NULL && ep2 == NULL) |
106 | return -1; |
107 | if(ep1 == NULL && ep2 != NULL) |
108 | return 1; |
96da5c0d |
109 | |
3aee1200 |
110 | if(ep1->tracefile != ep2->tracefile) |
111 | g_error("ltt_event_position_compare on different tracefiles makes no sense"); |
112 | |
113 | if(ep1->block < ep2->block) |
96da5c0d |
114 | return -1; |
3aee1200 |
115 | if(ep1->block > ep2->block) |
96da5c0d |
116 | return 1; |
3aee1200 |
117 | if(ep1->offset < ep2->offset) |
96da5c0d |
118 | return -1; |
3aee1200 |
119 | if(ep1->offset > ep2->offset) |
96da5c0d |
120 | return 1; |
121 | return 0; |
122 | } |
123 | |
2a74fbf4 |
124 | /***************************************************************************** |
125 | * Function name |
126 | * ltt_event_position_copy : copy position |
127 | * Input params |
128 | * src : a pointer to event's position structure source |
129 | * dest : a pointer to event's position structure dest |
130 | * Return |
131 | * void |
132 | ****************************************************************************/ |
133 | void ltt_event_position_copy(LttEventPosition *dest, |
134 | const LttEventPosition *src) |
135 | { |
a00149f6 |
136 | if(src == NULL) |
137 | dest = NULL; |
138 | else |
139 | *dest = *src; |
2a74fbf4 |
140 | } |
96da5c0d |
141 | |
142 | |
27304273 |
143 | |
144 | LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep) |
145 | { |
146 | return ep->tracefile; |
147 | } |
148 | |
c37440c8 |
149 | /***************************************************************************** |
150 | * These functions extract data from an event after architecture specific |
151 | * conversions |
152 | ****************************************************************************/ |
153 | guint32 ltt_event_get_unsigned(LttEvent *e, struct marker_field *f) |
154 | { |
155 | gboolean reverse_byte_order; |
f2a74ed3 |
156 | |
c37440c8 |
157 | if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) { |
158 | reverse_byte_order = (g_ntohs(0x1) != 0x1); |
159 | } else { |
160 | reverse_byte_order = LTT_GET_BO(e->tracefile); |
161 | } |
162 | |
163 | switch(f->size) { |
164 | case 1: |
165 | { |
166 | guint8 x = *(guint8 *)(e->data + f->offset); |
167 | return (guint32) x; |
168 | } |
169 | break; |
170 | case 2: |
171 | return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset); |
172 | break; |
173 | case 4: |
174 | return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset); |
175 | break; |
176 | case 8: |
177 | default: |
178 | g_critical("ltt_event_get_unsigned : field size %i unknown", f->size); |
179 | return 0; |
180 | break; |
181 | } |
182 | } |
183 | |
184 | gint32 ltt_event_get_int(LttEvent *e, struct marker_field *f) |
185 | { |
186 | gboolean reverse_byte_order; |
187 | if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) { |
188 | reverse_byte_order = (g_ntohs(0x1) != 0x1); |
189 | } else { |
190 | reverse_byte_order = LTT_GET_BO(e->tracefile); |
191 | } |
192 | |
193 | switch(f->size) { |
194 | case 1: |
195 | { |
196 | gint8 x = *(gint8 *)(e->data + f->offset); |
197 | return (gint32) x; |
198 | } |
199 | break; |
200 | case 2: |
201 | return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset); |
202 | break; |
203 | case 4: |
204 | return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset); |
205 | break; |
206 | case 8: |
207 | default: |
208 | g_critical("ltt_event_get_int : field size %i unknown", f->size); |
209 | return 0; |
210 | break; |
211 | } |
212 | } |
213 | |
214 | guint64 ltt_event_get_long_unsigned(LttEvent *e, struct marker_field *f) |
215 | { |
216 | gboolean reverse_byte_order; |
217 | if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) { |
218 | reverse_byte_order = (g_ntohs(0x1) != 0x1); |
219 | } else { |
220 | reverse_byte_order = LTT_GET_BO(e->tracefile); |
221 | } |
222 | |
223 | switch(f->size) { |
224 | case 1: |
225 | { |
226 | guint8 x = *(guint8 *)(e->data + f->offset); |
227 | return (guint64) x; |
228 | } |
229 | break; |
230 | case 2: |
231 | return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset); |
232 | break; |
233 | case 4: |
234 | return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset); |
235 | break; |
236 | case 8: |
237 | return ltt_get_uint64(reverse_byte_order, e->data + f->offset); |
238 | break; |
239 | default: |
240 | g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->size); |
241 | return 0; |
242 | break; |
243 | } |
244 | } |
245 | |
246 | gint64 ltt_event_get_long_int(LttEvent *e, struct marker_field *f) |
247 | { |
248 | gboolean reverse_byte_order; |
249 | if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) { |
250 | reverse_byte_order = (g_ntohs(0x1) != 0x1); |
251 | } else { |
252 | reverse_byte_order = LTT_GET_BO(e->tracefile); |
253 | } |
254 | |
255 | switch(f->size) { |
256 | case 1: |
257 | { |
258 | gint8 x = *(gint8 *)(e->data + f->offset); |
259 | return (gint64) x; |
260 | } |
261 | break; |
262 | case 2: |
263 | return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset); |
264 | break; |
265 | case 4: |
266 | return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset); |
267 | break; |
268 | case 8: |
269 | return ltt_get_int64(reverse_byte_order, e->data + f->offset); |
270 | break; |
271 | default: |
272 | g_critical("ltt_event_get_long_int : field size %i unknown", f->size); |
273 | return 0; |
274 | break; |
275 | } |
276 | } |
277 | |
278 | #if 0 |
279 | float ltt_event_get_float(LttEvent *e, struct marker_field *f) |
280 | { |
281 | gboolean reverse_byte_order; |
282 | if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) { |
283 | reverse_byte_order = (g_ntohs(0x1) != 0x1); |
284 | } else { |
285 | g_assert(LTT_HAS_FLOAT(e->tracefile)); |
286 | reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile); |
287 | } |
288 | |
289 | g_assert(f->field_type.type_class == LTT_FLOAT && f->size == 4); |
290 | |
291 | if(reverse_byte_order == 0) return *(float *)(e->data + f->offset); |
292 | else{ |
293 | void *ptr = e->data + f->offset; |
294 | guint32 value = bswap_32(*(guint32*)ptr); |
295 | return *(float*)&value; |
296 | } |
297 | } |
298 | |
299 | double ltt_event_get_double(LttEvent *e, struct marker_field *f) |
300 | { |
301 | gboolean reverse_byte_order; |
302 | if(unlikely(f->attributes & LTT_ATTRIBUTE_NETWORK_BYTE_ORDER)) { |
303 | reverse_byte_order = (g_ntohs(0x1) != 0x1); |
304 | } else { |
305 | g_assert(LTT_HAS_FLOAT(e->tracefile)); |
306 | reverse_byte_order = LTT_GET_FLOAT_BO(e->tracefile); |
307 | } |
308 | |
309 | if(f->size == 4) |
310 | return ltt_event_get_float(e, f); |
311 | |
312 | g_assert(f->field_type.type_class == LTT_FLOAT && f->size == 8); |
313 | |
314 | if(reverse_byte_order == 0) return *(double *)(e->data + f->offset); |
315 | else { |
316 | void *ptr = e->data + f->offset; |
317 | guint64 value = bswap_64(*(guint64*)ptr); |
318 | return *(double*)&value; |
319 | } |
320 | } |
321 | #endif |
322 | |
323 | /***************************************************************************** |
324 | * The string obtained is only valid until the next read from |
325 | * the same tracefile. |
326 | ****************************************************************************/ |
327 | char *ltt_event_get_string(LttEvent *e, struct marker_field *f) |
328 | { |
329 | g_assert(f->type == LTT_TYPE_STRING); |
330 | |
331 | return (gchar*)g_strdup((gchar*)(e->data + f->offset)); |
332 | } |
333 | |
334 | |