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
= NULL
;
50 struct bt_ctf_trace
*trace
, *writer_trace
;
51 enum bt_component_status ret
;
53 trace
= bt_ctf_stream_class_get_trace(stream_class
);
55 fprintf(writer_component
->err
,
56 "[error] %s in %s:%d\n", __func__
, __FILE__
,
61 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
64 fprintf(writer_component
->err
,
65 "[error] %s in %s:%d\n", __func__
, __FILE__
,
67 ret
= BT_COMPONENT_STATUS_ERROR
;
71 ret
= ctf_copy_clock_classes(writer_component
->err
, writer_trace
,
72 writer_stream_class
, trace
);
73 if (ret
!= BT_COMPONENT_STATUS_OK
) {
75 fprintf(writer_component
->err
,
76 "[error] %s in %s:%d\n", __func__
, __FILE__
,
78 goto end_put_writer_trace
;
81 writer_stream_class
= ctf_copy_stream_class(writer_component
->err
,
82 stream_class
, writer_trace
, true);
83 if (!writer_stream_class
) {
84 fprintf(writer_component
->err
, "[error] Failed to copy stream class\n");
85 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
86 __func__
, __FILE__
, __LINE__
);
87 goto end_put_writer_trace
;
90 g_hash_table_insert(writer_component
->stream_class_map
,
91 (gpointer
) stream_class
, writer_stream_class
);
98 return writer_stream_class
;
102 struct bt_ctf_stream
*insert_new_stream(
103 struct writer_component
*writer_component
,
104 struct bt_ctf_writer
*ctf_writer
,
105 struct bt_ctf_stream_class
*stream_class
,
106 struct bt_ctf_stream
*stream
)
108 struct bt_ctf_stream
*writer_stream
;
109 struct bt_ctf_stream_class
*writer_stream_class
;
111 writer_stream_class
= g_hash_table_lookup(
112 writer_component
->stream_class_map
,
113 (gpointer
) stream_class
);
114 if (writer_stream_class
) {
115 if (!bt_get(writer_stream_class
)) {
116 writer_stream
= NULL
;
117 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
118 __func__
, __FILE__
, __LINE__
);
122 writer_stream_class
= insert_new_stream_class(
123 writer_component
, ctf_writer
, stream_class
);
124 if (!writer_stream_class
) {
125 writer_stream
= NULL
;
126 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
127 __func__
, __FILE__
, __LINE__
);
132 writer_stream
= bt_ctf_writer_create_stream(ctf_writer
,
133 writer_stream_class
);
134 if (!writer_stream
) {
135 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
136 __func__
, __FILE__
, __LINE__
);
140 g_hash_table_insert(writer_component
->stream_map
, (gpointer
) stream
,
143 bt_ctf_writer_flush_metadata(ctf_writer
);
146 bt_put(writer_stream_class
);
148 return writer_stream
;
152 struct bt_ctf_stream
*lookup_stream(struct writer_component
*writer_component
,
153 struct bt_ctf_stream
*stream
)
155 return (struct bt_ctf_stream
*) g_hash_table_lookup(
156 writer_component
->stream_map
,
161 struct bt_ctf_event_class
*get_event_class(struct writer_component
*writer_component
,
162 struct bt_ctf_stream_class
*writer_stream_class
,
163 struct bt_ctf_event_class
*event_class
)
165 return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class
,
166 bt_ctf_event_class_get_name(event_class
));
169 struct bt_ctf_writer
*insert_new_writer(
170 struct writer_component
*writer_component
,
171 struct bt_ctf_trace
*trace
)
173 struct bt_ctf_writer
*ctf_writer
;
174 struct bt_ctf_trace
*writer_trace
;
175 char trace_name
[PATH_MAX
];
176 enum bt_component_status ret
;
178 snprintf(trace_name
, PATH_MAX
, "%s/%s_%03d",
179 writer_component
->base_path
->str
,
180 writer_component
->trace_name_base
->str
,
181 writer_component
->trace_id
++);
182 printf_verbose("CTF-Writer creating trace in %s\n", trace_name
);
184 ctf_writer
= bt_ctf_writer_create(trace_name
);
186 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
187 __func__
, __FILE__
, __LINE__
);
191 writer_trace
= bt_ctf_writer_get_trace(ctf_writer
);
193 ret
= BT_COMPONENT_STATUS_ERROR
;
194 fprintf(writer_component
->err
,
195 "[error] %s in %s:%d\n", __func__
, __FILE__
,
200 ret
= ctf_copy_trace(writer_component
->err
, trace
, writer_trace
);
201 bt_put(writer_trace
);
202 if (ret
!= BT_COMPONENT_STATUS_OK
) {
203 fprintf(writer_component
->err
, "[error] Failed to copy trace\n");
204 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
205 __func__
, __FILE__
, __LINE__
);
210 g_hash_table_insert(writer_component
->trace_map
, (gpointer
) trace
,
218 struct bt_ctf_writer
*get_writer(struct writer_component
*writer_component
,
219 struct bt_ctf_stream_class
*stream_class
)
221 struct bt_ctf_trace
*trace
;
222 struct bt_ctf_writer
*ctf_writer
;
224 trace
= bt_ctf_stream_class_get_trace(stream_class
);
227 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
228 __func__
, __FILE__
, __LINE__
);
232 ctf_writer
= g_hash_table_lookup(writer_component
->trace_map
,
235 if (!bt_get(ctf_writer
)) {
237 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
238 __func__
, __FILE__
, __LINE__
);
242 ctf_writer
= insert_new_writer(writer_component
, trace
);
251 struct bt_ctf_stream
*get_writer_stream(
252 struct writer_component
*writer_component
,
253 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
255 struct bt_ctf_stream_class
*stream_class
;
256 struct bt_ctf_writer
*ctf_writer
;
257 struct bt_ctf_stream
*writer_stream
;
259 stream_class
= bt_ctf_stream_get_class(stream
);
261 writer_stream
= NULL
;
262 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
263 __func__
, __FILE__
, __LINE__
);
267 ctf_writer
= get_writer(writer_component
, stream_class
);
269 writer_stream
= NULL
;
270 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
271 __func__
, __FILE__
, __LINE__
);
272 goto end_put_stream_class
;
275 writer_stream
= lookup_stream(writer_component
, stream
);
278 if (!bt_get(writer_stream
)) {
279 writer_stream
= NULL
;
280 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
281 __func__
, __FILE__
, __LINE__
);
282 goto end_put_stream_class
;
285 writer_stream
= insert_new_stream(writer_component
, ctf_writer
,
286 stream_class
, stream
);
287 bt_get(writer_stream
);
291 end_put_stream_class
:
292 bt_put(stream_class
);
294 return writer_stream
;
298 enum bt_component_status
writer_new_packet(
299 struct writer_component
*writer_component
,
300 struct bt_ctf_packet
*packet
)
302 struct bt_ctf_stream
*stream
, *writer_stream
;
303 struct bt_ctf_field
*writer_packet_context
;
304 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
307 stream
= bt_ctf_packet_get_stream(packet
);
309 ret
= BT_COMPONENT_STATUS_ERROR
;
310 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
311 __func__
, __FILE__
, __LINE__
);
315 writer_stream
= get_writer_stream(writer_component
, packet
, stream
);
316 if (!writer_stream
) {
317 ret
= BT_COMPONENT_STATUS_ERROR
;
318 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
319 __func__
, __FILE__
, __LINE__
);
323 writer_packet_context
= ctf_copy_packet_context(writer_component
->err
,
324 packet
, writer_stream
);
325 if (!writer_packet_context
) {
326 ret
= BT_COMPONENT_STATUS_ERROR
;
327 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
328 __func__
, __FILE__
, __LINE__
);
332 int_ret
= bt_ctf_stream_set_packet_context(writer_stream
,
333 writer_packet_context
);
335 ret
= BT_COMPONENT_STATUS_ERROR
;
336 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
338 goto end_put_writer_packet_context
;
341 bt_put(writer_stream
);
343 end_put_writer_packet_context
:
344 bt_put(writer_packet_context
);
352 enum bt_component_status
writer_close_packet(
353 struct writer_component
*writer_component
,
354 struct bt_ctf_packet
*packet
)
356 struct bt_ctf_stream
*stream
, *writer_stream
;
357 enum bt_component_status ret
;
359 stream
= bt_ctf_packet_get_stream(packet
);
361 ret
= BT_COMPONENT_STATUS_ERROR
;
362 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
363 __func__
, __FILE__
, __LINE__
);
367 writer_stream
= lookup_stream(writer_component
, stream
);
368 if (!writer_stream
) {
369 ret
= BT_COMPONENT_STATUS_ERROR
;
370 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
371 __func__
, __FILE__
, __LINE__
);
375 if (!bt_get(writer_stream
)) {
376 fprintf(writer_component
->err
,
377 "[error] Failed to get reference on writer stream\n");
378 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
379 __func__
, __FILE__
, __LINE__
);
380 ret
= BT_COMPONENT_STATUS_ERROR
;
384 ret
= bt_ctf_stream_flush(writer_stream
);
386 fprintf(writer_component
->err
,
387 "[error] Failed to flush packet\n");
388 ret
= BT_COMPONENT_STATUS_ERROR
;
391 ret
= BT_COMPONENT_STATUS_OK
;
393 bt_put(writer_stream
);
402 enum bt_component_status
writer_output_event(
403 struct writer_component
*writer_component
,
404 struct bt_ctf_event
*event
)
406 enum bt_component_status ret
;
407 struct bt_ctf_event_class
*event_class
, *writer_event_class
;
408 struct bt_ctf_stream
*stream
, *writer_stream
;
409 struct bt_ctf_stream_class
*stream_class
, *writer_stream_class
;
410 struct bt_ctf_event
*writer_event
;
411 const char *event_name
;
414 event_class
= bt_ctf_event_get_class(event
);
416 ret
= BT_COMPONENT_STATUS_ERROR
;
417 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
422 event_name
= bt_ctf_event_class_get_name(event_class
);
424 ret
= BT_COMPONENT_STATUS_ERROR
;
425 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
427 goto end_put_event_class
;
430 stream
= bt_ctf_event_get_stream(event
);
432 ret
= BT_COMPONENT_STATUS_ERROR
;
433 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
435 goto end_put_event_class
;
438 writer_stream
= lookup_stream(writer_component
, stream
);
439 if (!writer_stream
|| !bt_get(writer_stream
)) {
440 ret
= BT_COMPONENT_STATUS_ERROR
;
441 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
446 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
448 ret
= BT_COMPONENT_STATUS_ERROR
;
449 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
451 goto end_put_writer_stream
;
454 writer_stream_class
= g_hash_table_lookup(
455 writer_component
->stream_class_map
,
456 (gpointer
) stream_class
);
457 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
458 ret
= BT_COMPONENT_STATUS_ERROR
;
459 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
461 goto end_put_stream_class
;
464 writer_event_class
= get_event_class(writer_component
,
465 writer_stream_class
, event_class
);
466 if (!writer_event_class
) {
467 writer_event_class
= ctf_copy_event_class(writer_component
->err
,
469 if (!writer_event_class
) {
470 ret
= BT_COMPONENT_STATUS_ERROR
;
471 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
472 __func__
, __FILE__
, __LINE__
);
473 goto end_put_writer_stream_class
;
475 int_ret
= bt_ctf_stream_class_add_event_class(
476 writer_stream_class
, writer_event_class
);
478 ret
= BT_COMPONENT_STATUS_ERROR
;
479 fprintf(writer_component
->err
, "[error] %s in %s:%d\n",
480 __func__
, __FILE__
, __LINE__
);
481 goto end_put_writer_stream_class
;
485 writer_event
= ctf_copy_event(writer_component
->err
, event
,
486 writer_event_class
, true);
488 ret
= BT_COMPONENT_STATUS_ERROR
;
489 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
491 fprintf(writer_component
->err
, "[error] Failed to copy event %s\n",
492 bt_ctf_event_class_get_name(writer_event_class
));
493 goto end_put_writer_event_class
;
496 int_ret
= bt_ctf_stream_append_event(writer_stream
, writer_event
);
498 ret
= BT_COMPONENT_STATUS_ERROR
;
499 fprintf(writer_component
->err
, "[error] %s in %s:%d\n", __func__
,
501 fprintf(writer_component
->err
, "[error] Failed to append event %s\n",
502 bt_ctf_event_class_get_name(writer_event_class
));
503 goto end_put_writer_event
;
506 ret
= BT_COMPONENT_STATUS_OK
;
508 end_put_writer_event
:
509 bt_put(writer_event
);
510 end_put_writer_event_class
:
511 bt_put(writer_event_class
);
512 end_put_writer_stream_class
:
513 bt_put(writer_stream_class
);
514 end_put_stream_class
:
515 bt_put(stream_class
);
516 end_put_writer_stream
:
517 bt_put(writer_stream
);