1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
3 * lttng-event-notifier-notification.c
5 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
10 #include <lttng/lttng-bytecode.h>
11 #include <lttng/events.h>
12 #include <lttng/msgpack.h>
13 #include <lttng/event-notifier-notification.h>
16 int capture_enum(struct lttng_msgpack_writer
*writer
,
17 struct lttng_interpreter_output
*output
) __attribute__ ((unused
));
19 int capture_enum(struct lttng_msgpack_writer
*writer
,
20 struct lttng_interpreter_output
*output
)
25 * Enums are captured as a map containing 2 key-value pairs. Such as:
29 ret
= lttng_msgpack_begin_map(writer
, 2);
35 ret
= lttng_msgpack_write_str(writer
, "type");
41 ret
= lttng_msgpack_write_str(writer
, "enum");
47 ret
= lttng_msgpack_write_str(writer
, "value");
53 switch (output
->type
) {
54 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
55 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
61 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
62 ret
= lttng_msgpack_write_signed_integer(writer
, output
->u
.u
);
72 ret
= lttng_msgpack_end_map(writer
);
81 int64_t capture_sequence_element_signed(uint8_t *ptr
,
82 const struct lttng_integer_type
*type
)
85 unsigned int size
= type
->size
;
86 bool byte_order_reversed
= type
->reverse_byte_order
;
95 tmp
= *(int16_t *) ptr
;
96 if (byte_order_reversed
)
105 tmp
= *(int32_t *) ptr
;
106 if (byte_order_reversed
)
115 tmp
= *(int64_t *) ptr
;
116 if (byte_order_reversed
)
130 uint64_t capture_sequence_element_unsigned(uint8_t *ptr
,
131 const struct lttng_integer_type
*type
)
134 unsigned int size
= type
->size
;
135 bool byte_order_reversed
= type
->reverse_byte_order
;
144 tmp
= *(uint16_t *) ptr
;
145 if (byte_order_reversed
)
154 tmp
= *(uint32_t *) ptr
;
155 if (byte_order_reversed
)
164 tmp
= *(uint64_t *) ptr
;
165 if (byte_order_reversed
)
179 int capture_sequence(struct lttng_msgpack_writer
*writer
,
180 struct lttng_interpreter_output
*output
) __attribute__ ((unused
));
181 int capture_sequence(struct lttng_msgpack_writer
*writer
,
182 struct lttng_interpreter_output
*output
)
184 const struct lttng_integer_type
*integer_type
= NULL
;
185 const struct lttng_type
*nested_type
;
190 ret
= lttng_msgpack_begin_array(writer
, output
->u
.sequence
.nr_elem
);
196 ptr
= (uint8_t *) output
->u
.sequence
.ptr
;
197 nested_type
= output
->u
.sequence
.nested_type
;
198 switch (nested_type
->atype
) {
200 integer_type
= &nested_type
->u
.integer
;
202 case atype_enum_nestable
:
203 /* Treat enumeration as an integer. */
204 integer_type
= &nested_type
->u
.enum_nestable
.container_type
->u
.integer
;
207 /* Capture of array of non-integer are not supported. */
210 signedness
= integer_type
->signedness
;
211 for (i
= 0; i
< output
->u
.sequence
.nr_elem
; i
++) {
213 ret
= lttng_msgpack_write_signed_integer(writer
,
214 capture_sequence_element_signed(ptr
, integer_type
));
220 ret
= lttng_msgpack_write_unsigned_integer(writer
,
221 capture_sequence_element_unsigned(ptr
, integer_type
));
229 * We assume that alignment is smaller or equal to the size.
230 * This currently holds true but if it changes in the future,
231 * we will want to change the pointer arithmetics below to
232 * take into account that the next element might be further
235 WARN_ON(integer_type
->alignment
> integer_type
->size
);
237 /* Size is in number of bits. */
238 ptr
+= (integer_type
->size
/ CHAR_BIT
) ;
241 ret
= lttng_msgpack_end_array(writer
);
248 void lttng_event_notifier_notification_send(struct lttng_event_notifier
*event_notifier
)
250 struct lttng_event_notifier_group
*event_notifier_group
= event_notifier
->group
;
251 struct lib_ring_buffer_ctx ctx
;
254 if (unlikely(!READ_ONCE(event_notifier
->enabled
)))
257 lib_ring_buffer_ctx_init(&ctx
, event_notifier_group
->chan
, NULL
,
258 sizeof(event_notifier
->user_token
),
259 lttng_alignof(event_notifier
->user_token
), -1);
260 ret
= event_notifier_group
->ops
->event_reserve(&ctx
, 0);
262 //TODO: error handling with counter maps
263 //silently drop for now.
267 lib_ring_buffer_align_ctx(&ctx
, lttng_alignof(event_notifier
->user_token
));
268 event_notifier_group
->ops
->event_write(&ctx
, &event_notifier
->user_token
,
269 sizeof(event_notifier
->user_token
));
270 event_notifier_group
->ops
->event_commit(&ctx
);
271 irq_work_queue(&event_notifier_group
->wakeup_pending
);