API : export the offsetted timestamp
[babeltrace.git] / formats / ctf / events.c
CommitLineData
9843982d 1/*
5c5facc7 2 * ctf/events.c
9843982d
JD
3 *
4 * Babeltrace Library
5 *
6 * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
7 *
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Julien Desfossez <julien.desfossez@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 */
21
22#include <babeltrace/babeltrace.h>
23#include <babeltrace/format.h>
24#include <babeltrace/ctf/events.h>
25#include <babeltrace/ctf-ir/metadata.h>
e4195791
MD
26#include <babeltrace/prio_heap.h>
27#include <babeltrace/iterator-internal.h>
28#include <babeltrace/ctf/events-internal.h>
29#include <babeltrace/ctf/metadata.h>
9843982d
JD
30#include <glib.h>
31
32/*
33 * thread local storage to store the last error that occured
34 * while reading a field, this variable must be accessed by
35 * bt_ctf_field_error only
36 */
37__thread int bt_ctf_last_field_error = 0;
38
e4195791
MD
39struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
40 struct bt_iter_pos *begin_pos,
41 struct bt_iter_pos *end_pos)
42{
43 struct bt_ctf_iter *iter;
44 int ret;
45
46 iter = g_new0(struct bt_ctf_iter, 1);
47 ret = bt_iter_init(&iter->parent, ctx, begin_pos, end_pos);
48 if (ret) {
49 g_free(iter);
50 return NULL;
51 }
634d474b
MD
52 iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks));
53 iter->recalculate_dep_graph = 0;
54 iter->main_callbacks.callback = NULL;
55 iter->dep_gc = g_ptr_array_new();
e4195791
MD
56 return iter;
57}
58
59void bt_ctf_iter_destroy(struct bt_ctf_iter *iter)
60{
634d474b
MD
61 struct bt_stream_callbacks *bt_stream_cb;
62 struct bt_callback_chain *bt_chain;
63 int i, j;
64
65 /* free all events callbacks */
66 if (iter->main_callbacks.callback)
67 g_array_free(iter->main_callbacks.callback, TRUE);
68
69 /* free per-event callbacks */
70 for (i = 0; i < iter->callbacks->len; i++) {
71 bt_stream_cb = &g_array_index(iter->callbacks,
72 struct bt_stream_callbacks, i);
73 if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks)
74 continue;
75 for (j = 0; j < bt_stream_cb->per_id_callbacks->len; j++) {
76 bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
77 struct bt_callback_chain, j);
78 if (bt_chain->callback) {
79 g_array_free(bt_chain->callback, TRUE);
80 }
81 }
82 g_array_free(bt_stream_cb->per_id_callbacks, TRUE);
83 }
84
e4195791
MD
85 bt_iter_fini(&iter->parent);
86 g_free(iter);
87}
88
89struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter)
90{
91 return &iter->parent;
92}
93
94struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter)
95{
96 struct ctf_file_stream *file_stream;
97 struct bt_ctf_event *ret = &iter->current_ctf_event;
98
99 file_stream = heap_maximum(iter->parent.stream_heap);
100 if (!file_stream) {
101 /* end of file for all streams */
102 goto stop;
103 }
104 ret->stream = &file_stream->parent;
105 ret->event = g_ptr_array_index(ret->stream->events_by_id,
106 ret->stream->event_id);
107
634d474b 108 if (ret->stream->stream_id > iter->callbacks->len)
e4195791
MD
109 goto end;
110
634d474b 111 process_callbacks(iter, ret->stream);
e4195791
MD
112
113end:
114 return ret;
115stop:
116 return NULL;
117}
118
9843982d
JD
119struct definition *bt_ctf_get_top_level_scope(struct bt_ctf_event *event,
120 enum bt_ctf_scope scope)
121{
122 struct definition *tmp = NULL;
123
124 switch (scope) {
125 case BT_TRACE_PACKET_HEADER:
126 if (!event->stream)
127 goto error;
128 if (event->stream->trace_packet_header)
129 tmp = &event->stream->trace_packet_header->p;
130 break;
131 case BT_STREAM_PACKET_CONTEXT:
132 if (!event->stream)
133 goto error;
134 if (event->stream->stream_packet_context)
135 tmp = &event->stream->stream_packet_context->p;
136 break;
137 case BT_STREAM_EVENT_HEADER:
138 if (!event->stream)
139 goto error;
140 if (event->stream->stream_event_header)
141 tmp = &event->stream->stream_event_header->p;
142 break;
143 case BT_STREAM_EVENT_CONTEXT:
144 if (!event->stream)
145 goto error;
146 if (event->stream->stream_event_context)
147 tmp = &event->stream->stream_event_context->p;
148 break;
149 case BT_EVENT_CONTEXT:
150 if (!event->event)
151 goto error;
152 if (event->event->event_context)
153 tmp = &event->event->event_context->p;
154 break;
155 case BT_EVENT_FIELDS:
156 if (!event->event)
157 goto error;
158 if (event->event->event_fields)
159 tmp = &event->event->event_fields->p;
160 break;
161 }
162 return tmp;
163
164error:
165 return NULL;
166}
167
168struct definition *bt_ctf_get_field(struct bt_ctf_event *event,
169 struct definition *scope,
170 const char *field)
171{
172 struct definition *def;
173
174 if (scope) {
175 def = lookup_definition(scope, field);
176 if (bt_ctf_field_type(def) == CTF_TYPE_VARIANT) {
177 struct definition_variant *variant_definition;
178 variant_definition = container_of(def,
179 struct definition_variant, p);
180 return variant_definition->current_field;
181 }
182 return def;
183 }
184 return NULL;
185}
186
187struct definition *bt_ctf_get_index(struct bt_ctf_event *event,
188 struct definition *field,
189 unsigned int index)
190{
191 struct definition *ret = NULL;
192
193 if (bt_ctf_field_type(field) == CTF_TYPE_ARRAY) {
194 struct definition_array *array_definition;
195 array_definition = container_of(field,
196 struct definition_array, p);
197 ret = array_index(array_definition, index);
198 } else if (bt_ctf_field_type(field) == CTF_TYPE_SEQUENCE) {
199 struct definition_sequence *sequence_definition;
200 sequence_definition = container_of(field,
201 struct definition_sequence, p);
202 ret = sequence_index(sequence_definition, index);
203 }
204 return ret;
205}
206
207const char *bt_ctf_event_name(struct bt_ctf_event *event)
208{
209 struct ctf_event *event_class;
210 struct ctf_stream_class *stream_class;
211
212 if (!event)
213 return NULL;
214 stream_class = event->stream->stream_class;
215 event_class = g_ptr_array_index(stream_class->events_by_id,
216 event->stream->event_id);
217 return g_quark_to_string(event_class->name);
218}
219
220const char *bt_ctf_field_name(const struct definition *def)
221{
222 if (def)
223 return g_quark_to_string(def->name);
224 return NULL;
225}
226
da320b83 227enum ctf_type_id bt_ctf_field_type(const struct definition *def)
9843982d
JD
228{
229 if (def)
230 return def->declaration->id;
231 return CTF_TYPE_UNKNOWN;
232}
233
234int bt_ctf_get_field_list(struct bt_ctf_event *event,
235 struct definition *scope,
236 struct definition const * const **list,
237 unsigned int *count)
238{
239 switch (bt_ctf_field_type(scope)) {
240 case CTF_TYPE_INTEGER:
241 case CTF_TYPE_FLOAT:
242 case CTF_TYPE_STRING:
243 case CTF_TYPE_ENUM:
244 goto error;
245 case CTF_TYPE_STRUCT:
246 {
247 struct definition_struct *def_struct;
248
249 def_struct = container_of(scope, struct definition_struct, p);
250 if (!def_struct)
251 goto error;
252 if (def_struct->fields->pdata) {
253 *list = (struct definition const* const*) def_struct->fields->pdata;
254 *count = def_struct->fields->len;
255 goto end;
256 } else {
257 goto error;
258 }
259 }
260 case CTF_TYPE_UNTAGGED_VARIANT:
261 goto error;
262 case CTF_TYPE_VARIANT:
263 {
264 struct definition_variant *def_variant;
265
266 def_variant = container_of(scope, struct definition_variant, p);
267 if (!def_variant)
268 goto error;
269 if (def_variant->fields->pdata) {
270 *list = (struct definition const* const*) def_variant->fields->pdata;
271 *count = def_variant->fields->len;
272 goto end;
273 } else {
274 goto error;
275 }
276 }
277 case CTF_TYPE_ARRAY:
278 {
279 struct definition_array *def_array;
280
281 def_array = container_of(scope, struct definition_array, p);
282 if (!def_array)
283 goto error;
284 if (def_array->elems->pdata) {
285 *list = (struct definition const* const*) def_array->elems->pdata;
286 *count = def_array->elems->len;
287 goto end;
288 } else {
289 goto error;
290 }
291 }
292 case CTF_TYPE_SEQUENCE:
293 {
294 struct definition_sequence *def_sequence;
295
296 def_sequence = container_of(scope, struct definition_sequence, p);
297 if (!def_sequence)
298 goto error;
299 if (def_sequence->elems->pdata) {
300 *list = (struct definition const* const*) def_sequence->elems->pdata;
301 *count = def_sequence->elems->len;
302 goto end;
303 } else {
304 goto error;
305 }
306 }
307 default:
308 break;
309 }
310
311end:
312 return 0;
313
314error:
315 *list = NULL;
316 *count = 0;
317 return -1;
318}
319
57f3005e 320uint64_t bt_ctf_get_timestamp_raw(struct bt_ctf_event *event)
9843982d
JD
321{
322 if (event && event->stream->has_timestamp)
323 return event->stream->timestamp;
324 else
57f3005e
SJD
325 return -1ULL;
326}
327
328uint64_t bt_ctf_get_timestamp(struct bt_ctf_event *event)
329{
330 uint64_t ts_nsec;
331 struct ctf_trace *trace;
332 struct trace_collection *tc;
333 uint64_t tc_offset;
334 uint64_t timestamp;
335
336 if (!event->stream->has_timestamp) {
337 return -1ULL;
338 }
339
340 trace = event->stream->stream_class->trace;
341 tc = trace->collection;
342 tc_offset = tc->single_clock_offset_avg;
343 timestamp = event->stream->timestamp;
344 if (event->stream->current_clock->freq == 1000000000ULL) {
345 ts_nsec = timestamp;
346 } else {
347 ts_nsec = (uint64_t) ((double) timestamp * 1000000000.0
348 / (double) event->stream->current_clock->freq);
349 }
350 ts_nsec += tc_offset;
351
352 return ts_nsec;
9843982d
JD
353}
354
355static void bt_ctf_field_set_error(int error)
356{
357 bt_ctf_last_field_error = error;
358}
359
360int bt_ctf_field_get_error(void)
361{
362 int ret;
363 ret = bt_ctf_last_field_error;
364 bt_ctf_last_field_error = 0;
365
366 return ret;
367}
368
da320b83 369uint64_t bt_ctf_get_uint64(const struct definition *field)
9843982d
JD
370{
371 unsigned int ret = 0;
372
373 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
374 ret = get_unsigned_int(field);
375 else
376 bt_ctf_field_set_error(-EINVAL);
377
378 return ret;
379}
380
da320b83 381int64_t bt_ctf_get_int64(const struct definition *field)
9843982d
JD
382{
383 int ret = 0;
384
385 if (field && bt_ctf_field_type(field) == CTF_TYPE_INTEGER)
386 ret = get_signed_int(field);
387 else
388 bt_ctf_field_set_error(-EINVAL);
389
390 return ret;
391
392}
393
da320b83 394char *bt_ctf_get_char_array(const struct definition *field)
9843982d
JD
395{
396 char *ret = NULL;
397
398 if (field && bt_ctf_field_type(field) == CTF_TYPE_ARRAY)
399 ret = get_char_array(field)->str;
400 else
401 bt_ctf_field_set_error(-EINVAL);
402
403 return ret;
404}
405
da320b83 406char *bt_ctf_get_string(const struct definition *field)
9843982d
JD
407{
408 char *ret = NULL;
409
410 if (field && bt_ctf_field_type(field) == CTF_TYPE_STRING)
411 ret = get_string(field);
412 else
413 bt_ctf_field_set_error(-EINVAL);
414
415 return ret;
416}
This page took 0.057884 seconds and 4 git commands to generate.