4 * Babeltrace CTF Writer Output Plugin Event Handling
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <babeltrace/ctf-ir/event.h>
30 #include <babeltrace/ctf-ir/packet.h>
31 #include <babeltrace/ctf-ir/event-class.h>
32 #include <babeltrace/ctf-ir/stream.h>
33 #include <babeltrace/ctf-ir/stream-class.h>
34 #include <babeltrace/ctf-ir/clock-class.h>
35 #include <babeltrace/ctf-ir/fields.h>
36 #include <babeltrace/ctf-writer/stream-class.h>
37 #include <babeltrace/ctf-writer/stream.h>
39 #include <ctfcopytrace.h>
44 struct bt_ctf_stream_class
*insert_new_stream_class(
45 struct writer_component
*writer_component
,
46 struct bt_ctf_writer
*ctf_writer
,
47 struct bt_ctf_stream_class
*stream_class
)
49 struct bt_ctf_stream_class
*writer_stream_class
;
50 struct bt_ctf_trace
*trace
, *writer_trace
;
51 enum bt_component_status ret
;
53 writer_stream_class
= ctf_copy_stream_class(writer_component
->err
,
55 if (!writer_stream_class
) {
56 fprintf(writer_component
->err
, "[error] Failed to copy stream class\n");
57 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
58 __func__
, __FILE__
, __LINE__
);
62 trace
= bt_ctf_stream_class_get_trace(stream_class
);
64 fprintf(writer_component
->err
,
65 "[error] %s in %s:%d\n", __func__
, __FILE__
,
70 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
73 fprintf(writer_component
->err
,
74 "[error] %s in %s:%d\n", __func__
, __FILE__
,
76 ret
= BT_COMPONENT_STATUS_ERROR
;
80 ret
= ctf_copy_clock_classes(writer_component
->err
, writer_trace
,
81 writer_stream_class
, trace
);
83 if (ret
!= BT_COMPONENT_STATUS_OK
) {
85 fprintf(writer_component
->err
,
86 "[error] %s in %s:%d\n", __func__
, __FILE__
,
92 ret
= ctf_copy_event_classes(writer_component
->err
, stream_class
,
94 if (ret
!= BT_COMPONENT_STATUS_OK
) {
95 fprintf(writer_component
->err
, "[error] Failed to copy event classes\n");
96 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
101 g_hash_table_insert(writer_component
->stream_class_map
,
102 (gpointer
) stream_class
, writer_stream_class
);
107 BT_PUT(writer_stream_class
);
109 return writer_stream_class
;
113 struct bt_ctf_stream
*insert_new_stream(
114 struct writer_component
*writer_component
,
115 struct bt_ctf_writer
*ctf_writer
,
116 struct bt_ctf_stream_class
*stream_class
,
117 struct bt_ctf_stream
*stream
)
119 struct bt_ctf_stream
*writer_stream
;
120 struct bt_ctf_stream_class
*writer_stream_class
;
122 writer_stream_class
= g_hash_table_lookup(
123 writer_component
->stream_class_map
,
124 (gpointer
) stream_class
);
125 if (writer_stream_class
) {
126 if (!bt_get(writer_stream_class
)) {
127 writer_stream
= NULL
;
128 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
129 __func__
, __FILE__
, __LINE__
);
133 writer_stream_class
= insert_new_stream_class(
134 writer_component
, ctf_writer
, stream_class
);
135 if (!writer_stream_class
) {
136 writer_stream
= NULL
;
137 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
138 __func__
, __FILE__
, __LINE__
);
143 writer_stream
= bt_ctf_writer_create_stream(ctf_writer
,
144 writer_stream_class
);
145 if (!writer_stream
) {
146 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
147 __func__
, __FILE__
, __LINE__
);
151 g_hash_table_insert(writer_component
->stream_map
, (gpointer
) stream
,
154 bt_ctf_writer_flush_metadata(ctf_writer
);
157 bt_put(writer_stream_class
);
159 return writer_stream
;
163 struct bt_ctf_stream
*lookup_stream(struct writer_component
*writer_component
,
164 struct bt_ctf_stream
*stream
)
166 return (struct bt_ctf_stream
*) g_hash_table_lookup(
167 writer_component
->stream_map
,
172 struct bt_ctf_event_class
*get_event_class(struct writer_component
*writer_component
,
173 struct bt_ctf_stream_class
*writer_stream_class
,
174 struct bt_ctf_event_class
*event_class
)
176 return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class
,
177 bt_ctf_event_class_get_name(event_class
));
180 struct bt_ctf_writer
*insert_new_writer(
181 struct writer_component
*writer_component
,
182 struct bt_ctf_trace
*trace
)
184 struct bt_ctf_writer
*ctf_writer
;
185 struct bt_ctf_trace
*writer_trace
;
186 char trace_name
[PATH_MAX
];
187 enum bt_component_status ret
;
189 snprintf(trace_name
, PATH_MAX
, "%s/%s_%03d",
190 writer_component
->base_path
->str
,
191 writer_component
->trace_name_base
->str
,
192 writer_component
->trace_id
++);
193 printf_verbose("CTF-Writer creating trace in %s\n", trace_name
);
195 ctf_writer
= bt_ctf_writer_create(trace_name
);
197 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
198 __func__
, __FILE__
, __LINE__
);
202 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
204 ret
= BT_COMPONENT_STATUS_ERROR
;
205 fprintf(writer_component
->err
,
206 "[error] %s in %s:%d\n", __func__
, __FILE__
,
211 ret
= ctf_copy_trace(writer_component
->err
, trace
, writer_trace
);
212 bt_put(writer_trace
);
213 if (ret
!= BT_COMPONENT_STATUS_OK
) {
214 fprintf(writer_component
->err
, "[error] Failed to copy trace\n");
215 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
216 __func__
, __FILE__
, __LINE__
);
221 g_hash_table_insert(writer_component
->trace_map
, (gpointer
) trace
,
229 struct bt_ctf_writer
*get_writer(struct writer_component
*writer_component
,
230 struct bt_ctf_stream_class
*stream_class
)
232 struct bt_ctf_trace
*trace
;
233 struct bt_ctf_writer
*ctf_writer
;
235 trace
= bt_ctf_stream_class_get_trace(stream_class
);
238 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
239 __func__
, __FILE__
, __LINE__
);
243 ctf_writer
= g_hash_table_lookup(writer_component
->trace_map
,
246 if (!bt_get(ctf_writer
)) {
248 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
249 __func__
, __FILE__
, __LINE__
);
253 ctf_writer
= insert_new_writer(writer_component
, trace
);
262 struct bt_ctf_stream
*get_writer_stream(
263 struct writer_component
*writer_component
,
264 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
266 struct bt_ctf_stream_class
*stream_class
;
267 struct bt_ctf_writer
*ctf_writer
;
268 struct bt_ctf_stream
*writer_stream
;
270 stream_class
= bt_ctf_stream_get_class(stream
);
272 writer_stream
= NULL
;
273 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
274 __func__
, __FILE__
, __LINE__
);
278 ctf_writer
= get_writer(writer_component
, stream_class
);
280 writer_stream
= NULL
;
281 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
282 __func__
, __FILE__
, __LINE__
);
283 goto end_put_stream_class
;
286 writer_stream
= lookup_stream(writer_component
, stream
);
289 if (!bt_get(writer_stream
)) {
290 writer_stream
= NULL
;
291 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
292 __func__
, __FILE__
, __LINE__
);
293 goto end_put_stream_class
;
296 writer_stream
= insert_new_stream(writer_component
, ctf_writer
,
297 stream_class
, stream
);
298 bt_get(writer_stream
);
302 end_put_stream_class
:
303 bt_put(stream_class
);
305 return writer_stream
;
309 enum bt_component_status
writer_new_packet(
310 struct writer_component
*writer_component
,
311 struct bt_ctf_packet
*packet
)
313 struct bt_ctf_stream
*stream
, *writer_stream
;
314 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
316 stream
= bt_ctf_packet_get_stream(packet
);
318 ret
= BT_COMPONENT_STATUS_ERROR
;
319 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
320 __func__
, __FILE__
, __LINE__
);
324 writer_stream
= get_writer_stream(writer_component
, packet
, stream
);
325 if (!writer_stream
) {
326 ret
= BT_COMPONENT_STATUS_ERROR
;
327 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
328 __func__
, __FILE__
, __LINE__
);
332 ret
= ctf_copy_packet_context(writer_component
->err
, packet
,
334 if (ret
!= BT_COMPONENT_STATUS_OK
) {
335 ret
= BT_COMPONENT_STATUS_ERROR
;
336 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
337 __func__
, __FILE__
, __LINE__
);
341 bt_put(writer_stream
);
350 enum bt_component_status
writer_close_packet(
351 struct writer_component
*writer_component
,
352 struct bt_ctf_packet
*packet
)
354 struct bt_ctf_stream
*stream
, *writer_stream
;
355 enum bt_component_status ret
;
357 stream
= bt_ctf_packet_get_stream(packet
);
359 ret
= BT_COMPONENT_STATUS_ERROR
;
360 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
361 __func__
, __FILE__
, __LINE__
);
365 writer_stream
= lookup_stream(writer_component
, stream
);
366 if (!writer_stream
) {
367 ret
= BT_COMPONENT_STATUS_ERROR
;
368 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
369 __func__
, __FILE__
, __LINE__
);
373 if (!bt_get(writer_stream
)) {
374 fprintf(writer_component
->err
,
375 "[error] Failed to get reference on writer stream\n");
376 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
377 __func__
, __FILE__
, __LINE__
);
378 ret
= BT_COMPONENT_STATUS_ERROR
;
382 ret
= bt_ctf_stream_flush(writer_stream
);
384 fprintf(writer_component
->err
,
385 "[error] Failed to flush packet\n");
386 ret
= BT_COMPONENT_STATUS_ERROR
;
389 ret
= BT_COMPONENT_STATUS_OK
;
391 bt_put(writer_stream
);
400 enum bt_component_status
writer_output_event(
401 struct writer_component
*writer_component
,
402 struct bt_ctf_event
*event
)
404 enum bt_component_status ret
;
405 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
406 struct bt_ctf_stream
*stream
, *writer_stream
;
407 struct bt_ctf_stream_class
*stream_class
, *writer_stream_class
;
408 struct bt_ctf_event
*writer_event
;
409 const char *event_name
;
412 event_class
= bt_ctf_event_get_class(event
);
414 ret
= BT_COMPONENT_STATUS_ERROR
;
415 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
420 event_name
= bt_ctf_event_class_get_name(event_class
);
422 ret
= BT_COMPONENT_STATUS_ERROR
;
423 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
425 goto end_put_event_class
;
428 stream
= bt_ctf_event_get_stream(event
);
430 ret
= BT_COMPONENT_STATUS_ERROR
;
431 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
433 goto end_put_event_class
;
436 writer_stream
= lookup_stream(writer_component
, stream
);
437 if (!writer_stream
|| !bt_get(writer_stream
)) {
438 ret
= BT_COMPONENT_STATUS_ERROR
;
439 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
444 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
446 ret
= BT_COMPONENT_STATUS_ERROR
;
447 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
449 goto end_put_writer_stream
;
452 writer_stream_class
= g_hash_table_lookup(
453 writer_component
->stream_class_map
,
454 (gpointer
) stream_class
);
455 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
456 ret
= BT_COMPONENT_STATUS_ERROR
;
457 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
459 goto end_put_stream_class
;
462 writer_event_class
= get_event_class(writer_component
,
463 writer_stream_class
, event_class
);
464 if (!writer_event_class
) {
465 ret
= BT_COMPONENT_STATUS_ERROR
;
466 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
468 goto end_put_writer_stream_class
;
471 writer_event
= ctf_copy_event(writer_component
->err
, event
, writer_event_class
);
473 ret
= BT_COMPONENT_STATUS_ERROR
;
474 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
476 fprintf(writer_component
->err
, "[error] Failed to copy event %s\n",
477 bt_ctf_event_class_get_name(writer_event_class
));
478 goto end_put_writer_event_class
;
481 int_ret
= bt_ctf_stream_append_event(writer_stream
, writer_event
);
483 ret
= BT_COMPONENT_STATUS_ERROR
;
484 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
486 fprintf(writer_component
->err
, "[error] Failed to append event %s\n",
487 bt_ctf_event_class_get_name(writer_event_class
));
488 goto end_put_writer_event
;
491 ret
= BT_COMPONENT_STATUS_OK
;
493 end_put_writer_event
:
494 bt_put(writer_event
);
495 end_put_writer_event_class
:
496 bt_put(writer_event_class
);
497 end_put_writer_stream_class
:
498 bt_put(writer_stream_class
);
499 end_put_stream_class
:
500 bt_put(stream_class
);
501 end_put_writer_stream
:
502 bt_put(writer_stream
);