Add TODO
[libside.git] / include / side / trace.h
CommitLineData
f611d0c3
MD
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6#ifndef _SIDE_TRACE_H
7#define _SIDE_TRACE_H
8
9#include <stdint.h>
10#include <inttypes.h>
11#include <stdlib.h>
12#include <stdio.h>
13#include <side/macros.h>
14
15/* SIDE stands for "Static Instrumentation Dynamically Enabled" */
16
17struct side_arg_vec;
18struct side_type_description;
19struct side_event_field;
20
21enum side_type {
22 SIDE_TYPE_U8,
23 SIDE_TYPE_U16,
24 SIDE_TYPE_U32,
25 SIDE_TYPE_U64,
26 SIDE_TYPE_S8,
27 SIDE_TYPE_S16,
28 SIDE_TYPE_S32,
29 SIDE_TYPE_S64,
ba845af5 30
f611d0c3
MD
31 SIDE_TYPE_STRING,
32 SIDE_TYPE_DYNAMIC,
33 SIDE_TYPE_STRUCT,
34 SIDE_TYPE_ARRAY,
35 SIDE_TYPE_VLA,
36 SIDE_TYPE_VLA_VISITOR,
ba845af5
MD
37
38 SIDE_TYPE_ARRAY_U8,
39 SIDE_TYPE_ARRAY_U16,
40 SIDE_TYPE_ARRAY_U32,
41 SIDE_TYPE_ARRAY_U64,
42 SIDE_TYPE_ARRAY_S8,
43 SIDE_TYPE_ARRAY_S16,
44 SIDE_TYPE_ARRAY_S32,
45 SIDE_TYPE_ARRAY_S64,
46
1533629f
MD
47 SIDE_TYPE_VLA_U8,
48 SIDE_TYPE_VLA_U16,
49 SIDE_TYPE_VLA_U32,
50 SIDE_TYPE_VLA_U64,
51 SIDE_TYPE_VLA_S8,
52 SIDE_TYPE_VLA_S16,
53 SIDE_TYPE_VLA_S32,
54 SIDE_TYPE_VLA_S64,
55
f611d0c3 56 //TODO:
f611d0c3
MD
57 //variants (discriminated unions)
58};
59
60enum side_loglevel {
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,
69};
70
71enum side_visitor_status {
72 SIDE_VISITOR_STATUS_ERROR = -1,
73 SIDE_VISITOR_STATUS_OK = 0,
74 SIDE_VISITOR_STATUS_END = 1,
75};
76
77typedef enum side_visitor_status (*side_visitor_begin)(void *ctx);
78typedef enum side_visitor_status (*side_visitor_end)(void *ctx);
79typedef enum side_visitor_status (*side_visitor_get_next)(void *ctx, struct side_arg_vec *sav_elem);
80
81struct side_type_description {
82 enum side_type type;
8d02fd98 83 //TODO: we should add something like a list of user attributes (namespaced strings)
f611d0c3
MD
84 union {
85 struct {
86 uint32_t nr_fields;
87 const struct side_event_field *fields;
88 } side_struct;
89 struct {
90 uint32_t length;
91 const struct side_type_description *elem_type;
92 } side_array;
93 struct {
94 const struct side_type_description *elem_type;
95 } side_vla;
96 struct {
97 const struct side_type_description *elem_type;
98 side_visitor_begin begin;
99 side_visitor_end end;
100 side_visitor_get_next get_next;
101 } side_vla_visitor;
102 } u;
103};
104
105struct side_event_field {
106 const char *field_name;
107 struct side_type_description side_type;
108};
109
110struct side_event_description {
111 uint32_t version;
112 uint32_t enabled;
113 uint32_t loglevel; /* enum side_loglevel */
114 uint32_t nr_fields;
115 const char *provider_name;
116 const char *event_name;
117 const struct side_event_field *fields;
118};
119
120struct side_arg_vec {
121 uint32_t type; /* enum side_type */
122 union {
123 uint8_t side_u8;
124 uint16_t side_u16;
125 uint32_t side_u32;
126 uint64_t side_u64;
127 int8_t side_s8;
128 int16_t side_s16;
129 int32_t side_s32;
130 int64_t side_s64;
ba845af5 131
f611d0c3
MD
132 const char *string;
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;
ba845af5
MD
137
138 void *side_array_fixint;
1533629f
MD
139 struct {
140 void *p;
141 uint32_t length;
142 } side_vla_fixint;
f611d0c3
MD
143 } u;
144};
145
146struct side_arg_vec_description {
147 const struct side_arg_vec *sav;
148 uint32_t len;
149};
150
151#define side_type_decl(_type) { .type = _type }
152#define side_field(_type, _name) { .field_name = _name, .side_type = side_type_decl(_type) }
153
154#define side_type_struct_decl(_fields) \
155 { \
156 .type = SIDE_TYPE_STRUCT, \
157 .u = { \
158 .side_struct = { \
159 .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \
160 .fields = _fields, \
161 }, \
162 }, \
163 }
164#define side_field_struct(_name, _fields) \
165 { \
166 .field_name = _name, \
167 .side_type = side_type_struct_decl(SIDE_PARAM(_fields)), \
168 }
169
170#define side_type_array_decl(_elem_type, _length) \
171 { \
172 .type = SIDE_TYPE_ARRAY, \
173 .u = { \
174 .side_array = { \
175 .length = _length, \
176 .elem_type = _elem_type, \
177 }, \
178 }, \
179 }
180#define side_field_array(_name, _elem_type, _length) \
181 { \
182 .field_name = _name, \
183 .side_type = side_type_array_decl(_elem_type, _length), \
184 }
185
186#define side_type_vla_decl(_elem_type) \
187 { \
188 .type = SIDE_TYPE_VLA, \
189 .u = { \
190 .side_vla = { \
191 .elem_type = _elem_type, \
192 }, \
193 }, \
194 }
195#define side_field_vla(_name, _elem_type) \
196 { \
197 .field_name = _name, \
198 .side_type = side_type_vla_decl(_elem_type), \
199 }
200
201#define side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next) \
202 { \
203 .type = SIDE_TYPE_VLA_VISITOR, \
204 .u = { \
205 .side_vla_visitor = { \
206 .elem_type = _elem_type, \
207 .begin = _begin, \
208 .end = _end, \
209 .get_next = _get_next, \
210 }, \
211 }, \
212 }
213#define side_field_vla_visitor(_name, _elem_type, _begin, _end, _get_next) \
214 { \
215 .field_name = _name, \
216 .side_type = side_type_vla_visitor_decl(_elem_type, _begin, _end, _get_next), \
217 }
218
71002b5e 219#define side_elem(...) \
f611d0c3
MD
220 SIDE_COMPOUND_LITERAL(const struct side_type_description, side_type_decl(__VA_ARGS__))
221
222#define side_field_list(...) \
223 SIDE_COMPOUND_LITERAL(const struct side_event_field, __VA_ARGS__)
224
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) } }
238
1533629f
MD
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) } }
247
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) } } }
ba845af5 256
f611d0c3
MD
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), \
262 }
263
264#define side_arg_list(...) __VA_ARGS__
265
266#define side_event_cond(desc) if (side_unlikely((desc)->enabled))
267#define side_event_call(desc, _sav) \
268 { \
269 const struct side_arg_vec side_sav[] = { _sav }; \
270 const struct side_arg_vec_description sav_desc = { \
271 .sav = side_sav, \
272 .len = SIDE_ARRAY_SIZE(side_sav), \
273 }; \
274 tracer_call(desc, &sav_desc); \
275 }
276
277#define side_event(desc, sav) \
278 side_event_cond(desc) \
279 side_event_call(desc, SIDE_PARAM(sav)); \
280
281#define side_define_event(_identifier, _provider, _event, _loglevel, _fields) \
282 struct side_event_description _identifier = { \
283 .version = 0, \
284 .enabled = 0, \
285 .loglevel = _loglevel, \
286 .nr_fields = SIDE_ARRAY_SIZE(SIDE_PARAM(_fields)), \
287 .provider_name = _provider, \
288 .event_name = _event, \
289 .fields = _fields, \
290 }
291
292#define side_declare_event(_identifier) \
293 struct side_event_description _identifier
294
295#endif /* _SIDE_TRACE_H */
This page took 0.043513 seconds and 4 git commands to generate.