Init RCU, add empty side callback
[libside.git] / src / side.c
CommitLineData
6841ae81
MD
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6#include <side/trace.h>
7#include "tracer.h"
85b765b8 8#include "rcu.h"
6841ae81 9
054b7b5c
MD
10/* Top 8 bits reserved for kernel tracer use. */
11#define SIDE_EVENT_ENABLED_KERNEL_MASK 0xFF000000
29b3374e
MD
12#define SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK 0x80000000
13
054b7b5c
MD
14/* Allow 2^24 tracers to be registered on an event. */
15#define SIDE_EVENT_ENABLED_USER_MASK 0x00FFFFFF
16
17struct side_rcu_gp_state rcu_gp;
075ceef7
MD
18
19/*
20 * Lazy initialization for early use within library constructors.
21 */
22static bool initialized;
23
24static
25void side_init(void)
26 __attribute__((constructor));
27
054b7b5c
MD
28const struct side_callback side_empty_callback;
29
6841ae81
MD
30void side_call(const struct side_event_description *desc, const struct side_arg_vec_description *sav_desc)
31{
054b7b5c
MD
32 const struct side_callback *side_cb;
33 unsigned int rcu_period;
34
075ceef7
MD
35 if (side_unlikely(!initialized))
36 side_init();
6841ae81
MD
37 if (side_unlikely(desc->flags & SIDE_EVENT_FLAG_VARIADIC)) {
38 printf("ERROR: unexpected variadic event description\n");
39 abort();
40 }
d5cdb129 41 if (side_unlikely(*desc->enabled & SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK)) {
dda82f46 42 // TODO: call kernel write.
6841ae81 43 }
054b7b5c
MD
44 if (side_unlikely(!(*desc->enabled & SIDE_EVENT_ENABLED_USER_MASK)))
45 return;
46
6841ae81 47 //TODO: replace tracer_call by rcu iteration on list of registered callbacks
4a7d8700 48 tracer_call(desc, sav_desc, NULL);
054b7b5c
MD
49
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);
6841ae81
MD
54}
55
56void 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)
59{
054b7b5c
MD
60 const struct side_callback *side_cb;
61 unsigned int rcu_period;
62
075ceef7
MD
63 if (side_unlikely(!initialized))
64 side_init();
d5cdb129 65 if (side_unlikely(*desc->enabled & SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK)) {
dda82f46 66 // TODO: call kernel write.
6841ae81 67 }
054b7b5c
MD
68 if (side_unlikely(!(*desc->enabled & SIDE_EVENT_ENABLED_USER_MASK)))
69 return;
70
6841ae81 71 //TODO: replace tracer_call by rcu iteration on list of registered callbacks
4a7d8700 72 tracer_call_variadic(desc, sav_desc, var_struct, NULL);
054b7b5c
MD
73
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);
6841ae81 78}
075ceef7
MD
79
80void side_init(void)
81{
82 if (initialized)
83 return;
054b7b5c 84 side_rcu_gp_init(&rcu_gp);
075ceef7
MD
85 initialized = true;
86}
This page took 0.037403 seconds and 4 git commands to generate.