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
;
36 SIDE_TYPE_VLA_VISITOR
,
57 //variants (discriminated unions)
61 SIDE_LOGLEVEL_EMERG
= 0,
62 SIDE_LOGLEVEL_ALERT
= 1,
63 SIDE_LOGLEVEL_CRIT
= 2,
64 SIDE_LOGLEVEL_ERR
= 3,
65 SIDE_LOGLEVEL_WARNING
= 4,
66 SIDE_LOGLEVEL_NOTICE
= 5,
67 SIDE_LOGLEVEL_INFO
= 6,
68 SIDE_LOGLEVEL_DEBUG
= 7,
71 enum side_visitor_status
{
72 SIDE_VISITOR_STATUS_ERROR
= -1,
73 SIDE_VISITOR_STATUS_OK
= 0,
74 SIDE_VISITOR_STATUS_END
= 1,
77 typedef enum side_visitor_status (*side_visitor_begin
)(void *ctx
);
78 typedef enum side_visitor_status (*side_visitor_end
)(void *ctx
);
79 typedef enum side_visitor_status (*side_visitor_get_next
)(void *ctx
, struct side_arg_vec
*sav_elem
);
81 struct side_type_description
{
83 //TODO: we should add something like a list of user attributes (namespaced strings)
87 const struct side_event_field
*fields
;
91 const struct side_type_description
*elem_type
;
94 const struct side_type_description
*elem_type
;
97 const struct side_type_description
*elem_type
;
98 side_visitor_begin begin
;
100 side_visitor_get_next get_next
;
105 struct side_event_field
{
106 const char *field_name
;
107 struct side_type_description side_type
;
110 struct side_event_description
{
113 uint32_t loglevel
; /* enum side_loglevel */
115 const char *provider_name
;
116 const char *event_name
;
117 const struct side_event_field
*fields
;
120 struct side_arg_vec
{
121 uint32_t type
; /* enum side_type */
133 const struct side_arg_vec_description
*side_struct
;
134 const struct side_arg_vec_description
*side_array
;
135 const struct side_arg_vec_description
*side_vla
;
136 void *side_vla_visitor_ctx
;
138 void *side_array_fixint
;
146 struct side_arg_vec_description
{
147 const struct side_arg_vec
*sav
;
151 #define side_type_decl(_type) { .type = _type }
152 #define side_field(_type, _name) { .field_name = _name, .side_type = side_type_decl(_type) }
154 #define side_type_struct_decl(_fields) \
156 .type = SIDE_TYPE_STRUCT, \
159 .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \
164 #define side_field_struct(_name, _fields) \
166 .field_name = _name, \
167 .side_type = side_type_struct_decl(SIDE_PARAM(_fields)), \
170 #define side_type_array_decl(_elem_type, _length) \
172 .type = SIDE_TYPE_ARRAY, \
176 .elem_type = _elem_type, \
180 #define side_field_array(_name, _elem_type, _length) \
182 .field_name = _name, \
183 .side_type = side_type_array_decl(_elem_type, _length), \
186 #define side_type_vla_decl(_elem_type) \
188 .type = SIDE_TYPE_VLA, \
191 .elem_type = _elem_type, \
195 #define side_field_vla(_name, _elem_type) \
197 .field_name = _name, \
198 .side_type = side_type_vla_decl(_elem_type), \
201 #define side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next) \
203 .type = SIDE_TYPE_VLA_VISITOR, \
205 .side_vla_visitor = { \
206 .elem_type = _elem_type, \
209 .get_next = _get_next, \
213 #define side_field_vla_visitor(_name, _elem_type, _begin, _end, _get_next) \
215 .field_name = _name, \
216 .side_type = side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next), \
219 #define side_elem(...) \
220 SIDE_COMPOUND_LITERAL(const struct side_type_description, side_type_decl(__VA_ARGS__))
222 #define side_field_list(...) \
223 SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
225 #define side_arg_u8(val) { .type = SIDE_TYPE_U8, .u = { .side_u8 = (val) } }
226 #define side_arg_u16(val) { .type = SIDE_TYPE_U16, .u = { .side_u16 = (val) } }
227 #define side_arg_u32(val) { .type = SIDE_TYPE_U32, .u = { .side_u32 = (val) } }
228 #define side_arg_u64(val) { .type = SIDE_TYPE_U64, .u = { .side_u64 = (val) } }
229 #define side_arg_s8(val) { .type = SIDE_TYPE_S8, .u = { .side_s8 = (val) } }
230 #define side_arg_s16(val) { .type = SIDE_TYPE_S16, .u = { .side_s16 = (val) } }
231 #define side_arg_s32(val) { .type = SIDE_TYPE_S32, .u = { .side_s32 = (val) } }
232 #define side_arg_s64(val) { .type = SIDE_TYPE_S64, .u = { .side_s64 = (val) } }
233 #define side_arg_string(val) { .type = SIDE_TYPE_STRING, .u = { .string = (val) } }
234 #define side_arg_struct(_side_type) { .type = SIDE_TYPE_STRUCT, .u = { .side_struct = (_side_type) } }
235 #define side_arg_array(_side_type) { .type = SIDE_TYPE_ARRAY, .u = { .side_array = (_side_type) } }
236 #define side_arg_vla(_side_type) { .type = SIDE_TYPE_VLA, .u = { .side_vla = (_side_type) } }
237 #define side_arg_vla_visitor(_ctx) { .type = SIDE_TYPE_VLA_VISITOR, .u = { .side_vla_visitor_ctx = (_ctx) } }
239 #define side_arg_array_u8(_ptr) { .type = SIDE_TYPE_ARRAY_U8, .u = { .side_array_fixint = (_ptr) } }
240 #define side_arg_array_u16(_ptr) { .type = SIDE_TYPE_ARRAY_U16, .u = { .side_array_fixint = (_ptr) } }
241 #define side_arg_array_u32(_ptr) { .type = SIDE_TYPE_ARRAY_U32, .u = { .side_array_fixint = (_ptr) } }
242 #define side_arg_array_u64(_ptr) { .type = SIDE_TYPE_ARRAY_U64, .u = { .side_array_fixint = (_ptr) } }
243 #define side_arg_array_s8(_ptr) { .type = SIDE_TYPE_ARRAY_S8, .u = { .side_array_fixint = (_ptr) } }
244 #define side_arg_array_s16(_ptr) { .type = SIDE_TYPE_ARRAY_S16, .u = { .side_array_fixint = (_ptr) } }
245 #define side_arg_array_s32(_ptr) { .type = SIDE_TYPE_ARRAY_S32, .u = { .side_array_fixint = (_ptr) } }
246 #define side_arg_array_s64(_ptr) { .type = SIDE_TYPE_ARRAY_S64, .u = { .side_array_fixint = (_ptr) } }
248 #define side_arg_vla_u8(_ptr, _length) { .type = SIDE_TYPE_VLA_U8, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } }
249 #define side_arg_vla_u16(_ptr, _length) { .type = SIDE_TYPE_VLA_U16, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
250 #define side_arg_vla_u32(_ptr, _length) { .type = SIDE_TYPE_VLA_U32, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
251 #define side_arg_vla_u64(_ptr, _length) { .type = SIDE_TYPE_VLA_U64, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
252 #define side_arg_vla_s8(_ptr, _length) { .type = SIDE_TYPE_VLA_S8, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
253 #define side_arg_vla_s16(_ptr, _length) { .type = SIDE_TYPE_VLA_S16, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
254 #define side_arg_vla_s32(_ptr, _length) { .type = SIDE_TYPE_VLA_S32, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
255 #define side_arg_vla_s64(_ptr, _length) { .type = SIDE_TYPE_VLA_S64, .u = { .side_vla_fixint = { .p = (_ptr), .length = (_length) } } }
257 #define side_arg_define_vec(_identifier, _sav) \
258 const struct side_arg_vec _identifier##_vec[] = { _sav }; \
259 const struct side_arg_vec_description _identifier = { \
260 .sav = _identifier##_vec, \
261 .len = SIDE_ARRAY_SIZE(_identifier##_vec), \
264 #define side_arg_list(...) __VA_ARGS__
266 #define side_event_cond(desc) if (side_unlikely((desc)->enabled))
267 #define side_event_call(desc, _sav) \
269 const struct side_arg_vec side_sav[] = { _sav }; \
270 const struct side_arg_vec_description sav_desc = { \
272 .len = SIDE_ARRAY_SIZE(side_sav), \
274 tracer_call(desc, &sav_desc); \
277 #define side_event(desc, sav) \
278 side_event_cond(desc) \
279 side_event_call(desc, SIDE_PARAM(sav)); \
281 #define side_define_event(_identifier, _provider, _event, _loglevel, _fields) \
282 struct side_event_description _identifier = { \
285 .loglevel = _loglevel, \
286 .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \
287 .provider_name = _provider, \
288 .event_name = _event, \
292 #define side_declare_event(_identifier) \
293 struct side_event_description _identifier
295 #endif /* _SIDE_TRACE_H */