1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 #include <side/macros.h>
15 /* SIDE stands for "Static Instrumentation Dynamically Enabled" */
18 struct side_type_description
;
19 struct side_event_field
;
35 SIDE_TYPE_VLA_VISITOR
,
37 //specialized array and vla for fixed-size integers (optimization)
38 //variants (discriminated unions)
42 SIDE_LOGLEVEL_EMERG
= 0,
43 SIDE_LOGLEVEL_ALERT
= 1,
44 SIDE_LOGLEVEL_CRIT
= 2,
45 SIDE_LOGLEVEL_ERR
= 3,
46 SIDE_LOGLEVEL_WARNING
= 4,
47 SIDE_LOGLEVEL_NOTICE
= 5,
48 SIDE_LOGLEVEL_INFO
= 6,
49 SIDE_LOGLEVEL_DEBUG
= 7,
52 enum side_visitor_status
{
53 SIDE_VISITOR_STATUS_ERROR
= -1,
54 SIDE_VISITOR_STATUS_OK
= 0,
55 SIDE_VISITOR_STATUS_END
= 1,
58 typedef enum side_visitor_status (*side_visitor_begin
)(void *ctx
);
59 typedef enum side_visitor_status (*side_visitor_end
)(void *ctx
);
60 typedef enum side_visitor_status (*side_visitor_get_next
)(void *ctx
, struct side_arg_vec
*sav_elem
);
62 struct side_type_description
{
67 const struct side_event_field
*fields
;
71 const struct side_type_description
*elem_type
;
74 const struct side_type_description
*elem_type
;
77 const struct side_type_description
*elem_type
;
78 side_visitor_begin begin
;
80 side_visitor_get_next get_next
;
85 struct side_event_field
{
86 const char *field_name
;
87 struct side_type_description side_type
;
90 struct side_event_description
{
93 uint32_t loglevel
; /* enum side_loglevel */
95 const char *provider_name
;
96 const char *event_name
;
97 const struct side_event_field
*fields
;
100 struct side_arg_vec
{
101 uint32_t type
; /* enum side_type */
112 const struct side_arg_vec_description
*side_struct
;
113 const struct side_arg_vec_description
*side_array
;
114 const struct side_arg_vec_description
*side_vla
;
115 void *side_vla_visitor_ctx
;
119 struct side_arg_vec_description
{
120 const struct side_arg_vec
*sav
;
124 #define side_type_decl(_type) { .type = _type }
125 #define side_field(_type, _name) { .field_name = _name, .side_type = side_type_decl(_type) }
127 #define side_type_struct_decl(_fields) \
129 .type = SIDE_TYPE_STRUCT, \
132 .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \
137 #define side_field_struct(_name, _fields) \
139 .field_name = _name, \
140 .side_type = side_type_struct_decl(SIDE_PARAM(_fields)), \
143 #define side_type_array_decl(_elem_type, _length) \
145 .type = SIDE_TYPE_ARRAY, \
149 .elem_type = _elem_type, \
153 #define side_field_array(_name, _elem_type, _length) \
155 .field_name = _name, \
156 .side_type = side_type_array_decl(_elem_type, _length), \
159 #define side_type_vla_decl(_elem_type) \
161 .type = SIDE_TYPE_VLA, \
164 .elem_type = _elem_type, \
168 #define side_field_vla(_name, _elem_type) \
170 .field_name = _name, \
171 .side_type = side_type_vla_decl(_elem_type), \
174 #define side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next) \
176 .type = SIDE_TYPE_VLA_VISITOR, \
178 .side_vla_visitor = { \
179 .elem_type = _elem_type, \
182 .get_next = _get_next, \
186 #define side_field_vla_visitor(_name, _elem_type, _begin, _end, _get_next) \
188 .field_name = _name, \
189 .side_type = side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next), \
192 #define side_vla_elem(...) \
193 SIDE_COMPOUND_LITERAL(const struct side_type_description, side_type_decl(__VA_ARGS__))
195 #define side_vla_visitor_elem(...) \
196 SIDE_COMPOUND_LITERAL(const struct side_type_description, side_type_decl(__VA_ARGS__))
198 #define side_array_elem(...) \
199 SIDE_COMPOUND_LITERAL(const struct side_type_description, side_type_decl(__VA_ARGS__))
201 #define side_field_list(...) \
202 SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
204 #define side_arg_u8(val) { .type = SIDE_TYPE_U8, .u = { .side_u8 = (val) } }
205 #define side_arg_u16(val) { .type = SIDE_TYPE_U16, .u = { .side_u16 = (val) } }
206 #define side_arg_u32(val) { .type = SIDE_TYPE_U32, .u = { .side_u32 = (val) } }
207 #define side_arg_u64(val) { .type = SIDE_TYPE_U64, .u = { .side_u64 = (val) } }
208 #define side_arg_s8(val) { .type = SIDE_TYPE_S8, .u = { .side_s8 = (val) } }
209 #define side_arg_s16(val) { .type = SIDE_TYPE_S16, .u = { .side_s16 = (val) } }
210 #define side_arg_s32(val) { .type = SIDE_TYPE_S32, .u = { .side_s32 = (val) } }
211 #define side_arg_s64(val) { .type = SIDE_TYPE_S64, .u = { .side_s64 = (val) } }
212 #define side_arg_string(val) { .type = SIDE_TYPE_STRING, .u = { .string = (val) } }
213 #define side_arg_struct(_side_type) { .type = SIDE_TYPE_STRUCT, .u = { .side_struct = (_side_type) } }
214 #define side_arg_array(_side_type) { .type = SIDE_TYPE_ARRAY, .u = { .side_array = (_side_type) } }
215 #define side_arg_vla(_side_type) { .type = SIDE_TYPE_VLA, .u = { .side_vla = (_side_type) } }
216 #define side_arg_vla_visitor(_ctx) { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_vla_visitor_ctx = (_ctx) } }
218 #define side_arg_define_vec(_identifier, _sav) \
219 const struct side_arg_vec _identifier##_vec[] = { _sav }; \
220 const struct side_arg_vec_description _identifier = { \
221 .sav = _identifier##_vec, \
222 .len = SIDE_ARRAY_SIZE(_identifier##_vec), \
225 #define side_arg_list(...) __VA_ARGS__
227 #define side_event_cond(desc) if (side_unlikely((desc)->enabled))
228 #define side_event_call(desc, _sav) \
230 const struct side_arg_vec side_sav[] = { _sav }; \
231 const struct side_arg_vec_description sav_desc = { \
233 .len = SIDE_ARRAY_SIZE(side_sav), \
235 tracer_call(desc, &sav_desc); \
238 #define side_event(desc, sav) \
239 side_event_cond(desc) \
240 side_event_call(desc, SIDE_PARAM(sav)); \
242 #define side_define_event(_identifier, _provider, _event, _loglevel, _fields) \
243 struct side_event_description _identifier = { \
246 .loglevel = _loglevel, \
247 .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \
248 .provider_name = _provider, \
249 .event_name = _event, \
253 #define side_declare_event(_identifier) \
254 struct side_event_description _identifier
256 #endif /* _SIDE_TRACE_H */