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