Rename bt_ctf_X -> bt_X, maintain backward compat. for pre-2.0 CTF writer
[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>
83509119 51#include <babeltrace/ref.h>
44e0a4f5 52#include <babeltrace/ctf-ir/attributes-internal.h>
3d9990ac 53#include <babeltrace/compiler-internal.h>
7b010242 54#include <inttypes.h>
273b65be 55
273b65be 56static
50842bdc 57void bt_event_destroy(struct bt_object *obj);
273b65be 58
50842bdc 59struct bt_event *bt_event_create(struct bt_event_class *event_class)
273b65be 60{
09840de5 61 int ret;
50842bdc
PP
62 enum bt_validation_flag validation_flags =
63 BT_VALIDATION_FLAG_STREAM |
64 BT_VALIDATION_FLAG_EVENT;
65 struct bt_event *event = NULL;
66 struct bt_trace *trace = NULL;
67 struct bt_stream_class *stream_class = NULL;
68 struct bt_field_type *packet_header_type = NULL;
69 struct bt_field_type *packet_context_type = NULL;
70 struct bt_field_type *event_header_type = NULL;
71 struct bt_field_type *stream_event_ctx_type = NULL;
72 struct bt_field_type *event_context_type = NULL;
73 struct bt_field_type *event_payload_type = NULL;
74 struct bt_field *event_header = NULL;
75 struct bt_field *stream_event_context = NULL;
76 struct bt_field *event_context = NULL;
77 struct bt_field *event_payload = NULL;
09840de5 78 struct bt_value *environment = NULL;
50842bdc 79 struct bt_validation_output validation_output = { 0 };
09840de5 80 int trace_valid = 0;
273b65be 81
7b010242
PP
82 BT_LOGD("Creating event object: event-class-addr=%p, "
83 "event-class-name=\"%s\", event-class-id=%" PRId64,
50842bdc
PP
84 event_class, bt_event_class_get_name(event_class),
85 bt_event_class_get_id(event_class));
7b010242 86
273b65be 87 if (!event_class) {
7b010242 88 BT_LOGW_STR("Invalid parameter: event class is NULL.");
e6a8e8e4 89 goto error;
273b65be
JG
90 }
91
50842bdc 92 stream_class = bt_event_class_get_stream_class(event_class);
09840de5 93
662e778c 94 /*
e6a8e8e4
JG
95 * We disallow the creation of an event if its event class has not been
96 * associated to a stream class.
662e778c 97 */
e6a8e8e4 98 if (!stream_class) {
e0bcd1b0 99 BT_LOGW_STR("Event class is not part of a stream class.");
e6a8e8e4 100 goto error;
662e778c 101 }
09840de5 102
09840de5
PP
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 */
50842bdc 107 trace = bt_stream_class_get_trace(stream_class);
09840de5 108 if (trace) {
e0bcd1b0 109 BT_LOGD_STR("Event's class is part of a trace.");
50842bdc 110 packet_header_type = bt_trace_get_packet_header_type(trace);
09840de5
PP
111 trace_valid = trace->valid;
112 assert(trace_valid);
113 environment = trace->environment;
114 }
115
50842bdc 116 packet_context_type = bt_stream_class_get_packet_context_type(
09840de5 117 stream_class);
50842bdc 118 event_header_type = bt_stream_class_get_event_header_type(
09840de5 119 stream_class);
50842bdc 120 stream_event_ctx_type = bt_stream_class_get_event_context_type(
09840de5 121 stream_class);
50842bdc
PP
122 event_context_type = bt_event_class_get_context_type(event_class);
123 event_payload_type = bt_event_class_get_payload_type(event_class);
124 ret = bt_validate_class_types(environment, packet_header_type,
09840de5
PP
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);
09840de5
PP
135 if (ret) {
136 /*
137 * This means something went wrong during the validation
138 * process, not that the objects are invalid.
139 */
e0bcd1b0 140 BT_LOGE("Failed to validate event and parents: ret=%d", ret);
09840de5
PP
141 goto error;
142 }
143
144 if ((validation_output.valid_flags & validation_flags) !=
145 validation_flags) {
146 /* Invalid trace/stream class/event class */
3ee09f3a 147 BT_LOGW("Invalid trace, stream class, or event class: "
e0bcd1b0 148 "valid-flags=0x%x", validation_output.valid_flags);
09840de5
PP
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 */
50842bdc 158 event = g_new0(struct bt_event, 1);
b8248cc0 159 if (!event) {
7b010242 160 BT_LOGE_STR("Failed to allocate one event.");
e6a8e8e4 161 goto error;
b8248cc0
PP
162 }
163
50842bdc 164 bt_object_init(event, bt_event_destroy);
09840de5 165
e6a8e8e4
JG
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);
41ac640a 174 event->clock_values = g_hash_table_new_full(g_direct_hash,
1556a1af 175 g_direct_equal, bt_put, bt_put);
be514b0c
PP
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 =
50842bdc 181 bt_field_create(validation_output.event_header_type);
be514b0c
PP
182 if (!event_header) {
183 BT_LOGE_STR("Cannot create initial event header field object.");
184 goto error;
185 }
662e778c 186 }
09840de5 187
5fd2e9fd 188 if (validation_output.stream_event_ctx_type) {
be514b0c
PP
189 BT_LOGD("Creating initial stream event context field: ft-addr=%p",
190 validation_output.stream_event_ctx_type);
50842bdc 191 stream_event_context = bt_field_create(
5fd2e9fd
PP
192 validation_output.stream_event_ctx_type);
193 if (!stream_event_context) {
7b010242 194 BT_LOGE_STR("Cannot create initial stream event context field object.");
5fd2e9fd
PP
195 goto error;
196 }
197 }
198
09840de5 199 if (validation_output.event_context_type) {
be514b0c
PP
200 BT_LOGD("Creating initial event context field: ft-addr=%p",
201 validation_output.event_context_type);
50842bdc 202 event_context = bt_field_create(
09840de5
PP
203 validation_output.event_context_type);
204 if (!event_context) {
7b010242 205 BT_LOGE_STR("Cannot create initial event context field object.");
83509119 206 goto error;
662e778c 207 }
f655a84d 208 }
09840de5
PP
209
210 if (validation_output.event_payload_type) {
be514b0c
PP
211 BT_LOGD("Creating initial event payload field: ft-addr=%p",
212 validation_output.event_payload_type);
50842bdc 213 event_payload = bt_field_create(
09840de5
PP
214 validation_output.event_payload_type);
215 if (!event_payload) {
7b010242 216 BT_LOGE_STR("Cannot create initial event payload field object.");
09840de5
PP
217 goto error;
218 }
662e778c
JG
219 }
220
09840de5
PP
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 */
50842bdc 227 bt_validation_replace_types(trace, stream_class,
09840de5
PP
228 event_class, &validation_output, validation_flags);
229 BT_MOVE(event->event_header, event_header);
5fd2e9fd 230 BT_MOVE(event->stream_event_context, stream_event_context);
09840de5
PP
231 BT_MOVE(event->context_payload, event_context);
232 BT_MOVE(event->fields_payload, event_payload);
233
234 /*
50842bdc 235 * Put what was not moved in bt_validation_replace_types().
09840de5 236 */
50842bdc 237 bt_validation_output_put_types(&validation_output);
09840de5 238
662e778c
JG
239 /*
240 * Freeze the stream class since the event header must not be changed
241 * anymore.
242 */
50842bdc 243 bt_stream_class_freeze(stream_class);
09840de5
PP
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 */
e6a8e8e4 253 BT_PUT(stream_class);
09840de5 254 BT_PUT(trace);
7b010242
PP
255 BT_LOGD("Created event object: addr=%p, event-class-name=\"%s\", "
256 "event-class-id=%" PRId64,
50842bdc
PP
257 event, bt_event_class_get_name(event->event_class),
258 bt_event_class_get_id(event_class));
273b65be 259 return event;
09840de5 260
83509119 261error:
50842bdc 262 bt_validation_output_put_types(&validation_output);
83509119 263 BT_PUT(event);
e6a8e8e4 264 BT_PUT(stream_class);
09840de5
PP
265 BT_PUT(trace);
266 BT_PUT(event_header);
5fd2e9fd 267 BT_PUT(stream_event_context);
09840de5
PP
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
83509119 277 return event;
273b65be
JG
278}
279
50842bdc 280struct bt_event_class *bt_event_get_class(struct bt_event *event)
2f100782 281{
50842bdc 282 struct bt_event_class *event_class = NULL;
2f100782
JG
283
284 if (!event) {
7b010242 285 BT_LOGW_STR("Invalid parameter: event is NULL.");
2f100782
JG
286 goto end;
287 }
288
50842bdc 289 event_class = bt_get(bt_event_borrow_event_class(event));
2f100782
JG
290end:
291 return event_class;
292}
293
50842bdc 294struct bt_stream *bt_event_get_stream(struct bt_event *event)
8e5003bb 295{
50842bdc 296 struct bt_stream *stream = NULL;
cacf3147
PP
297
298 if (!event) {
7b010242 299 BT_LOGW_STR("Invalid parameter: event is NULL.");
cacf3147
PP
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) {
50842bdc 309 stream = (struct bt_stream *) bt_object_get_parent(event);
cacf3147
PP
310 } else {
311 if (event->packet) {
312 stream = bt_get(event->packet->stream);
313 }
314 }
315
316end:
317 return stream;
8e5003bb
JG
318}
319
50842bdc 320int bt_event_set_payload(struct bt_event *event,
273b65be 321 const char *name,
50842bdc 322 struct bt_field *payload)
273b65be
JG
323{
324 int ret = 0;
325
7b010242
PP
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,
50842bdc
PP
337 event, bt_event_class_get_name(event->event_class),
338 bt_event_class_get_id(event->event_class));
273b65be
JG
339 ret = -1;
340 goto end;
341 }
342
c5a9aa19 343 if (name) {
50842bdc 344 ret = bt_field_structure_set_field_by_name(
2225de6b 345 event->fields_payload, name, payload);
c5a9aa19 346 } else {
50842bdc 347 struct bt_field_type *payload_type;
c5a9aa19 348
50842bdc 349 payload_type = bt_field_get_type(payload);
09840de5 350
50842bdc 351 if (bt_field_type_compare(payload_type,
09840de5 352 event->event_class->fields) == 0) {
83509119
JG
353 bt_put(event->fields_payload);
354 bt_get(payload);
c5a9aa19
JG
355 event->fields_payload = payload;
356 } else {
7b010242
PP
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,
50842bdc
PP
361 bt_event_class_get_name(event->event_class),
362 bt_event_class_get_id(event->event_class));
c5a9aa19
JG
363 ret = -1;
364 }
365
83509119 366 bt_put(payload_type);
c5a9aa19 367 }
7b010242
PP
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",
50842bdc
PP
373 event, bt_event_class_get_name(event->event_class),
374 bt_event_class_get_id(event->event_class),
7b010242
PP
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",
50842bdc
PP
380 event, bt_event_class_get_name(event->event_class),
381 bt_event_class_get_id(event->event_class),
7b010242
PP
382 name, payload);
383 }
384
273b65be
JG
385end:
386 return ret;
387}
388
50842bdc 389struct bt_field *bt_event_get_event_payload(struct bt_event *event)
71362d53 390{
50842bdc 391 struct bt_field *payload = NULL;
71362d53 392
7b010242
PP
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,
50842bdc
PP
401 event, bt_event_class_get_name(event->event_class),
402 bt_event_class_get_id(event->event_class));
71362d53
PP
403 goto end;
404 }
405
406 payload = event->fields_payload;
83509119 407 bt_get(payload);
71362d53
PP
408end:
409 return payload;
410}
273b65be 411
50842bdc
PP
412int bt_event_set_event_payload(struct bt_event *event,
413 struct bt_field *payload)
e5e6eb3a 414{
50842bdc 415 return bt_event_set_payload(event, NULL, payload);
e5e6eb3a
JG
416}
417
50842bdc 418struct bt_field *bt_event_get_payload(struct bt_event *event,
273b65be
JG
419 const char *name)
420{
50842bdc 421 struct bt_field *field = NULL;
273b65be 422
c5a9aa19 423 if (!event) {
7b010242 424 BT_LOGW_STR("Invalid parameter: event is NULL.");
273b65be
JG
425 goto end;
426 }
427
c5a9aa19 428 if (name) {
50842bdc
PP
429 field = bt_field_structure_get_field_by_name(
430 event->fields_payload, name);
c5a9aa19
JG
431 } else {
432 field = event->fields_payload;
83509119 433 bt_get(field);
c5a9aa19 434 }
273b65be
JG
435end:
436 return field;
437}
438
50842bdc
PP
439struct bt_field *bt_event_get_payload_by_index(
440 struct bt_event *event, uint64_t index)
2f100782 441{
50842bdc 442 struct bt_field *field = NULL;
2f100782 443
9ac68eb1 444 if (!event) {
7b010242 445 BT_LOGW_STR("Invalid parameter: event is NULL.");
2f100782
JG
446 goto end;
447 }
448
50842bdc 449 field = bt_field_structure_get_field_by_index(event->fields_payload,
2f100782
JG
450 index);
451end:
452 return field;
453}
454
50842bdc
PP
455struct bt_field *bt_event_get_header(
456 struct bt_event *event)
662e778c 457{
50842bdc 458 struct bt_field *header = NULL;
662e778c 459
7b010242
PP
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,
50842bdc
PP
468 event, bt_event_class_get_name(event->event_class),
469 bt_event_class_get_id(event->event_class));
662e778c
JG
470 goto end;
471 }
472
473 header = event->event_header;
83509119 474 bt_get(header);
662e778c
JG
475end:
476 return header;
477}
478
50842bdc
PP
479int bt_event_set_header(struct bt_event *event,
480 struct bt_field *header)
662e778c
JG
481{
482 int ret = 0;
50842bdc
PP
483 struct bt_field_type *field_type = NULL;
484 struct bt_stream_class *stream_class = NULL;
662e778c 485
7b010242
PP
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,
50842bdc
PP
495 event, bt_event_class_get_name(event->event_class),
496 bt_event_class_get_id(event->event_class));
662e778c
JG
497 ret = -1;
498 goto end;
499 }
500
50842bdc 501 stream_class = (struct bt_stream_class *) bt_object_get_parent(
835b2d10 502 event->event_class);
662e778c
JG
503 /*
504 * Ensure the provided header's type matches the one registered to the
505 * stream class.
506 */
c5c82c6e 507 if (header) {
50842bdc
PP
508 field_type = bt_field_get_type(header);
509 if (bt_field_type_compare(field_type,
c5c82c6e
PP
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,
50842bdc
PP
515 bt_event_class_get_name(event->event_class),
516 bt_event_class_get_id(event->event_class));
c5c82c6e
PP
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,
50842bdc
PP
527 bt_event_class_get_name(event->event_class),
528 bt_event_class_get_id(event->event_class),
c5c82c6e
PP
529 stream_class->event_header_type);
530 ret = -1;
531 goto end;
532 }
662e778c
JG
533 }
534
83509119 535 bt_put(event->event_header);
835b2d10 536 event->event_header = bt_get(header);
7b010242
PP
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",
50842bdc
PP
540 event, bt_event_class_get_name(event->event_class),
541 bt_event_class_get_id(event->event_class), header);
662e778c 542end:
e6a8e8e4 543 bt_put(stream_class);
83509119 544 bt_put(field_type);
662e778c
JG
545 return ret;
546}
547
50842bdc
PP
548struct bt_field *bt_event_get_event_context(
549 struct bt_event *event)
f655a84d 550{
50842bdc 551 struct bt_field *context = NULL;
f655a84d 552
7b010242
PP
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,
50842bdc
PP
561 event, bt_event_class_get_name(event->event_class),
562 bt_event_class_get_id(event->event_class));
f655a84d
JG
563 goto end;
564 }
565
566 context = event->context_payload;
83509119 567 bt_get(context);
f655a84d
JG
568end:
569 return context;
570}
571
50842bdc
PP
572int bt_event_set_event_context(struct bt_event *event,
573 struct bt_field *context)
f655a84d
JG
574{
575 int ret = 0;
50842bdc 576 struct bt_field_type *field_type = NULL;
f655a84d 577
7b010242
PP
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,
50842bdc
PP
587 event, bt_event_class_get_name(event->event_class),
588 bt_event_class_get_id(event->event_class));
f655a84d
JG
589 ret = -1;
590 goto end;
591 }
592
c5c82c6e 593 if (context) {
50842bdc 594 field_type = bt_field_get_type(context);
c5c82c6e 595
50842bdc 596 if (bt_field_type_compare(field_type,
c5c82c6e
PP
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,
50842bdc
PP
602 bt_event_class_get_name(event->event_class),
603 bt_event_class_get_id(event->event_class));
c5c82c6e
PP
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,
50842bdc
PP
614 bt_event_class_get_name(event->event_class),
615 bt_event_class_get_id(event->event_class),
c5c82c6e
PP
616 event->event_class->context);
617 ret = -1;
618 goto end;
619 }
f655a84d
JG
620 }
621
83509119 622 bt_put(event->context_payload);
835b2d10 623 event->context_payload = bt_get(context);
7b010242
PP
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",
50842bdc
PP
627 event, bt_event_class_get_name(event->event_class),
628 bt_event_class_get_id(event->event_class), context);
f655a84d 629end:
83509119 630 bt_put(field_type);
f655a84d
JG
631 return ret;
632}
633
50842bdc
PP
634struct bt_field *bt_event_get_stream_event_context(
635 struct bt_event *event)
5fd2e9fd 636{
50842bdc 637 struct bt_field *stream_event_context = NULL;
5fd2e9fd 638
7b010242
PP
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,
50842bdc
PP
647 event, bt_event_class_get_name(event->event_class),
648 bt_event_class_get_id(event->event_class));
5fd2e9fd
PP
649 goto end;
650 }
651
652 stream_event_context = event->stream_event_context;
653end:
654 return bt_get(stream_event_context);
655}
656
50842bdc
PP
657int bt_event_set_stream_event_context(struct bt_event *event,
658 struct bt_field *stream_event_context)
5fd2e9fd
PP
659{
660 int ret = 0;
50842bdc
PP
661 struct bt_field_type *field_type = NULL;
662 struct bt_stream_class *stream_class = NULL;
5fd2e9fd 663
7b010242
PP
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,
50842bdc
PP
673 event, bt_event_class_get_name(event->event_class),
674 bt_event_class_get_id(event->event_class));
5fd2e9fd
PP
675 ret = -1;
676 goto end;
677 }
678
50842bdc 679 stream_class = bt_event_class_get_stream_class(event->event_class);
5fd2e9fd
PP
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
c5c82c6e 686 if (stream_event_context) {
50842bdc
PP
687 field_type = bt_field_get_type(stream_event_context);
688 if (bt_field_type_compare(field_type,
c5c82c6e
PP
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,
50842bdc
PP
694 bt_event_class_get_name(event->event_class),
695 bt_event_class_get_id(event->event_class));
c5c82c6e
PP
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,
50842bdc
PP
706 bt_event_class_get_name(event->event_class),
707 bt_event_class_get_id(event->event_class),
c5c82c6e
PP
708 stream_class->event_context_type);
709 ret = -1;
710 goto end;
711 }
5fd2e9fd
PP
712 }
713
714 bt_get(stream_event_context);
715 BT_MOVE(event->stream_event_context, stream_event_context);
7b010242
PP
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",
50842bdc
PP
719 event, bt_event_class_get_name(event->event_class),
720 bt_event_class_get_id(event->event_class),
7b010242 721 stream_event_context);
5fd2e9fd
PP
722end:
723 BT_PUT(stream_class);
724 bt_put(field_type);
725 return ret;
726}
727
7b010242 728/* Pre-2.0 CTF writer backward compatibility */
50842bdc 729void bt_ctf_event_get(struct bt_event *event)
273b65be 730{
83509119 731 bt_get(event);
273b65be
JG
732}
733
7b010242 734/* Pre-2.0 CTF writer backward compatibility */
50842bdc 735void bt_ctf_event_put(struct bt_event *event)
273b65be 736{
83509119 737 bt_put(event);
273b65be
JG
738}
739
50842bdc 740void bt_event_destroy(struct bt_object *obj)
273b65be 741{
50842bdc 742 struct bt_event *event;
273b65be 743
50842bdc 744 event = container_of(obj, struct bt_event, base);
7b010242
PP
745 BT_LOGD("Destroying event: addr=%p, "
746 "event-class-name=\"%s\", event-class-id=%" PRId64,
50842bdc
PP
747 event, bt_event_class_get_name(event->event_class),
748 bt_event_class_get_id(event->event_class));
7b010242 749
e6a8e8e4
JG
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 }
41ac640a 758 g_hash_table_destroy(event->clock_values);
03039f21 759 BT_LOGD_STR("Putting event's header field.");
83509119 760 bt_put(event->event_header);
03039f21 761 BT_LOGD_STR("Putting event's stream event context field.");
5fd2e9fd 762 bt_put(event->stream_event_context);
03039f21 763 BT_LOGD_STR("Putting event's context field.");
83509119 764 bt_put(event->context_payload);
03039f21 765 BT_LOGD_STR("Putting event's payload field.");
83509119 766 bt_put(event->fields_payload);
03039f21 767 BT_LOGD_STR("Putting event's packet.");
5c3b707d 768 bt_put(event->packet);
273b65be
JG
769 g_free(event);
770}
771
50842bdc
PP
772struct bt_clock_value *bt_event_get_clock_value(
773 struct bt_event *event, struct bt_clock_class *clock_class)
78586d8a 774{
50842bdc 775 struct bt_clock_value *clock_value = NULL;
78586d8a 776
ac0c6bdd 777 if (!event || !clock_class) {
7b010242
PP
778 BT_LOGW("Invalid parameter: event or clock class is NULL: "
779 "event-addr=%p, clock-class-addr=%p",
780 event, clock_class);
78586d8a
JG
781 goto end;
782 }
783
ac0c6bdd 784 clock_value = g_hash_table_lookup(event->clock_values, clock_class);
78586d8a 785 if (!clock_value) {
7b010242
PP
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,
50842bdc
PP
790 bt_event_class_get_name(event->event_class),
791 bt_event_class_get_id(event->event_class),
792 clock_class, bt_clock_class_get_name(clock_class));
78586d8a
JG
793 goto end;
794 }
795
1556a1af
JG
796 bt_get(clock_value);
797end:
798 return clock_value;
799}
800
50842bdc
PP
801int bt_event_set_clock_value(struct bt_event *event,
802 struct bt_clock_value *value)
662e778c
JG
803{
804 int ret = 0;
50842bdc
PP
805 struct bt_trace *trace;
806 struct bt_stream_class *stream_class;
807 struct bt_event_class *event_class;
808 struct bt_clock_class *clock_class = NULL;
662e778c 809
7b010242
PP
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,
50842bdc
PP
821 event, bt_event_class_get_name(event->event_class),
822 bt_event_class_get_id(event->event_class));
662e778c
JG
823 ret = -1;
824 goto end;
825 }
826
50842bdc
PP
827 clock_class = bt_clock_value_get_class(value);
828 event_class = bt_event_borrow_event_class(event);
c9d90a34 829 assert(event_class);
50842bdc 830 stream_class = bt_event_class_borrow_stream_class(event_class);
c9d90a34 831 assert(stream_class);
50842bdc 832 trace = bt_stream_class_borrow_trace(stream_class);
c9d90a34
PP
833 assert(trace);
834
50842bdc 835 if (!bt_trace_has_clock_class(trace, clock_class)) {
7b010242
PP
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\"",
50842bdc
PP
840 event, bt_event_class_get_name(event->event_class),
841 bt_event_class_get_id(event->event_class),
842 clock_class, bt_clock_class_get_name(clock_class));
c9d90a34
PP
843 ret = -1;
844 goto end;
845 }
846
847 g_hash_table_insert(event->clock_values, clock_class, bt_get(value));
7b010242
PP
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,
50842bdc
PP
853 event, bt_event_class_get_name(event->event_class),
854 bt_event_class_get_id(event->event_class),
855 clock_class, bt_clock_class_get_name(clock_class),
7b010242 856 value, value->value);
c9d90a34
PP
857 clock_class = NULL;
858
662e778c 859end:
c9d90a34 860 bt_put(clock_class);
662e778c
JG
861 return ret;
862}
863
273b65be 864BT_HIDDEN
50842bdc 865int bt_event_validate(struct bt_event *event)
273b65be
JG
866{
867 /* Make sure each field's payload has been set */
868 int ret;
50842bdc 869 struct bt_stream_class *stream_class = NULL;
273b65be
JG
870
871 assert(event);
06b019a7 872 if (event->event_header) {
50842bdc 873 ret = bt_field_validate(event->event_header);
06b019a7
JD
874 if (ret) {
875 BT_LOGD("Invalid event's header field: "
876 "event-addr=%p, event-class-name=\"%s\", "
877 "event-class-id=%" PRId64,
50842bdc
PP
878 event, bt_event_class_get_name(event->event_class),
879 bt_event_class_get_id(event->event_class));
06b019a7
JD
880 goto end;
881 }
662e778c
JG
882 }
883
50842bdc 884 stream_class = bt_event_class_get_stream_class(event->event_class);
5fd2e9fd
PP
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) {
50842bdc 891 ret = bt_field_validate(event->stream_event_context);
5fd2e9fd 892 if (ret) {
7b010242
PP
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,
50842bdc
PP
897 bt_event_class_get_name(event->event_class),
898 bt_event_class_get_id(event->event_class));
5fd2e9fd
PP
899 goto end;
900 }
901 }
902
50842bdc 903 ret = bt_field_validate(event->fields_payload);
273b65be 904 if (ret) {
7b010242
PP
905 BT_LOGD("Invalid event's payload field: "
906 "event-addr=%p, event-class-name=\"%s\", "
907 "event-class-id=%" PRId64,
908 event,
50842bdc
PP
909 bt_event_class_get_name(event->event_class),
910 bt_event_class_get_id(event->event_class));
273b65be
JG
911 goto end;
912 }
913
914 if (event->event_class->context) {
7b010242
PP
915 BT_LOGD("Invalid event's context field: "
916 "event-addr=%p, event-class-name=\"%s\", "
917 "event-class-id=%" PRId64,
918 event,
50842bdc
PP
919 bt_event_class_get_name(event->event_class),
920 bt_event_class_get_id(event->event_class));
921 ret = bt_field_validate(event->context_payload);
273b65be
JG
922 }
923end:
5fd2e9fd 924 bt_put(stream_class);
273b65be
JG
925 return ret;
926}
927
928BT_HIDDEN
50842bdc
PP
929int bt_event_serialize(struct bt_event *event,
930 struct bt_stream_pos *pos,
931 enum bt_byte_order native_byte_order)
273b65be
JG
932{
933 int ret = 0;
934
935 assert(event);
936 assert(pos);
dc3fffef 937
ffffc526 938 BT_LOGV_STR("Serializing event's context field.");
273b65be 939 if (event->context_payload) {
50842bdc 940 ret = bt_field_serialize(event->context_payload, pos,
dc3fffef 941 native_byte_order);
273b65be 942 if (ret) {
3ee09f3a 943 BT_LOGW("Cannot serialize event's context field: "
7b010242
PP
944 "event-addr=%p, event-class-name=\"%s\", "
945 "event-class-id=%" PRId64,
946 event,
50842bdc
PP
947 bt_event_class_get_name(event->event_class),
948 bt_event_class_get_id(event->event_class));
273b65be
JG
949 goto end;
950 }
951 }
952
ffffc526 953 BT_LOGV_STR("Serializing event's payload field.");
273b65be 954 if (event->fields_payload) {
50842bdc 955 ret = bt_field_serialize(event->fields_payload, pos,
dc3fffef 956 native_byte_order);
273b65be 957 if (ret) {
3ee09f3a 958 BT_LOGW("Cannot serialize event's payload field: "
7b010242
PP
959 "event-addr=%p, event-class-name=\"%s\", "
960 "event-class-id=%" PRId64,
961 event,
50842bdc
PP
962 bt_event_class_get_name(event->event_class),
963 bt_event_class_get_id(event->event_class));
273b65be
JG
964 goto end;
965 }
966 }
967end:
968 return ret;
969}
970
50842bdc 971struct bt_packet *bt_event_get_packet(struct bt_event *event)
5c0f40f4 972{
50842bdc 973 struct bt_packet *packet = NULL;
5c0f40f4 974
7b010242
PP
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,
50842bdc
PP
983 event, bt_event_class_get_name(event->event_class),
984 bt_event_class_get_id(event->event_class));
5c0f40f4
JG
985 goto end;
986 }
987
988 packet = bt_get(event->packet);
989end:
990 return packet;
991}
992
50842bdc
PP
993int bt_event_set_packet(struct bt_event *event,
994 struct bt_packet *packet)
5c3b707d 995{
50842bdc
PP
996 struct bt_stream_class *event_stream_class = NULL;
997 struct bt_stream_class *packet_stream_class = NULL;
998 struct bt_stream *stream = NULL;
5c3b707d
PP
999 int ret = 0;
1000
7b010242
PP
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,
50842bdc
PP
1012 event, bt_event_class_get_name(event->event_class),
1013 bt_event_class_get_id(event->event_class));
5c3b707d
PP
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 */
50842bdc 1022 stream = bt_event_get_stream(event);
5c3b707d
PP
1023 if (stream) {
1024 if (packet->stream != stream) {
7b010242
PP
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",
50842bdc
PP
1029 event, bt_event_class_get_name(event->event_class),
1030 bt_event_class_get_id(event->event_class),
7b010242 1031 packet->stream, stream);
5c3b707d
PP
1032 ret = -1;
1033 goto end;
1034 }
1035 } else {
b2b635e9 1036 event_stream_class =
50842bdc 1037 bt_event_class_get_stream_class(event->event_class);
b2b635e9 1038 packet_stream_class =
50842bdc 1039 bt_stream_get_class(packet->stream);
b2b635e9
PP
1040
1041 assert(event_stream_class);
1042 assert(packet_stream_class);
1043
1044 if (event_stream_class != packet_stream_class) {
7b010242
PP
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",
50842bdc
PP
1049 event, bt_event_class_get_name(event->event_class),
1050 bt_event_class_get_id(event->event_class),
7b010242 1051 packet_stream_class, event_stream_class);
b2b635e9
PP
1052 ret = -1;
1053 goto end;
1054 }
5c3b707d
PP
1055 }
1056
cacf3147
PP
1057 bt_get(packet);
1058 BT_MOVE(event->packet, packet);
7b010242
PP
1059 BT_LOGV("Set event's packet: event-addr=%p, "
1060 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
1061 "packet-addr=%p",
50842bdc
PP
1062 event, bt_event_class_get_name(event->event_class),
1063 bt_event_class_get_id(event->event_class), packet);
5c3b707d
PP
1064
1065end:
1066 BT_PUT(stream);
b2b635e9
PP
1067 BT_PUT(event_stream_class);
1068 BT_PUT(packet_stream_class);
5c3b707d
PP
1069
1070 return ret;
1071}
4ce9f9d0
PP
1072
1073BT_HIDDEN
50842bdc 1074void bt_event_freeze(struct bt_event *event)
4ce9f9d0
PP
1075{
1076 assert(event);
7b010242
PP
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,
50842bdc
PP
1084 event, bt_event_class_get_name(event->event_class),
1085 bt_event_class_get_id(event->event_class));
1086 bt_packet_freeze(event->packet);
03039f21 1087 BT_LOGD_STR("Freezing event's header field.");
50842bdc 1088 bt_field_freeze(event->event_header);
03039f21 1089 BT_LOGD_STR("Freezing event's stream event context field.");
50842bdc 1090 bt_field_freeze(event->stream_event_context);
03039f21 1091 BT_LOGD_STR("Freezing event's context field.");
50842bdc 1092 bt_field_freeze(event->context_payload);
03039f21 1093 BT_LOGD_STR("Freezing event's payload field.");
50842bdc 1094 bt_field_freeze(event->fields_payload);
4ce9f9d0
PP
1095 event->frozen = 1;
1096}
This page took 0.102207 seconds and 4 git commands to generate.