Split clock value API from clock class API
[babeltrace.git] / lib / ctf-ir / event.c
1 /*
2 * event.c
3 *
4 * Babeltrace CTF IR - Event
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
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
26 * SOFTWARE.
27 */
28
29 #define BT_LOG_TAG "EVENT"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/ctf-ir/fields-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/clock-class.h>
35 #include <babeltrace/ctf-ir/clock-value.h>
36 #include <babeltrace/ctf-ir/clock-value-internal.h>
37 #include <babeltrace/ctf-ir/clock-class-internal.h>
38 #include <babeltrace/ctf-ir/event-internal.h>
39 #include <babeltrace/ctf-ir/event-class.h>
40 #include <babeltrace/ctf-ir/event-class-internal.h>
41 #include <babeltrace/ctf-ir/stream-class.h>
42 #include <babeltrace/ctf-ir/stream-class-internal.h>
43 #include <babeltrace/ctf-ir/stream-internal.h>
44 #include <babeltrace/ctf-ir/packet.h>
45 #include <babeltrace/ctf-ir/packet-internal.h>
46 #include <babeltrace/ctf-ir/trace-internal.h>
47 #include <babeltrace/ctf-ir/validation-internal.h>
48 #include <babeltrace/ctf-ir/packet-internal.h>
49 #include <babeltrace/ctf-ir/utils.h>
50 #include <babeltrace/ctf-writer/serialize-internal.h>
51 #include <babeltrace/ref.h>
52 #include <babeltrace/ctf-ir/attributes-internal.h>
53 #include <babeltrace/compiler-internal.h>
54 #include <inttypes.h>
55
56 static
57 void bt_ctf_event_destroy(struct bt_object *obj);
58
59 struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
60 {
61 int ret;
62 enum bt_ctf_validation_flag validation_flags =
63 BT_CTF_VALIDATION_FLAG_STREAM |
64 BT_CTF_VALIDATION_FLAG_EVENT;
65 struct bt_ctf_event *event = NULL;
66 struct bt_ctf_trace *trace = NULL;
67 struct bt_ctf_stream_class *stream_class = NULL;
68 struct bt_ctf_field_type *packet_header_type = NULL;
69 struct bt_ctf_field_type *packet_context_type = NULL;
70 struct bt_ctf_field_type *event_header_type = NULL;
71 struct bt_ctf_field_type *stream_event_ctx_type = NULL;
72 struct bt_ctf_field_type *event_context_type = NULL;
73 struct bt_ctf_field_type *event_payload_type = NULL;
74 struct bt_ctf_field *event_header = NULL;
75 struct bt_ctf_field *stream_event_context = NULL;
76 struct bt_ctf_field *event_context = NULL;
77 struct bt_ctf_field *event_payload = NULL;
78 struct bt_value *environment = NULL;
79 struct bt_ctf_validation_output validation_output = { 0 };
80 int trace_valid = 0;
81
82 BT_LOGD("Creating event object: event-class-addr=%p, "
83 "event-class-name=\"%s\", event-class-id=%" PRId64,
84 event_class, bt_ctf_event_class_get_name(event_class),
85 bt_ctf_event_class_get_id(event_class));
86
87 if (!event_class) {
88 BT_LOGW_STR("Invalid parameter: event class is NULL.");
89 goto error;
90 }
91
92 stream_class = bt_ctf_event_class_get_stream_class(event_class);
93
94 /*
95 * We disallow the creation of an event if its event class has not been
96 * associated to a stream class.
97 */
98 if (!stream_class) {
99 BT_LOGW_STR("Event class is not part of a stream class.");
100 goto error;
101 }
102
103 /* The event class was frozen when added to its stream class */
104 assert(event_class->frozen);
105
106 /* Validate the trace (if any), the stream class, and the event class */
107 trace = bt_ctf_stream_class_get_trace(stream_class);
108 if (trace) {
109 BT_LOGD_STR("Event's class is part of a trace.");
110 packet_header_type = bt_ctf_trace_get_packet_header_type(trace);
111 trace_valid = trace->valid;
112 assert(trace_valid);
113 environment = trace->environment;
114 }
115
116 packet_context_type = bt_ctf_stream_class_get_packet_context_type(
117 stream_class);
118 event_header_type = bt_ctf_stream_class_get_event_header_type(
119 stream_class);
120 stream_event_ctx_type = bt_ctf_stream_class_get_event_context_type(
121 stream_class);
122 event_context_type = bt_ctf_event_class_get_context_type(event_class);
123 event_payload_type = bt_ctf_event_class_get_payload_type(event_class);
124 ret = bt_ctf_validate_class_types(environment, packet_header_type,
125 packet_context_type, event_header_type, stream_event_ctx_type,
126 event_context_type, event_payload_type, trace_valid,
127 stream_class->valid, event_class->valid,
128 &validation_output, validation_flags);
129 BT_PUT(packet_header_type);
130 BT_PUT(packet_context_type);
131 BT_PUT(event_header_type);
132 BT_PUT(stream_event_ctx_type);
133 BT_PUT(event_context_type);
134 BT_PUT(event_payload_type);
135 if (ret) {
136 /*
137 * This means something went wrong during the validation
138 * process, not that the objects are invalid.
139 */
140 BT_LOGE("Failed to validate event and parents: ret=%d", ret);
141 goto error;
142 }
143
144 if ((validation_output.valid_flags & validation_flags) !=
145 validation_flags) {
146 /* Invalid trace/stream class/event class */
147 BT_LOGW("Invalid trace, stream class, or event class: "
148 "valid-flags=0x%x", validation_output.valid_flags);
149 goto error;
150 }
151
152 /*
153 * At this point we know the trace (if associated to the stream
154 * class), the stream class, and the event class, with their
155 * current types, are valid. We may proceed with creating
156 * the event.
157 */
158 event = g_new0(struct bt_ctf_event, 1);
159 if (!event) {
160 BT_LOGE_STR("Failed to allocate one event.");
161 goto error;
162 }
163
164 bt_object_init(event, bt_ctf_event_destroy);
165
166 /*
167 * event does not share a common ancestor with the event class; it has
168 * to guarantee its existence by holding a reference. This reference
169 * shall be released once the event is associated to a stream since,
170 * from that point, the event and its class will share the same
171 * lifetime.
172 */
173 event->event_class = bt_get(event_class);
174 event->clock_values = g_hash_table_new_full(g_direct_hash,
175 g_direct_equal, bt_put, bt_put);
176
177 if (validation_output.event_header_type) {
178 BT_LOGD("Creating initial event header field: ft-addr=%p",
179 validation_output.event_header_type);
180 event_header =
181 bt_ctf_field_create(validation_output.event_header_type);
182 if (!event_header) {
183 BT_LOGE_STR("Cannot create initial event header field object.");
184 goto error;
185 }
186 }
187
188 if (validation_output.stream_event_ctx_type) {
189 BT_LOGD("Creating initial stream event context field: ft-addr=%p",
190 validation_output.stream_event_ctx_type);
191 stream_event_context = bt_ctf_field_create(
192 validation_output.stream_event_ctx_type);
193 if (!stream_event_context) {
194 BT_LOGE_STR("Cannot create initial stream event context field object.");
195 goto error;
196 }
197 }
198
199 if (validation_output.event_context_type) {
200 BT_LOGD("Creating initial event context field: ft-addr=%p",
201 validation_output.event_context_type);
202 event_context = bt_ctf_field_create(
203 validation_output.event_context_type);
204 if (!event_context) {
205 BT_LOGE_STR("Cannot create initial event context field object.");
206 goto error;
207 }
208 }
209
210 if (validation_output.event_payload_type) {
211 BT_LOGD("Creating initial event payload field: ft-addr=%p",
212 validation_output.event_payload_type);
213 event_payload = bt_ctf_field_create(
214 validation_output.event_payload_type);
215 if (!event_payload) {
216 BT_LOGE_STR("Cannot create initial event payload field object.");
217 goto error;
218 }
219 }
220
221 /*
222 * At this point all the fields are created, potentially from
223 * validated copies of field types, so that the field types and
224 * fields can be replaced in the trace, stream class,
225 * event class, and created event.
226 */
227 bt_ctf_validation_replace_types(trace, stream_class,
228 event_class, &validation_output, validation_flags);
229 BT_MOVE(event->event_header, event_header);
230 BT_MOVE(event->stream_event_context, stream_event_context);
231 BT_MOVE(event->context_payload, event_context);
232 BT_MOVE(event->fields_payload, event_payload);
233
234 /*
235 * Put what was not moved in bt_ctf_validation_replace_types().
236 */
237 bt_ctf_validation_output_put_types(&validation_output);
238
239 /*
240 * Freeze the stream class since the event header must not be changed
241 * anymore.
242 */
243 bt_ctf_stream_class_freeze(stream_class);
244
245 /*
246 * Mark stream class, and event class as valid since
247 * they're all frozen now.
248 */
249 stream_class->valid = 1;
250 event_class->valid = 1;
251
252 /* Put stuff we borrowed from the event class */
253 BT_PUT(stream_class);
254 BT_PUT(trace);
255 BT_LOGD("Created event object: addr=%p, event-class-name=\"%s\", "
256 "event-class-id=%" PRId64,
257 event, bt_ctf_event_class_get_name(event->event_class),
258 bt_ctf_event_class_get_id(event_class));
259 return event;
260
261 error:
262 bt_ctf_validation_output_put_types(&validation_output);
263 BT_PUT(event);
264 BT_PUT(stream_class);
265 BT_PUT(trace);
266 BT_PUT(event_header);
267 BT_PUT(stream_event_context);
268 BT_PUT(event_context);
269 BT_PUT(event_payload);
270 assert(!packet_header_type);
271 assert(!packet_context_type);
272 assert(!event_header_type);
273 assert(!stream_event_ctx_type);
274 assert(!event_context_type);
275 assert(!event_payload_type);
276
277 return event;
278 }
279
280 struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
281 {
282 struct bt_ctf_event_class *event_class = NULL;
283
284 if (!event) {
285 BT_LOGW_STR("Invalid parameter: event is NULL.");
286 goto end;
287 }
288
289 event_class = bt_get(bt_ctf_event_borrow_event_class(event));
290 end:
291 return event_class;
292 }
293
294 struct bt_ctf_stream *bt_ctf_event_get_stream(struct bt_ctf_event *event)
295 {
296 struct bt_ctf_stream *stream = NULL;
297
298 if (!event) {
299 BT_LOGW_STR("Invalid parameter: event is NULL.");
300 goto end;
301 }
302
303 /*
304 * If the event has a parent, then this is its (writer) stream.
305 * If the event has no parent, then if it has a packet, this
306 * is its (non-writer) stream.
307 */
308 if (event->base.parent) {
309 stream = (struct bt_ctf_stream *) bt_object_get_parent(event);
310 } else {
311 if (event->packet) {
312 stream = bt_get(event->packet->stream);
313 }
314 }
315
316 end:
317 return stream;
318 }
319
320 int bt_ctf_event_set_payload(struct bt_ctf_event *event,
321 const char *name,
322 struct bt_ctf_field *payload)
323 {
324 int ret = 0;
325
326 if (!event || !payload) {
327 BT_LOGW("Invalid parameter: event or payload field is NULL: "
328 "event-addr=%p, payload-field-addr=%p",
329 event, payload);
330 ret = -1;
331 goto end;
332 }
333
334 if (event->frozen) {
335 BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
336 "event-class-name=\"%s\", event-class-id=%" PRId64,
337 event, bt_ctf_event_class_get_name(event->event_class),
338 bt_ctf_event_class_get_id(event->event_class));
339 ret = -1;
340 goto end;
341 }
342
343 if (name) {
344 ret = bt_ctf_field_structure_set_field_by_name(
345 event->fields_payload, name, payload);
346 } else {
347 struct bt_ctf_field_type *payload_type;
348
349 payload_type = bt_ctf_field_get_type(payload);
350
351 if (bt_ctf_field_type_compare(payload_type,
352 event->event_class->fields) == 0) {
353 bt_put(event->fields_payload);
354 bt_get(payload);
355 event->fields_payload = payload;
356 } else {
357 BT_LOGW("Invalid parameter: payload field type is different from the expected field type: "
358 "event-addr=%p, event-class-name=\"%s\", "
359 "event-class-id=%" PRId64,
360 event,
361 bt_ctf_event_class_get_name(event->event_class),
362 bt_ctf_event_class_get_id(event->event_class));
363 ret = -1;
364 }
365
366 bt_put(payload_type);
367 }
368
369 if (ret) {
370 BT_LOGW("Failed to set event's payload field: event-addr=%p, "
371 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
372 "payload-field-name=\"%s\", payload-field-addr=%p",
373 event, bt_ctf_event_class_get_name(event->event_class),
374 bt_ctf_event_class_get_id(event->event_class),
375 name, payload);
376 } else {
377 BT_LOGV("Set event's payload field: event-addr=%p, "
378 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
379 "payload-field-name=\"%s\", payload-field-addr=%p",
380 event, bt_ctf_event_class_get_name(event->event_class),
381 bt_ctf_event_class_get_id(event->event_class),
382 name, payload);
383 }
384
385 end:
386 return ret;
387 }
388
389 struct bt_ctf_field *bt_ctf_event_get_event_payload(struct bt_ctf_event *event)
390 {
391 struct bt_ctf_field *payload = NULL;
392
393 if (!event) {
394 BT_LOGW_STR("Invalid parameter: event is NULL.");
395 goto end;
396 }
397
398 if (!event->fields_payload) {
399 BT_LOGV("Event has no current payload field: addr=%p, "
400 "event-class-name=\"%s\", event-class-id=%" PRId64,
401 event, bt_ctf_event_class_get_name(event->event_class),
402 bt_ctf_event_class_get_id(event->event_class));
403 goto end;
404 }
405
406 payload = event->fields_payload;
407 bt_get(payload);
408 end:
409 return payload;
410 }
411
412 int bt_ctf_event_set_event_payload(struct bt_ctf_event *event,
413 struct bt_ctf_field *payload)
414 {
415 return bt_ctf_event_set_payload(event, NULL, payload);
416 }
417
418 struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
419 const char *name)
420 {
421 struct bt_ctf_field *field = NULL;
422
423 if (!event) {
424 BT_LOGW_STR("Invalid parameter: event is NULL.");
425 goto end;
426 }
427
428 if (name) {
429 field = bt_ctf_field_structure_get_field(event->fields_payload,
430 name);
431 } else {
432 field = event->fields_payload;
433 bt_get(field);
434 }
435 end:
436 return field;
437 }
438
439 struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
440 struct bt_ctf_event *event, uint64_t index)
441 {
442 struct bt_ctf_field *field = NULL;
443
444 if (!event) {
445 BT_LOGW_STR("Invalid parameter: event is NULL.");
446 goto end;
447 }
448
449 field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
450 index);
451 end:
452 return field;
453 }
454
455 struct bt_ctf_field *bt_ctf_event_get_header(
456 struct bt_ctf_event *event)
457 {
458 struct bt_ctf_field *header = NULL;
459
460 if (!event) {
461 BT_LOGW_STR("Invalid parameter: event is NULL.");
462 goto end;
463 }
464
465 if (!event->event_header) {
466 BT_LOGV("Event has no current header field: addr=%p, "
467 "event-class-name=\"%s\", event-class-id=%" PRId64,
468 event, bt_ctf_event_class_get_name(event->event_class),
469 bt_ctf_event_class_get_id(event->event_class));
470 goto end;
471 }
472
473 header = event->event_header;
474 bt_get(header);
475 end:
476 return header;
477 }
478
479 int bt_ctf_event_set_header(struct bt_ctf_event *event,
480 struct bt_ctf_field *header)
481 {
482 int ret = 0;
483 struct bt_ctf_field_type *field_type = NULL;
484 struct bt_ctf_stream_class *stream_class = NULL;
485
486 if (!event) {
487 BT_LOGW_STR("Invalid parameter: event is NULL.");
488 ret = -1;
489 goto end;
490 }
491
492 if (event->frozen) {
493 BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
494 "event-class-name=\"%s\", event-class-id=%" PRId64,
495 event, bt_ctf_event_class_get_name(event->event_class),
496 bt_ctf_event_class_get_id(event->event_class));
497 ret = -1;
498 goto end;
499 }
500
501 stream_class = (struct bt_ctf_stream_class *) bt_object_get_parent(
502 event->event_class);
503 /*
504 * Ensure the provided header's type matches the one registered to the
505 * stream class.
506 */
507 if (header) {
508 field_type = bt_ctf_field_get_type(header);
509 if (bt_ctf_field_type_compare(field_type,
510 stream_class->event_header_type)) {
511 BT_LOGW("Invalid parameter: header field type is different from the expected field type: "
512 "event-addr=%p, event-class-name=\"%s\", "
513 "event-class-id=%" PRId64,
514 event,
515 bt_ctf_event_class_get_name(event->event_class),
516 bt_ctf_event_class_get_id(event->event_class));
517 ret = -1;
518 goto end;
519 }
520 } else {
521 if (stream_class->event_header_type) {
522 BT_LOGW("Invalid parameter: setting no event header but event header field type is not NULL: "
523 "event-addr=%p, event-class-name=\"%s\", "
524 "event-class-id=%" PRId64 ", "
525 "event-header-ft-addr=%p",
526 event,
527 bt_ctf_event_class_get_name(event->event_class),
528 bt_ctf_event_class_get_id(event->event_class),
529 stream_class->event_header_type);
530 ret = -1;
531 goto end;
532 }
533 }
534
535 bt_put(event->event_header);
536 event->event_header = bt_get(header);
537 BT_LOGV("Set event's header field: event-addr=%p, "
538 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
539 "header-field-addr=%p",
540 event, bt_ctf_event_class_get_name(event->event_class),
541 bt_ctf_event_class_get_id(event->event_class), header);
542 end:
543 bt_put(stream_class);
544 bt_put(field_type);
545 return ret;
546 }
547
548 struct bt_ctf_field *bt_ctf_event_get_event_context(
549 struct bt_ctf_event *event)
550 {
551 struct bt_ctf_field *context = NULL;
552
553 if (!event) {
554 BT_LOGW_STR("Invalid parameter: event is NULL.");
555 goto end;
556 }
557
558 if (!event->context_payload) {
559 BT_LOGV("Event has no current context field: addr=%p, "
560 "event-class-name=\"%s\", event-class-id=%" PRId64,
561 event, bt_ctf_event_class_get_name(event->event_class),
562 bt_ctf_event_class_get_id(event->event_class));
563 goto end;
564 }
565
566 context = event->context_payload;
567 bt_get(context);
568 end:
569 return context;
570 }
571
572 int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
573 struct bt_ctf_field *context)
574 {
575 int ret = 0;
576 struct bt_ctf_field_type *field_type = NULL;
577
578 if (!event) {
579 BT_LOGW_STR("Invalid parameter: event is NULL.");
580 ret = -1;
581 goto end;
582 }
583
584 if (event->frozen) {
585 BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
586 "event-class-name=\"%s\", event-class-id=%" PRId64,
587 event, bt_ctf_event_class_get_name(event->event_class),
588 bt_ctf_event_class_get_id(event->event_class));
589 ret = -1;
590 goto end;
591 }
592
593 if (context) {
594 field_type = bt_ctf_field_get_type(context);
595
596 if (bt_ctf_field_type_compare(field_type,
597 event->event_class->context)) {
598 BT_LOGW("Invalid parameter: context field type is different from the expected field type: "
599 "event-addr=%p, event-class-name=\"%s\", "
600 "event-class-id=%" PRId64,
601 event,
602 bt_ctf_event_class_get_name(event->event_class),
603 bt_ctf_event_class_get_id(event->event_class));
604 ret = -1;
605 goto end;
606 }
607 } else {
608 if (event->event_class->context) {
609 BT_LOGW("Invalid parameter: setting no event context but event context field type is not NULL: "
610 "event-addr=%p, event-class-name=\"%s\", "
611 "event-class-id=%" PRId64 ", "
612 "event-context-ft-addr=%p",
613 event,
614 bt_ctf_event_class_get_name(event->event_class),
615 bt_ctf_event_class_get_id(event->event_class),
616 event->event_class->context);
617 ret = -1;
618 goto end;
619 }
620 }
621
622 bt_put(event->context_payload);
623 event->context_payload = bt_get(context);
624 BT_LOGV("Set event's context field: event-addr=%p, "
625 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
626 "context-field-addr=%p",
627 event, bt_ctf_event_class_get_name(event->event_class),
628 bt_ctf_event_class_get_id(event->event_class), context);
629 end:
630 bt_put(field_type);
631 return ret;
632 }
633
634 struct bt_ctf_field *bt_ctf_event_get_stream_event_context(
635 struct bt_ctf_event *event)
636 {
637 struct bt_ctf_field *stream_event_context = NULL;
638
639 if (!event) {
640 BT_LOGW_STR("Invalid parameter: event is NULL.");
641 goto end;
642 }
643
644 if (!event->stream_event_context) {
645 BT_LOGV("Event has no current stream event context field: addr=%p, "
646 "event-class-name=\"%s\", event-class-id=%" PRId64,
647 event, bt_ctf_event_class_get_name(event->event_class),
648 bt_ctf_event_class_get_id(event->event_class));
649 goto end;
650 }
651
652 stream_event_context = event->stream_event_context;
653 end:
654 return bt_get(stream_event_context);
655 }
656
657 int bt_ctf_event_set_stream_event_context(struct bt_ctf_event *event,
658 struct bt_ctf_field *stream_event_context)
659 {
660 int ret = 0;
661 struct bt_ctf_field_type *field_type = NULL;
662 struct bt_ctf_stream_class *stream_class = NULL;
663
664 if (!event) {
665 BT_LOGW_STR("Invalid parameter: event is NULL.");
666 ret = -1;
667 goto end;
668 }
669
670 if (event->frozen) {
671 BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
672 "event-class-name=\"%s\", event-class-id=%" PRId64,
673 event, bt_ctf_event_class_get_name(event->event_class),
674 bt_ctf_event_class_get_id(event->event_class));
675 ret = -1;
676 goto end;
677 }
678
679 stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
680 /*
681 * We should not have been able to create the event without associating
682 * the event class to a stream class.
683 */
684 assert(stream_class);
685
686 if (stream_event_context) {
687 field_type = bt_ctf_field_get_type(stream_event_context);
688 if (bt_ctf_field_type_compare(field_type,
689 stream_class->event_context_type)) {
690 BT_LOGW("Invalid parameter: stream event context field type is different from the expected field type: "
691 "event-addr=%p, event-class-name=\"%s\", "
692 "event-class-id=%" PRId64,
693 event,
694 bt_ctf_event_class_get_name(event->event_class),
695 bt_ctf_event_class_get_id(event->event_class));
696 ret = -1;
697 goto end;
698 }
699 } else {
700 if (stream_class->event_context_type) {
701 BT_LOGW("Invalid parameter: setting no stream event context but stream event context field type is not NULL: "
702 "event-addr=%p, event-class-name=\"%s\", "
703 "event-class-id=%" PRId64 ", "
704 "stream-event-context-ft-addr=%p",
705 event,
706 bt_ctf_event_class_get_name(event->event_class),
707 bt_ctf_event_class_get_id(event->event_class),
708 stream_class->event_context_type);
709 ret = -1;
710 goto end;
711 }
712 }
713
714 bt_get(stream_event_context);
715 BT_MOVE(event->stream_event_context, stream_event_context);
716 BT_LOGV("Set event's stream event context field: event-addr=%p, "
717 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
718 "stream-event-context-field-addr=%p",
719 event, bt_ctf_event_class_get_name(event->event_class),
720 bt_ctf_event_class_get_id(event->event_class),
721 stream_event_context);
722 end:
723 BT_PUT(stream_class);
724 bt_put(field_type);
725 return ret;
726 }
727
728 /* Pre-2.0 CTF writer backward compatibility */
729 void bt_ctf_event_get(struct bt_ctf_event *event)
730 {
731 bt_get(event);
732 }
733
734 /* Pre-2.0 CTF writer backward compatibility */
735 void bt_ctf_event_put(struct bt_ctf_event *event)
736 {
737 bt_put(event);
738 }
739
740 void bt_ctf_event_destroy(struct bt_object *obj)
741 {
742 struct bt_ctf_event *event;
743
744 event = container_of(obj, struct bt_ctf_event, base);
745 BT_LOGD("Destroying event: addr=%p, "
746 "event-class-name=\"%s\", event-class-id=%" PRId64,
747 event, bt_ctf_event_class_get_name(event->event_class),
748 bt_ctf_event_class_get_id(event->event_class));
749
750 if (!event->base.parent) {
751 /*
752 * Event was keeping a reference to its class since it shared no
753 * common ancestor with it to guarantee they would both have the
754 * same lifetime.
755 */
756 bt_put(event->event_class);
757 }
758 g_hash_table_destroy(event->clock_values);
759 BT_LOGD_STR("Putting event's header field.");
760 bt_put(event->event_header);
761 BT_LOGD_STR("Putting event's stream event context field.");
762 bt_put(event->stream_event_context);
763 BT_LOGD_STR("Putting event's context field.");
764 bt_put(event->context_payload);
765 BT_LOGD_STR("Putting event's payload field.");
766 bt_put(event->fields_payload);
767 BT_LOGD_STR("Putting event's packet.");
768 bt_put(event->packet);
769 g_free(event);
770 }
771
772 struct bt_ctf_clock_value *bt_ctf_event_get_clock_value(
773 struct bt_ctf_event *event, struct bt_ctf_clock_class *clock_class)
774 {
775 struct bt_ctf_clock_value *clock_value = NULL;
776
777 if (!event || !clock_class) {
778 BT_LOGW("Invalid parameter: event or clock class is NULL: "
779 "event-addr=%p, clock-class-addr=%p",
780 event, clock_class);
781 goto end;
782 }
783
784 clock_value = g_hash_table_lookup(event->clock_values, clock_class);
785 if (!clock_value) {
786 BT_LOGV("No clock value associated to the given clock class: "
787 "event-addr=%p, event-class-name=\"%s\", "
788 "event-class-id=%" PRId64 ", clock-class-addr=%p, "
789 "clock-class-name=\"%s\"", event,
790 bt_ctf_event_class_get_name(event->event_class),
791 bt_ctf_event_class_get_id(event->event_class),
792 clock_class, bt_ctf_clock_class_get_name(clock_class));
793 goto end;
794 }
795
796 bt_get(clock_value);
797 end:
798 return clock_value;
799 }
800
801 int bt_ctf_event_set_clock_value(struct bt_ctf_event *event,
802 struct bt_ctf_clock_value *value)
803 {
804 int ret = 0;
805 struct bt_ctf_trace *trace;
806 struct bt_ctf_stream_class *stream_class;
807 struct bt_ctf_event_class *event_class;
808 struct bt_ctf_clock_class *clock_class = NULL;
809
810 if (!event || !value) {
811 BT_LOGW("Invalid parameter: event or clock value is NULL: "
812 "event-addr=%p, clock-value-addr=%p",
813 event, value);
814 ret = -1;
815 goto end;
816 }
817
818 if (event->frozen) {
819 BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
820 "event-class-name=\"%s\", event-class-id=%" PRId64,
821 event, bt_ctf_event_class_get_name(event->event_class),
822 bt_ctf_event_class_get_id(event->event_class));
823 ret = -1;
824 goto end;
825 }
826
827 clock_class = bt_ctf_clock_value_get_class(value);
828 event_class = bt_ctf_event_borrow_event_class(event);
829 assert(event_class);
830 stream_class = bt_ctf_event_class_borrow_stream_class(event_class);
831 assert(stream_class);
832 trace = bt_ctf_stream_class_borrow_trace(stream_class);
833 assert(trace);
834
835 if (!bt_ctf_trace_has_clock_class(trace, clock_class)) {
836 BT_LOGW("Invalid parameter: clock class is not part of event's trace: "
837 "event-addr=%p, event-class-name=\"%s\", "
838 "event-class-id=%" PRId64 ", clock-class-addr=%p, "
839 "clock-class-name=\"%s\"",
840 event, bt_ctf_event_class_get_name(event->event_class),
841 bt_ctf_event_class_get_id(event->event_class),
842 clock_class, bt_ctf_clock_class_get_name(clock_class));
843 ret = -1;
844 goto end;
845 }
846
847 g_hash_table_insert(event->clock_values, clock_class, bt_get(value));
848 BT_LOGV("Set event's clock value: "
849 "event-addr=%p, event-class-name=\"%s\", "
850 "event-class-id=%" PRId64 ", clock-class-addr=%p, "
851 "clock-class-name=\"%s\", clock-value-addr=%p, "
852 "clock-value-cycles=%" PRIu64,
853 event, bt_ctf_event_class_get_name(event->event_class),
854 bt_ctf_event_class_get_id(event->event_class),
855 clock_class, bt_ctf_clock_class_get_name(clock_class),
856 value, value->value);
857 clock_class = NULL;
858
859 end:
860 bt_put(clock_class);
861 return ret;
862 }
863
864 BT_HIDDEN
865 int bt_ctf_event_validate(struct bt_ctf_event *event)
866 {
867 /* Make sure each field's payload has been set */
868 int ret;
869 struct bt_ctf_stream_class *stream_class = NULL;
870
871 assert(event);
872 if (event->event_header) {
873 ret = bt_ctf_field_validate(event->event_header);
874 if (ret) {
875 BT_LOGD("Invalid event's header field: "
876 "event-addr=%p, event-class-name=\"%s\", "
877 "event-class-id=%" PRId64,
878 event, bt_ctf_event_class_get_name(event->event_class),
879 bt_ctf_event_class_get_id(event->event_class));
880 goto end;
881 }
882 }
883
884 stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
885 /*
886 * We should not have been able to create the event without associating
887 * the event class to a stream class.
888 */
889 assert(stream_class);
890 if (stream_class->event_context_type) {
891 ret = bt_ctf_field_validate(event->stream_event_context);
892 if (ret) {
893 BT_LOGD("Invalid event's stream event context field: "
894 "event-addr=%p, event-class-name=\"%s\", "
895 "event-class-id=%" PRId64,
896 event,
897 bt_ctf_event_class_get_name(event->event_class),
898 bt_ctf_event_class_get_id(event->event_class));
899 goto end;
900 }
901 }
902
903 ret = bt_ctf_field_validate(event->fields_payload);
904 if (ret) {
905 BT_LOGD("Invalid event's payload field: "
906 "event-addr=%p, event-class-name=\"%s\", "
907 "event-class-id=%" PRId64,
908 event,
909 bt_ctf_event_class_get_name(event->event_class),
910 bt_ctf_event_class_get_id(event->event_class));
911 goto end;
912 }
913
914 if (event->event_class->context) {
915 BT_LOGD("Invalid event's context field: "
916 "event-addr=%p, event-class-name=\"%s\", "
917 "event-class-id=%" PRId64,
918 event,
919 bt_ctf_event_class_get_name(event->event_class),
920 bt_ctf_event_class_get_id(event->event_class));
921 ret = bt_ctf_field_validate(event->context_payload);
922 }
923 end:
924 bt_put(stream_class);
925 return ret;
926 }
927
928 BT_HIDDEN
929 int bt_ctf_event_serialize(struct bt_ctf_event *event,
930 struct bt_ctf_stream_pos *pos,
931 enum bt_ctf_byte_order native_byte_order)
932 {
933 int ret = 0;
934
935 assert(event);
936 assert(pos);
937
938 BT_LOGV_STR("Serializing event's context field.");
939 if (event->context_payload) {
940 ret = bt_ctf_field_serialize(event->context_payload, pos,
941 native_byte_order);
942 if (ret) {
943 BT_LOGW("Cannot serialize event's context field: "
944 "event-addr=%p, event-class-name=\"%s\", "
945 "event-class-id=%" PRId64,
946 event,
947 bt_ctf_event_class_get_name(event->event_class),
948 bt_ctf_event_class_get_id(event->event_class));
949 goto end;
950 }
951 }
952
953 BT_LOGV_STR("Serializing event's payload field.");
954 if (event->fields_payload) {
955 ret = bt_ctf_field_serialize(event->fields_payload, pos,
956 native_byte_order);
957 if (ret) {
958 BT_LOGW("Cannot serialize event's payload field: "
959 "event-addr=%p, event-class-name=\"%s\", "
960 "event-class-id=%" PRId64,
961 event,
962 bt_ctf_event_class_get_name(event->event_class),
963 bt_ctf_event_class_get_id(event->event_class));
964 goto end;
965 }
966 }
967 end:
968 return ret;
969 }
970
971 struct bt_ctf_packet *bt_ctf_event_get_packet(struct bt_ctf_event *event)
972 {
973 struct bt_ctf_packet *packet = NULL;
974
975 if (!event) {
976 BT_LOGW_STR("Invalid parameter: event is NULL.");
977 goto end;
978 }
979
980 if (!event->packet) {
981 BT_LOGV("Event has no current packet: addr=%p, "
982 "event-class-name=\"%s\", event-class-id=%" PRId64,
983 event, bt_ctf_event_class_get_name(event->event_class),
984 bt_ctf_event_class_get_id(event->event_class));
985 goto end;
986 }
987
988 packet = bt_get(event->packet);
989 end:
990 return packet;
991 }
992
993 int bt_ctf_event_set_packet(struct bt_ctf_event *event,
994 struct bt_ctf_packet *packet)
995 {
996 struct bt_ctf_stream_class *event_stream_class = NULL;
997 struct bt_ctf_stream_class *packet_stream_class = NULL;
998 struct bt_ctf_stream *stream = NULL;
999 int ret = 0;
1000
1001 if (!event || !packet) {
1002 BT_LOGW("Invalid parameter: event or packet is NULL: "
1003 "event-addr=%p, packet-addr=%p",
1004 event, packet);
1005 ret = -1;
1006 goto end;
1007 }
1008
1009 if (event->frozen) {
1010 BT_LOGW("Invalid parameter: event is frozen: addr=%p, "
1011 "event-class-name=\"%s\", event-class-id=%" PRId64,
1012 event, bt_ctf_event_class_get_name(event->event_class),
1013 bt_ctf_event_class_get_id(event->event_class));
1014 ret = -1;
1015 goto end;
1016 }
1017
1018 /*
1019 * Make sure the new packet was created by this event's
1020 * stream, if it is set.
1021 */
1022 stream = bt_ctf_event_get_stream(event);
1023 if (stream) {
1024 if (packet->stream != stream) {
1025 BT_LOGW("Invalid parameter: packet's stream and event's stream differ: "
1026 "event-addr=%p, event-class-name=\"%s\", "
1027 "event-class-id=%" PRId64 ", packet-stream-addr=%p, "
1028 "event-stream-addr=%p",
1029 event, bt_ctf_event_class_get_name(event->event_class),
1030 bt_ctf_event_class_get_id(event->event_class),
1031 packet->stream, stream);
1032 ret = -1;
1033 goto end;
1034 }
1035 } else {
1036 event_stream_class =
1037 bt_ctf_event_class_get_stream_class(event->event_class);
1038 packet_stream_class =
1039 bt_ctf_stream_get_class(packet->stream);
1040
1041 assert(event_stream_class);
1042 assert(packet_stream_class);
1043
1044 if (event_stream_class != packet_stream_class) {
1045 BT_LOGW("Invalid parameter: packet's stream class and event's stream class differ: "
1046 "event-addr=%p, event-class-name=\"%s\", "
1047 "event-class-id=%" PRId64 ", packet-stream-class-addr=%p, "
1048 "event-stream-class-addr=%p",
1049 event, bt_ctf_event_class_get_name(event->event_class),
1050 bt_ctf_event_class_get_id(event->event_class),
1051 packet_stream_class, event_stream_class);
1052 ret = -1;
1053 goto end;
1054 }
1055 }
1056
1057 bt_get(packet);
1058 BT_MOVE(event->packet, packet);
1059 BT_LOGV("Set event's packet: event-addr=%p, "
1060 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
1061 "packet-addr=%p",
1062 event, bt_ctf_event_class_get_name(event->event_class),
1063 bt_ctf_event_class_get_id(event->event_class), packet);
1064
1065 end:
1066 BT_PUT(stream);
1067 BT_PUT(event_stream_class);
1068 BT_PUT(packet_stream_class);
1069
1070 return ret;
1071 }
1072
1073 BT_HIDDEN
1074 void bt_ctf_event_freeze(struct bt_ctf_event *event)
1075 {
1076 assert(event);
1077
1078 if (event->frozen) {
1079 return;
1080 }
1081
1082 BT_LOGD("Freezing event: addr=%p, "
1083 "event-class-name=\"%s\", event-class-id=%" PRId64,
1084 event, bt_ctf_event_class_get_name(event->event_class),
1085 bt_ctf_event_class_get_id(event->event_class));
1086 bt_ctf_packet_freeze(event->packet);
1087 BT_LOGD_STR("Freezing event's header field.");
1088 bt_ctf_field_freeze(event->event_header);
1089 BT_LOGD_STR("Freezing event's stream event context field.");
1090 bt_ctf_field_freeze(event->stream_event_context);
1091 BT_LOGD_STR("Freezing event's context field.");
1092 bt_ctf_field_freeze(event->context_payload);
1093 BT_LOGD_STR("Freezing event's payload field.");
1094 bt_ctf_field_freeze(event->fields_payload);
1095 event->frozen = 1;
1096 }
This page took 0.051001 seconds and 5 git commands to generate.