1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 #include <side/trace.h>
10 /* Top 8 bits reserved for kernel tracer use. */
11 #define SIDE_EVENT_ENABLED_KERNEL_MASK 0xFF000000
12 #define SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK 0x80000000
14 /* Allow 2^24 tracers to be registered on an event. */
15 #define SIDE_EVENT_ENABLED_USER_MASK 0x00FFFFFF
17 struct side_rcu_gp_state rcu_gp
;
20 * Lazy initialization for early use within library constructors.
22 static bool initialized
;
26 __attribute__((constructor
));
28 const struct side_callback side_empty_callback
;
30 void side_call(const struct side_event_description
*desc
, const struct side_arg_vec_description
*sav_desc
)
32 const struct side_callback
*side_cb
;
33 unsigned int rcu_period
;
35 if (side_unlikely(!initialized
))
37 if (side_unlikely(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)) {
38 printf("ERROR: unexpected variadic event description\n");
41 if (side_unlikely(*desc
->enabled
& SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK
)) {
42 // TODO: call kernel write.
44 if (side_unlikely(!(*desc
->enabled
& SIDE_EVENT_ENABLED_USER_MASK
)))
47 //TODO: replace tracer_call by rcu iteration on list of registered callbacks
48 tracer_call(desc
, sav_desc
, NULL
);
50 rcu_period
= side_rcu_read_begin(&rcu_gp
);
51 for (side_cb
= side_rcu_dereference(desc
->callbacks
); side_cb
->u
.call
!= NULL
; side_cb
++)
52 side_cb
->u
.call(desc
, sav_desc
, side_cb
->priv
);
53 side_rcu_read_end(&rcu_gp
, rcu_period
);
56 void side_call_variadic(const struct side_event_description
*desc
,
57 const struct side_arg_vec_description
*sav_desc
,
58 const struct side_arg_dynamic_event_struct
*var_struct
)
60 const struct side_callback
*side_cb
;
61 unsigned int rcu_period
;
63 if (side_unlikely(!initialized
))
65 if (side_unlikely(*desc
->enabled
& SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK
)) {
66 // TODO: call kernel write.
68 if (side_unlikely(!(*desc
->enabled
& SIDE_EVENT_ENABLED_USER_MASK
)))
71 //TODO: replace tracer_call by rcu iteration on list of registered callbacks
72 tracer_call_variadic(desc
, sav_desc
, var_struct
, NULL
);
74 rcu_period
= side_rcu_read_begin(&rcu_gp
);
75 for (side_cb
= side_rcu_dereference(desc
->callbacks
); side_cb
->u
.call_variadic
!= NULL
; side_cb
++)
76 side_cb
->u
.call_variadic(desc
, sav_desc
, var_struct
, side_cb
->priv
);
77 side_rcu_read_end(&rcu_gp
, rcu_period
);
84 side_rcu_gp_init(&rcu_gp
);