lib: merge common CTF IR part with the remaining implementation
[babeltrace.git] / lib / ctf-ir / event-class.c
CommitLineData
272df73e
PP
1/*
2 * event-class.c
3 *
4 * Babeltrace CTF IR - Event class
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
f8b979f9
PP
29#define BT_LOG_TAG "EVENT-CLASS"
30#include <babeltrace/lib-logging-internal.h>
31
3dca2276 32#include <babeltrace/assert-pre-internal.h>
312c056a 33#include <babeltrace/ctf-ir/clock-value-internal.h>
272df73e
PP
34#include <babeltrace/ctf-ir/fields-internal.h>
35#include <babeltrace/ctf-ir/field-types-internal.h>
36#include <babeltrace/ctf-ir/event-class.h>
37#include <babeltrace/ctf-ir/event-class-internal.h>
312c056a 38#include <babeltrace/ctf-ir/event-internal.h>
272df73e
PP
39#include <babeltrace/ctf-ir/stream-class.h>
40#include <babeltrace/ctf-ir/stream-class-internal.h>
41#include <babeltrace/ctf-ir/trace-internal.h>
42#include <babeltrace/ctf-ir/validation-internal.h>
43#include <babeltrace/ctf-ir/utils.h>
2a3ced3c 44#include <babeltrace/ctf-ir/utils-internal.h>
272df73e
PP
45#include <babeltrace/ref.h>
46#include <babeltrace/ctf-ir/attributes-internal.h>
3d9990ac
PP
47#include <babeltrace/compiler-internal.h>
48#include <babeltrace/endian-internal.h>
c55a9f58 49#include <babeltrace/types.h>
f8b979f9 50#include <babeltrace/values-internal.h>
f6ccaed9 51#include <babeltrace/assert-internal.h>
dc3fffef 52#include <inttypes.h>
0fbb9a9f 53#include <stdlib.h>
272df73e 54
cb6f1f7d
PP
55static inline
56void bt_event_class_finalize(struct bt_object *obj)
272df73e 57{
cb6f1f7d 58 struct bt_event_class *event_class;
272df73e 59
cb6f1f7d
PP
60 event_class = container_of(obj, struct bt_event_class, base);
61 BT_LOGD("Finalizing event class: addr=%p, name=\"%s\", id=%" PRId64,
62 event_class, bt_event_class_get_name(event_class),
63 bt_event_class_get_id(event_class));
f8b979f9 64
3dca2276
PP
65 if (event_class->name) {
66 g_string_free(event_class->name, TRUE);
cf76ce92
PP
67 }
68
3dca2276
PP
69 if (event_class->emf_uri) {
70 g_string_free(event_class->emf_uri, TRUE);
272df73e
PP
71 }
72
3dca2276
PP
73 BT_LOGD_STR("Putting context field type.");
74 bt_put(event_class->context_field_type);
75 BT_LOGD_STR("Putting payload field type.");
76 bt_put(event_class->payload_field_type);
77}
78
cb6f1f7d
PP
79static inline
80int bt_event_class_initialize(struct bt_event_class *event_class,
3dca2276
PP
81 const char *name, bt_object_release_func release_func,
82 bt_field_type_structure_create_func ft_struct_create_func)
83{
84 int ret = 0;
85
cb6f1f7d 86 BT_LOGD("Initializing event class object: name=\"%s\"",
3dca2276 87 name);
3fea54f6 88 bt_object_init_shared_with_parent(&event_class->base, release_func);
3dca2276
PP
89 event_class->payload_field_type = ft_struct_create_func();
90 if (!event_class->payload_field_type) {
f8b979f9 91 BT_LOGE_STR("Cannot create event class's initial payload field type object.");
272df73e
PP
92 goto error;
93 }
94
cf76ce92
PP
95 event_class->id = -1;
96 event_class->name = g_string_new(name);
97 if (!event_class->name) {
98 BT_LOGE_STR("Failed to allocate a GString.");
272df73e
PP
99 goto error;
100 }
101
cf76ce92
PP
102 event_class->emf_uri = g_string_new(NULL);
103 if (!event_class->emf_uri) {
104 BT_LOGE_STR("Failed to allocate a GString.");
272df73e
PP
105 goto error;
106 }
107
50842bdc 108 event_class->log_level = BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED;
cb6f1f7d
PP
109 BT_LOGD("Initialized event class object: addr=%p, name=\"%s\"",
110 event_class, bt_event_class_get_name(event_class));
3dca2276 111 return ret;
272df73e
PP
112
113error:
3dca2276 114 ret = -1;
272df73e
PP
115 return ret;
116}
117
3dca2276
PP
118static
119void bt_event_class_destroy(struct bt_object *obj)
272df73e 120{
312c056a
PP
121 struct bt_event_class *event_class = (void *) obj;
122
3dca2276 123 BT_LOGD("Destroying event class: addr=%p", obj);
cb6f1f7d 124 bt_event_class_finalize(obj);
312c056a 125 bt_object_pool_finalize(&event_class->event_pool);
3dca2276 126 g_free(obj);
272df73e
PP
127}
128
312c056a
PP
129static
130void free_event(struct bt_event *event,
131 struct bt_event_class *event_class)
132{
133 bt_event_destroy(event);
134}
135
3dca2276 136struct bt_event_class *bt_event_class_create(const char *name)
272df73e 137{
3dca2276
PP
138 int ret;
139 struct bt_event_class *event_class = NULL;
272df73e 140
3dca2276
PP
141 if (!name) {
142 BT_LOGW_STR("Invalid parameter: name is NULL.");
143 goto error;
cf76ce92 144 }
272df73e 145
3dca2276
PP
146 BT_LOGD("Creating event class object: name=\"%s\"",
147 name);
148 event_class = g_new0(struct bt_event_class, 1);
272df73e 149 if (!event_class) {
3dca2276
PP
150 BT_LOGE_STR("Failed to allocate one event class.");
151 goto error;
272df73e
PP
152 }
153
cb6f1f7d 154 ret = bt_event_class_initialize(event_class,
3dca2276
PP
155 name, bt_event_class_destroy,
156 (bt_field_type_structure_create_func)
157 bt_field_type_structure_create);
158 if (ret) {
159 goto error;
272df73e
PP
160 }
161
312c056a
PP
162 ret = bt_object_pool_initialize(&event_class->event_pool,
163 (bt_object_pool_new_object_func) bt_event_new,
164 (bt_object_pool_destroy_object_func) free_event,
165 event_class);
166 if (ret) {
167 BT_LOGE("Failed to initialize event pool: ret=%d",
168 ret);
169 goto error;
170 }
171
3dca2276
PP
172 BT_LOGD("Created event class object: addr=%p, name=\"%s\"",
173 event_class, bt_event_class_get_name(event_class));
174 goto end;
272df73e 175
3dca2276
PP
176error:
177 bt_put(event_class);
272df73e
PP
178
179end:
3dca2276 180 return event_class;
272df73e
PP
181}
182
3dca2276 183const char *bt_event_class_get_name(struct bt_event_class *event_class)
272df73e 184{
cb6f1f7d
PP
185 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
186 BT_ASSERT(event_class->name);
187 return event_class->name->str;
272df73e
PP
188}
189
3dca2276 190int64_t bt_event_class_get_id(struct bt_event_class *event_class)
272df73e 191{
cb6f1f7d
PP
192 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
193 return event_class->id;
272df73e
PP
194}
195
cb6f1f7d
PP
196int bt_event_class_set_id(struct bt_event_class *event_class,
197 uint64_t id_param)
272df73e 198{
cb6f1f7d
PP
199 int ret = 0;
200 int64_t id = (int64_t) id_param;
201
202 if (!event_class) {
203 BT_LOGW_STR("Invalid parameter: event class is NULL.");
204 ret = -1;
205 goto end;
206 }
207
208 if (event_class->frozen) {
209 BT_LOGW("Invalid parameter: event class is frozen: "
210 "addr=%p, name=\"%s\", id=%" PRId64,
211 event_class,
212 bt_event_class_get_name(event_class),
213 bt_event_class_get_id(event_class));
214 ret = -1;
215 goto end;
216 }
217
218 if (id < 0) {
219 BT_LOGW("Invalid parameter: invalid event class's ID: "
220 "addr=%p, name=\"%s\", id=%" PRIu64,
221 event_class,
222 bt_event_class_get_name(event_class),
223 id_param);
224 ret = -1;
225 goto end;
226 }
227
228 event_class->id = id;
229 BT_LOGV("Set event class's ID: "
230 "addr=%p, name=\"%s\", id=%" PRId64,
231 event_class, bt_event_class_get_name(event_class), id);
232
233end:
234 return ret;
272df73e
PP
235}
236
3dca2276
PP
237enum bt_event_class_log_level bt_event_class_get_log_level(
238 struct bt_event_class *event_class)
272df73e 239{
cb6f1f7d
PP
240 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
241 return event_class->log_level;
272df73e
PP
242}
243
3dca2276
PP
244int bt_event_class_set_log_level(struct bt_event_class *event_class,
245 enum bt_event_class_log_level log_level)
272df73e 246{
cb6f1f7d
PP
247 int ret = 0;
248
249 if (!event_class) {
250 BT_LOGW_STR("Invalid parameter: event class is NULL.");
251 ret = -1;
252 goto end;
253 }
254
255 if (event_class->frozen) {
256 BT_LOGW("Invalid parameter: event class is frozen: "
257 "addr=%p, name=\"%s\", id=%" PRId64,
258 event_class,
259 bt_event_class_get_name(event_class),
260 bt_event_class_get_id(event_class));
261 ret = -1;
262 goto end;
263 }
264
265 switch (log_level) {
266 case BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED:
267 case BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY:
268 case BT_EVENT_CLASS_LOG_LEVEL_ALERT:
269 case BT_EVENT_CLASS_LOG_LEVEL_CRITICAL:
270 case BT_EVENT_CLASS_LOG_LEVEL_ERROR:
271 case BT_EVENT_CLASS_LOG_LEVEL_WARNING:
272 case BT_EVENT_CLASS_LOG_LEVEL_NOTICE:
273 case BT_EVENT_CLASS_LOG_LEVEL_INFO:
274 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM:
275 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM:
276 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS:
277 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE:
278 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT:
279 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION:
280 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE:
281 case BT_EVENT_CLASS_LOG_LEVEL_DEBUG:
282 break;
283 default:
284 BT_LOGW("Invalid parameter: unknown event class log level: "
285 "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%d",
286 event_class, bt_event_class_get_name(event_class),
287 bt_event_class_get_id(event_class), log_level);
288 ret = -1;
289 goto end;
290 }
291
292 event_class->log_level = log_level;
293 BT_LOGV("Set event class's log level: "
294 "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%s",
295 event_class, bt_event_class_get_name(event_class),
296 bt_event_class_get_id(event_class),
297 bt_common_event_class_log_level_string(log_level));
298
299end:
300 return ret;
272df73e
PP
301}
302
3dca2276 303const char *bt_event_class_get_emf_uri(struct bt_event_class *event_class)
272df73e 304{
cb6f1f7d
PP
305 const char *emf_uri = NULL;
306
307 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
308
309 if (event_class->emf_uri->len > 0) {
310 emf_uri = event_class->emf_uri->str;
311 }
312
313 return emf_uri;
272df73e
PP
314}
315
3dca2276
PP
316int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
317 const char *emf_uri)
272df73e 318{
cb6f1f7d
PP
319 int ret = 0;
320
321 if (!event_class) {
322 BT_LOGW_STR("Invalid parameter: event class is NULL.");
323 ret = -1;
324 goto end;
325 }
326
327 if (emf_uri && strlen(emf_uri) == 0) {
328 BT_LOGW_STR("Invalid parameter: EMF URI is empty.");
329 ret = -1;
330 goto end;
331 }
332
333 if (event_class->frozen) {
334 BT_LOGW("Invalid parameter: event class is frozen: "
335 "addr=%p, name=\"%s\", id=%" PRId64,
336 event_class, bt_event_class_get_name(event_class),
337 bt_event_class_get_id(event_class));
338 ret = -1;
339 goto end;
340 }
341
342 if (emf_uri) {
343 g_string_assign(event_class->emf_uri, emf_uri);
344 BT_LOGV("Set event class's EMF URI: "
345 "addr=%p, name=\"%s\", id=%" PRId64 ", emf-uri=\"%s\"",
346 event_class, bt_event_class_get_name(event_class),
347 bt_event_class_get_id(event_class), emf_uri);
348 } else {
349 g_string_assign(event_class->emf_uri, "");
350 BT_LOGV("Reset event class's EMF URI: "
351 "addr=%p, name=\"%s\", id=%" PRId64,
352 event_class, bt_event_class_get_name(event_class),
353 bt_event_class_get_id(event_class));
354 }
355
356end:
357 return ret;
272df73e
PP
358}
359
094ff7c0 360struct bt_stream_class *bt_event_class_borrow_stream_class(
50842bdc 361 struct bt_event_class *event_class)
272df73e 362{
d975f66c 363 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
cb6f1f7d 364 return (void *) bt_object_borrow_parent(&event_class->base);
272df73e
PP
365}
366
094ff7c0 367struct bt_field_type *bt_event_class_borrow_payload_field_type(
3dca2276 368 struct bt_event_class *event_class)
272df73e 369{
cb6f1f7d
PP
370 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
371 return event_class->payload_field_type;
272df73e
PP
372}
373
3dca2276
PP
374int bt_event_class_set_payload_field_type(struct bt_event_class *event_class,
375 struct bt_field_type *field_type)
272df73e 376{
cb6f1f7d
PP
377 int ret = 0;
378
379 if (!event_class) {
380 BT_LOGW_STR("Invalid parameter: event class is NULL.");
381 ret = -1;
382 goto end;
383 }
384
385 if (field_type && bt_field_type_get_type_id(field_type) !=
386 BT_FIELD_TYPE_ID_STRUCT) {
387 BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
388 "addr=%p, name=\"%s\", id=%" PRId64 ", "
389 "payload-ft-addr=%p, payload-ft-id=%s",
390 event_class, bt_event_class_get_name(event_class),
391 bt_event_class_get_id(event_class), field_type,
392 bt_common_field_type_id_string(
393 bt_field_type_get_type_id(field_type)));
394 ret = -1;
395 goto end;
396 }
397
398 bt_put(event_class->payload_field_type);
399 event_class->payload_field_type = bt_get(field_type);
400 BT_LOGV("Set event class's payload field type: "
401 "event-class-addr=%p, event-class-name=\"%s\", "
402 "event-class-id=%" PRId64 ", payload-ft-addr=%p",
403 event_class, bt_event_class_get_name(event_class),
404 bt_event_class_get_id(event_class), field_type);
405end:
406 return ret;
272df73e
PP
407}
408
094ff7c0 409struct bt_field_type *bt_event_class_borrow_context_field_type(
3dca2276 410 struct bt_event_class *event_class)
272df73e 411{
cb6f1f7d
PP
412 struct bt_field_type *context_ft = NULL;
413
414 BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
415
416 if (!event_class->context_field_type) {
417 BT_LOGV("Event class has no context field type: "
418 "addr=%p, name=\"%s\", id=%" PRId64,
419 event_class, bt_event_class_get_name(event_class),
420 bt_event_class_get_id(event_class));
421 goto end;
422 }
423
424 context_ft = event_class->context_field_type;
425
426end:
427 return context_ft;
272df73e
PP
428}
429
3dca2276
PP
430int bt_event_class_set_context_field_type(
431 struct bt_event_class *event_class,
432 struct bt_field_type *field_type)
272df73e 433{
cb6f1f7d
PP
434 int ret = 0;
435
436 if (!event_class) {
437 BT_LOGW_STR("Invalid parameter: event class is NULL.");
438 ret = -1;
439 goto end;
440 }
441
442 if (event_class->frozen) {
443 BT_LOGW("Invalid parameter: event class is frozen: "
444 "addr=%p, name=\"%s\", id=%" PRId64,
445 event_class, bt_event_class_get_name(event_class),
446 bt_event_class_get_id(event_class));
447 ret = -1;
448 goto end;
449 }
450
451 if (field_type && bt_field_type_get_type_id(field_type) !=
452 BT_FIELD_TYPE_ID_STRUCT) {
453 BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
454 "addr=%p, name=\"%s\", id=%" PRId64 ", "
455 "context-ft-id=%s",
456 event_class, bt_event_class_get_name(event_class),
457 bt_event_class_get_id(event_class),
458 bt_common_field_type_id_string(
459 bt_field_type_get_type_id(field_type)));
460 ret = -1;
461 goto end;
462 }
463
464 bt_put(event_class->context_field_type);
465 event_class->context_field_type = bt_get(field_type);
466 BT_LOGV("Set event class's context field type: "
467 "event-class-addr=%p, event-class-name=\"%s\", "
468 "event-class-id=%" PRId64 ", context-ft-addr=%p",
469 event_class, bt_event_class_get_name(event_class),
470 bt_event_class_get_id(event_class), field_type);
471
472end:
473 return ret;
272df73e
PP
474}
475
476BT_HIDDEN
cb6f1f7d 477void bt_event_class_freeze(struct bt_event_class *event_class)
272df73e 478{
f6ccaed9 479 BT_ASSERT(event_class);
f8b979f9
PP
480
481 if (event_class->frozen) {
482 return;
483 }
484
485 BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64,
cb6f1f7d
PP
486 event_class, bt_event_class_get_name(event_class),
487 bt_event_class_get_id(event_class));
272df73e 488 event_class->frozen = 1;
0352f8fa 489 BT_LOGD_STR("Freezing event class's context field type.");
cb6f1f7d 490 bt_field_type_freeze(event_class->context_field_type);
0352f8fa 491 BT_LOGD_STR("Freezing event class's payload field type.");
cb6f1f7d 492 bt_field_type_freeze(event_class->payload_field_type);
272df73e 493}
2a3ced3c
PP
494
495BT_HIDDEN
cb6f1f7d
PP
496int bt_event_class_validate_single_clock_class(
497 struct bt_event_class *event_class,
2a3ced3c
PP
498 struct bt_clock_class **expected_clock_class)
499{
500 int ret = 0;
501
f6ccaed9
PP
502 BT_ASSERT(event_class);
503 BT_ASSERT(expected_clock_class);
cb6f1f7d 504 ret = bt_field_type_validate_single_clock_class(
3dca2276 505 event_class->context_field_type,
2a3ced3c
PP
506 expected_clock_class);
507 if (ret) {
508 BT_LOGW("Event class's context field type "
509 "is not recursively mapped to the "
510 "expected clock class: "
511 "event-class-addr=%p, "
512 "event-class-name=\"%s\", "
513 "event-class-id=%" PRId64 ", "
514 "ft-addr=%p",
515 event_class,
cb6f1f7d 516 bt_event_class_get_name(event_class),
2a3ced3c 517 event_class->id,
3dca2276 518 event_class->context_field_type);
2a3ced3c
PP
519 goto end;
520 }
521
cb6f1f7d 522 ret = bt_field_type_validate_single_clock_class(
3dca2276 523 event_class->payload_field_type,
2a3ced3c
PP
524 expected_clock_class);
525 if (ret) {
526 BT_LOGW("Event class's payload field type "
527 "is not recursively mapped to the "
528 "expected clock class: "
529 "event-class-addr=%p, "
530 "event-class-name=\"%s\", "
531 "event-class-id=%" PRId64 ", "
532 "ft-addr=%p",
533 event_class,
cb6f1f7d 534 bt_event_class_get_name(event_class),
2a3ced3c 535 event_class->id,
3dca2276 536 event_class->payload_field_type);
2a3ced3c
PP
537 goto end;
538 }
539
540end:
541 return ret;
542}
This page took 0.066071 seconds and 4 git commands to generate.