Commit | Line | Data |
---|---|---|
13405819 PP |
1 | # The MIT License (MIT) |
2 | # | |
4a90140d | 3 | # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com> |
13405819 | 4 | # |
1378f213 PP |
5 | # Permission is hereby granted, free of charge, to any person obtaining |
6 | # a copy of this software and associated documentation files (the | |
7 | # "Software"), to deal in the Software without restriction, including | |
8 | # without limitation the rights to use, copy, modify, merge, publish, | |
9 | # distribute, sublicense, and/or sell copies of the Software, and to | |
10 | # permit persons to whom the Software is furnished to do so, subject to | |
11 | # the following conditions: | |
13405819 | 12 | # |
1378f213 PP |
13 | # The above copyright notice and this permission notice shall be |
14 | # included in all copies or substantial portions of the Software. | |
13405819 | 15 | # |
1378f213 PP |
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
19 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
20 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
21 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
22 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
13405819 | 23 | |
e5aa0be3 PP |
24 | _CLOCK_CB = '{return_ctype} (*{cname}_clock_get_value)(void *);' |
25 | ||
26 | ||
27 | _PLATFORM_CALLBACKS_BEGIN = '''/* barectf platform callbacks */ | |
28 | struct {prefix}platform_callbacks {{ | |
29 | /* clock callbacks */''' | |
30 | ||
31 | ||
32 | _PLATFORM_CALLBACKS_END = ''' | |
33 | /* is back-end full? */ | |
34 | int (*is_backend_full)(void *); | |
35 | ||
36 | /* open packet */ | |
37 | void (*open_packet)(void *); | |
38 | ||
39 | /* close packet */ | |
40 | void (*close_packet)(void *); | |
41 | };''' | |
42 | ||
43 | ||
44 | _CTX_PARENT = '''/* common barectf context */ | |
45 | struct {prefix}ctx {{ | |
46 | /* platform callbacks */ | |
47 | struct {prefix}platform_callbacks cbs; | |
48 | ||
49 | /* platform data (passed to callbacks) */ | |
50 | void *data; | |
51 | ||
67bd189f | 52 | /* output buffer (will contain a CTF binary packet) */ |
e5aa0be3 | 53 | uint8_t *buf; |
67bd189f | 54 | |
e5aa0be3 | 55 | /* packet size in bits */ |
8079a626 | 56 | uint32_t packet_size; |
67bd189f | 57 | |
e5aa0be3 PP |
58 | /* content size in bits */ |
59 | uint32_t content_size; | |
60 | ||
61 | /* current position from beginning of packet in bits */ | |
67bd189f PP |
62 | uint32_t at; |
63 | ||
e5aa0be3 PP |
64 | /* packet header + context size (content offset) */ |
65 | uint32_t off_content; | |
66 | ||
67 | /* events discarded */ | |
68 | uint32_t events_discarded; | |
69 | ||
70 | /* current packet is opened */ | |
71 | int packet_is_open; | |
3cb793a1 PP |
72 | |
73 | /* in tracing code */ | |
74 | volatile int in_tracing_section; | |
75 | ||
76 | /* tracing is enabled */ | |
77 | volatile int is_tracing_enabled; | |
27bc6f1e PP |
78 | |
79 | /* use current/last event timestamp when opening/closing packets */ | |
80 | int use_cur_last_event_ts; | |
e5aa0be3 PP |
81 | }};''' |
82 | ||
83 | ||
2277c89f | 84 | _CTX_BEGIN = '''/* context for stream `{sname}` */ |
e5aa0be3 PP |
85 | struct {prefix}{sname}_ctx {{ |
86 | /* parent */ | |
87 | struct {prefix}ctx parent; | |
88 | ||
89 | /* config-specific members follow */''' | |
90 | ||
91 | ||
92 | _CTX_END = '};' | |
93 | ||
94 | ||
95 | _FUNC_INIT_PROTO = '''/* initialize context */ | |
96 | void {prefix}init( | |
f66be07f | 97 | void *vctx, |
e5aa0be3 PP |
98 | uint8_t *buf, |
99 | uint32_t buf_size, | |
100 | struct {prefix}platform_callbacks cbs, | |
101 | void *data | |
102 | )''' | |
103 | ||
104 | ||
105 | _FUNC_INIT_BODY = '''{{ | |
f66be07f PP |
106 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx); |
107 | ctx->cbs = cbs; | |
108 | ctx->data = data; | |
109 | ctx->buf = buf; | |
110 | ctx->packet_size = _BYTES_TO_BITS(buf_size); | |
111 | ctx->at = 0; | |
112 | ctx->events_discarded = 0; | |
113 | ctx->packet_is_open = 0; | |
3cb793a1 PP |
114 | ctx->in_tracing_section = 0; |
115 | ctx->is_tracing_enabled = 1; | |
27bc6f1e | 116 | ctx->use_cur_last_event_ts = 0; |
e5aa0be3 PP |
117 | }}''' |
118 | ||
119 | ||
2277c89f | 120 | _FUNC_OPEN_PROTO_BEGIN = '''/* open packet for stream `{sname}` */ |
e5aa0be3 PP |
121 | void {prefix}{sname}_open_packet( |
122 | struct {prefix}{sname}_ctx *ctx''' | |
123 | ||
124 | ||
125 | _FUNC_OPEN_PROTO_END = ')' | |
126 | ||
127 | ||
3cb793a1 PP |
128 | _FUNC_OPEN_BODY_BEGIN = '''{{ |
129 | {ts} | |
130 | const int saved_in_tracing_section = ctx->parent.in_tracing_section; | |
131 | ||
132 | /* | |
133 | * This function is either called by a tracing function, or | |
134 | * directly by the platform. | |
135 | * | |
136 | * If it's called by a tracing function, then | |
137 | * ctx->parent.in_tracing_section is 1, so it's safe to open | |
138 | * the packet here (alter the packet), even if tracing was | |
139 | * disabled in the meantime because we're already in a tracing | |
140 | * section (which finishes at the end of the tracing function | |
141 | * call). | |
142 | * | |
143 | * If it's called directly by the platform, then if tracing is | |
144 | * disabled, we don't want to alter the packet, and return | |
145 | * immediately. | |
146 | */ | |
147 | if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{ | |
148 | ctx->parent.in_tracing_section = 0; | |
149 | return; | |
150 | }} | |
151 | ||
152 | /* we can modify the packet */ | |
153 | ctx->parent.in_tracing_section = 1; | |
154 | ''' | |
e5aa0be3 PP |
155 | |
156 | ||
157 | _FUNC_OPEN_BODY_END = ''' | |
27bc6f1e | 158 | /* save content beginning's offset */ |
e5aa0be3 PP |
159 | ctx->parent.off_content = ctx->parent.at; |
160 | ||
161 | /* mark current packet as open */ | |
162 | ctx->parent.packet_is_open = 1; | |
3cb793a1 PP |
163 | |
164 | /* not tracing anymore */ | |
165 | ctx->parent.in_tracing_section = saved_in_tracing_section; | |
e5aa0be3 PP |
166 | }''' |
167 | ||
168 | ||
2277c89f | 169 | _FUNC_CLOSE_PROTO = '''/* close packet for stream `{sname}` */ |
e5aa0be3 PP |
170 | void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)''' |
171 | ||
172 | ||
3cb793a1 PP |
173 | _FUNC_CLOSE_BODY_BEGIN = '''{{ |
174 | {ts} | |
175 | const int saved_in_tracing_section = ctx->parent.in_tracing_section; | |
176 | ||
177 | /* | |
178 | * This function is either called by a tracing function, or | |
179 | * directly by the platform. | |
180 | * | |
181 | * If it's called by a tracing function, then | |
182 | * ctx->parent.in_tracing_section is 1, so it's safe to close | |
183 | * the packet here (alter the packet), even if tracing was | |
184 | * disabled in the meantime, because we're already in a tracing | |
185 | * section (which finishes at the end of the tracing function | |
186 | * call). | |
187 | * | |
188 | * If it's called directly by the platform, then if tracing is | |
189 | * disabled, we don't want to alter the packet, and return | |
190 | * immediately. | |
191 | */ | |
192 | if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{ | |
193 | ctx->parent.in_tracing_section = 0; | |
194 | return; | |
195 | }} | |
196 | ||
197 | /* we can modify the packet */ | |
198 | ctx->parent.in_tracing_section = 1; | |
199 | ''' | |
e5aa0be3 PP |
200 | |
201 | ||
202 | _FUNC_CLOSE_BODY_END = ''' | |
203 | /* go back to end of packet */ | |
204 | ctx->parent.at = ctx->parent.packet_size; | |
205 | ||
206 | /* mark packet as closed */ | |
207 | ctx->parent.packet_is_open = 0; | |
3cb793a1 PP |
208 | |
209 | /* not tracing anymore */ | |
210 | ctx->parent.in_tracing_section = saved_in_tracing_section; | |
e5aa0be3 PP |
211 | }''' |
212 | ||
213 | ||
a50674ee PP |
214 | _DEFINE_DEFAULT_STREAM_TRACE = '#define {prefix}trace_{evname} {prefix}{sname}_trace_{evname}' |
215 | ||
216 | ||
2277c89f | 217 | _FUNC_TRACE_PROTO_BEGIN = '''/* trace (stream `{sname}`, event `{evname}`) */ |
e5aa0be3 PP |
218 | void {prefix}{sname}_trace_{evname}( |
219 | struct {prefix}{sname}_ctx *ctx''' | |
220 | ||
221 | ||
222 | _FUNC_TRACE_PROTO_END = ')' | |
223 | ||
224 | ||
225 | _FUNC_TRACE_BODY = '''{{ | |
226 | uint32_t ev_size; | |
227 | ||
27bc6f1e PP |
228 | /* save timestamp */ |
229 | {save_ts} | |
230 | ||
3cb793a1 PP |
231 | if (!ctx->parent.is_tracing_enabled) {{ |
232 | return; | |
233 | }} | |
234 | ||
235 | /* we can modify the packet */ | |
236 | ctx->parent.in_tracing_section = 1; | |
237 | ||
e5aa0be3 | 238 | /* get event size */ |
f66be07f | 239 | ev_size = _get_event_size_{sname}_{evname}(TO_VOID_PTR(ctx){params}); |
e5aa0be3 PP |
240 | |
241 | /* do we have enough space to serialize? */ | |
f66be07f | 242 | if (!_reserve_event_space(TO_VOID_PTR(ctx), ev_size)) {{ |
e5aa0be3 | 243 | /* no: forget this */ |
3cb793a1 | 244 | ctx->parent.in_tracing_section = 0; |
e5aa0be3 PP |
245 | return; |
246 | }} | |
247 | ||
248 | /* serialize event */ | |
27bc6f1e | 249 | _serialize_event_{sname}_{evname}(TO_VOID_PTR(ctx){params}); |
e5aa0be3 PP |
250 | |
251 | /* commit event */ | |
f66be07f | 252 | _commit_event(TO_VOID_PTR(ctx)); |
3cb793a1 PP |
253 | |
254 | /* not tracing anymore */ | |
255 | ctx->parent.in_tracing_section = 0; | |
e5aa0be3 PP |
256 | }}''' |
257 | ||
258 | ||
259 | _FUNC_GET_EVENT_SIZE_PROTO_BEGIN = '''static uint32_t _get_event_size_{sname}_{evname}( | |
f66be07f | 260 | void *vctx''' |
e5aa0be3 PP |
261 | |
262 | ||
263 | _FUNC_GET_EVENT_SIZE_PROTO_END = ')' | |
264 | ||
265 | ||
f66be07f PP |
266 | _FUNC_GET_EVENT_SIZE_BODY_BEGIN = '''{{ |
267 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx); | |
e5aa0be3 PP |
268 | uint32_t at = ctx->at;''' |
269 | ||
270 | ||
271 | _FUNC_GET_EVENT_SIZE_BODY_END = ''' return at - ctx->at; | |
272 | }''' | |
273 | ||
274 | ||
275 | _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN = '''static void _serialize_stream_event_header_{sname}( | |
f66be07f | 276 | void *vctx, |
e5aa0be3 | 277 | uint32_t event_id''' |
df892ed5 | 278 | |
df892ed5 | 279 | |
e5aa0be3 | 280 | _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END = ')' |
67bd189f | 281 | |
df892ed5 | 282 | |
f66be07f PP |
283 | _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN = '''{{ |
284 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);''' | |
df892ed5 | 285 | |
df892ed5 | 286 | |
e5aa0be3 | 287 | _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END = '}' |
df892ed5 | 288 | |
6b9ba5f3 | 289 | |
e5aa0be3 | 290 | _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN = '''static void _serialize_stream_event_context_{sname}( |
f66be07f | 291 | void *vctx''' |
e5aa0be3 PP |
292 | |
293 | ||
294 | _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END = ')' | |
295 | ||
296 | ||
f66be07f PP |
297 | _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN = '''{{ |
298 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);''' | |
e5aa0be3 PP |
299 | |
300 | ||
301 | _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END = '}' | |
302 | ||
303 | ||
304 | _FUNC_SERIALIZE_EVENT_PROTO_BEGIN = '''static void _serialize_event_{sname}_{evname}( | |
27bc6f1e | 305 | void *vctx''' |
e5aa0be3 PP |
306 | |
307 | ||
308 | _FUNC_SERIALIZE_EVENT_PROTO_END = ')' | |
309 | ||
310 | ||
f66be07f PP |
311 | _FUNC_SERIALIZE_EVENT_BODY_BEGIN = '''{{ |
312 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);''' | |
e5aa0be3 PP |
313 | |
314 | ||
315 | _FUNC_SERIALIZE_EVENT_BODY_END = '}' | |
316 | ||
317 | ||
318 | _HEADER_BEGIN = '''#ifndef _{ucprefix}H | |
319 | #define _{ucprefix}H | |
320 | ||
321 | /* | |
cfb53ba6 PP |
322 | * The MIT License (MIT) |
323 | * | |
4a90140d | 324 | * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com> |
cfb53ba6 | 325 | * |
1378f213 PP |
326 | * Permission is hereby granted, free of charge, to any person obtaining |
327 | * a copy of this software and associated documentation files (the | |
328 | * "Software"), to deal in the Software without restriction, including | |
329 | * without limitation the rights to use, copy, modify, merge, publish, | |
330 | * distribute, sublicense, and/or sell copies of the Software, and to | |
331 | * permit persons to whom the Software is furnished to do so, subject to | |
332 | * the following conditions: | |
cfb53ba6 | 333 | * |
1378f213 PP |
334 | * The above copyright notice and this permission notice shall be |
335 | * included in all copies or substantial portions of the Software. | |
cfb53ba6 | 336 | * |
1378f213 PP |
337 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
338 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
339 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
340 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
341 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
342 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
343 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
344 | * SOFTWARE. | |
cfb53ba6 PP |
345 | * |
346 | * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
347 | * | |
e5aa0be3 PP |
348 | * The following C code was generated by barectf {version} |
349 | * on {date}. | |
350 | * | |
a3ebf585 | 351 | * For more details, see <http://barectf.org>. |
e5aa0be3 | 352 | */ |
67bd189f PP |
353 | |
354 | #include <stdint.h> | |
355 | ||
e5aa0be3 | 356 | #include "{bitfield_header_filename}" |
445687b2 | 357 | |
7005bc96 PP |
358 | #ifdef __cplusplus |
359 | extern "C" {{ | |
360 | #endif | |
361 | ||
30c8f734 PP |
362 | {prefix_def} |
363 | {default_stream_def} | |
b4700284 | 364 | |
a50674ee | 365 | {default_stream_trace_defs} |
30c8f734 | 366 | |
e5aa0be3 | 367 | struct {prefix}ctx; |
67bd189f | 368 | |
e5aa0be3 PP |
369 | uint32_t {prefix}packet_size(void *ctx); |
370 | int {prefix}packet_is_full(void *ctx); | |
371 | int {prefix}packet_is_empty(void *ctx); | |
372 | uint32_t {prefix}packet_events_discarded(void *ctx); | |
373 | uint8_t *{prefix}packet_buf(void *ctx); | |
374 | void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size); | |
375 | uint32_t {prefix}packet_buf_size(void *ctx); | |
3cb793a1 PP |
376 | int {prefix}packet_is_open(void *ctx); |
377 | int {prefix}is_in_tracing_section(void *ctx); | |
378 | volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx); | |
379 | int {prefix}is_tracing_enabled(void *ctx); | |
380 | void {prefix}enable_tracing(void *ctx, int enable);''' | |
67bd189f | 381 | |
67bd189f | 382 | |
7005bc96 PP |
383 | _HEADER_END = '''#ifdef __cplusplus |
384 | }} | |
385 | #endif | |
386 | ||
387 | #endif /* _{ucprefix}H */ | |
388 | ''' | |
67bd189f | 389 | |
67bd189f | 390 | |
e5aa0be3 | 391 | _C_SRC = '''/* |
cfb53ba6 PP |
392 | * The MIT License (MIT) |
393 | * | |
4a90140d | 394 | * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com> |
cfb53ba6 | 395 | * |
1378f213 PP |
396 | * Permission is hereby granted, free of charge, to any person obtaining |
397 | * a copy of this software and associated documentation files (the | |
398 | * "Software"), to deal in the Software without restriction, including | |
399 | * without limitation the rights to use, copy, modify, merge, publish, | |
400 | * distribute, sublicense, and/or sell copies of the Software, and to | |
401 | * permit persons to whom the Software is furnished to do so, subject to | |
402 | * the following conditions: | |
cfb53ba6 | 403 | * |
1378f213 PP |
404 | * The above copyright notice and this permission notice shall be |
405 | * included in all copies or substantial portions of the Software. | |
cfb53ba6 | 406 | * |
1378f213 PP |
407 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
408 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
409 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
410 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
411 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
412 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
413 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
414 | * SOFTWARE. | |
cfb53ba6 PP |
415 | * |
416 | * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
417 | * | |
e5aa0be3 PP |
418 | * The following C code was generated by barectf {version} |
419 | * on {date}. | |
420 | * | |
a3ebf585 | 421 | * For more details, see <http://barectf.org>. |
e5aa0be3 | 422 | */ |
445687b2 | 423 | |
e5aa0be3 | 424 | #include <stdint.h> |
8079a626 | 425 | #include <string.h> |
e5aa0be3 PP |
426 | #include <assert.h> |
427 | ||
428 | #include "{header_filename}" | |
429 | ||
1645a650 PP |
430 | #define _ALIGN(_at, _align) \\ |
431 | do {{ \\ | |
e5aa0be3 PP |
432 | (_at) = ((_at) + ((_align) - 1)) & -(_align); \\ |
433 | }} while (0) | |
8079a626 | 434 | |
f66be07f PP |
435 | #ifdef __cplusplus |
436 | # define TO_VOID_PTR(_value) static_cast<void *>(_value) | |
437 | # define FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value) | |
438 | #else | |
439 | # define TO_VOID_PTR(_value) ((void *) (_value)) | |
440 | # define FROM_VOID_PTR(_type, _value) ((_type *) (_value)) | |
441 | #endif | |
442 | ||
e5aa0be3 PP |
443 | #define _BITS_TO_BYTES(_x) ((_x) >> 3) |
444 | #define _BYTES_TO_BITS(_x) ((_x) << 3) | |
445687b2 | 445 | |
1405552b PP |
446 | union f2u {{ |
447 | float f; | |
448 | uint32_t u; | |
449 | }}; | |
450 | ||
451 | union d2u {{ | |
452 | double f; | |
453 | uint64_t u; | |
454 | }}; | |
455 | ||
e5aa0be3 PP |
456 | uint32_t {prefix}packet_size(void *ctx) |
457 | {{ | |
f66be07f | 458 | return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_size; |
e5aa0be3 | 459 | }} |
9a0782f7 | 460 | |
e5aa0be3 PP |
461 | int {prefix}packet_is_full(void *ctx) |
462 | {{ | |
f66be07f | 463 | struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx); |
e5aa0be3 PP |
464 | |
465 | return cctx->at == cctx->packet_size; | |
466 | }} | |
467 | ||
468 | int {prefix}packet_is_empty(void *ctx) | |
469 | {{ | |
f66be07f | 470 | struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx); |
e5aa0be3 PP |
471 | |
472 | return cctx->at <= cctx->off_content; | |
473 | }} | |
474 | ||
475 | uint32_t {prefix}packet_events_discarded(void *ctx) | |
476 | {{ | |
f66be07f | 477 | return FROM_VOID_PTR(struct {prefix}ctx, ctx)->events_discarded; |
e5aa0be3 PP |
478 | }} |
479 | ||
480 | uint8_t *{prefix}packet_buf(void *ctx) | |
481 | {{ | |
f66be07f | 482 | return FROM_VOID_PTR(struct {prefix}ctx, ctx)->buf; |
e5aa0be3 PP |
483 | }} |
484 | ||
485 | uint32_t {prefix}packet_buf_size(void *ctx) | |
486 | {{ | |
f66be07f PP |
487 | struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx); |
488 | ||
489 | return _BITS_TO_BYTES(cctx->packet_size); | |
e5aa0be3 PP |
490 | }} |
491 | ||
492 | void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size) | |
493 | {{ | |
f66be07f | 494 | struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx); |
e5aa0be3 | 495 | |
f66be07f PP |
496 | cctx->buf = buf; |
497 | cctx->packet_size = _BYTES_TO_BITS(buf_size); | |
e5aa0be3 PP |
498 | }} |
499 | ||
500 | int {prefix}packet_is_open(void *ctx) | |
501 | {{ | |
f66be07f | 502 | return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_is_open; |
e5aa0be3 PP |
503 | }} |
504 | ||
3cb793a1 PP |
505 | int {prefix}is_in_tracing_section(void *ctx) |
506 | {{ | |
507 | return FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section; | |
508 | }} | |
509 | ||
510 | volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx) | |
511 | {{ | |
512 | return &FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section; | |
513 | }} | |
514 | ||
515 | int {prefix}is_tracing_enabled(void *ctx) | |
516 | {{ | |
517 | return FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled; | |
518 | }} | |
519 | ||
520 | void {prefix}enable_tracing(void *ctx, int enable) | |
521 | {{ | |
522 | FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled = enable; | |
523 | }} | |
524 | ||
e5aa0be3 | 525 | static |
ca275dc0 | 526 | void _write_cstring(struct {prefix}ctx *ctx, const char *src) |
e5aa0be3 PP |
527 | {{ |
528 | uint32_t sz = strlen(src) + 1; | |
529 | ||
530 | memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz); | |
531 | ctx->at += _BYTES_TO_BITS(sz); | |
532 | }} | |
533 | ||
e5aa0be3 | 534 | static |
f66be07f | 535 | int _reserve_event_space(void *vctx, uint32_t ev_size) |
e5aa0be3 | 536 | {{ |
f66be07f PP |
537 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx); |
538 | ||
e5aa0be3 PP |
539 | /* event _cannot_ fit? */ |
540 | if (ev_size > (ctx->packet_size - ctx->off_content)) {{ | |
541 | ctx->events_discarded++; | |
542 | ||
543 | return 0; | |
544 | }} | |
545 | ||
546 | /* packet is full? */ | |
547 | if ({prefix}packet_is_full(ctx)) {{ | |
548 | /* yes: is back-end full? */ | |
549 | if (ctx->cbs.is_backend_full(ctx->data)) {{ | |
550 | /* yes: discard event */ | |
551 | ctx->events_discarded++; | |
552 | ||
553 | return 0; | |
554 | }} | |
555 | ||
556 | /* back-end is not full: open new packet */ | |
27bc6f1e | 557 | ctx->use_cur_last_event_ts = 1; |
e5aa0be3 | 558 | ctx->cbs.open_packet(ctx->data); |
27bc6f1e | 559 | ctx->use_cur_last_event_ts = 0; |
e5aa0be3 PP |
560 | }} |
561 | ||
562 | /* event fits the current packet? */ | |
563 | if (ev_size > (ctx->packet_size - ctx->at)) {{ | |
564 | /* no: close packet now */ | |
27bc6f1e | 565 | ctx->use_cur_last_event_ts = 1; |
e5aa0be3 | 566 | ctx->cbs.close_packet(ctx->data); |
27bc6f1e | 567 | ctx->use_cur_last_event_ts = 0; |
e5aa0be3 PP |
568 | |
569 | /* is back-end full? */ | |
570 | if (ctx->cbs.is_backend_full(ctx->data)) {{ | |
571 | /* yes: discard event */ | |
572 | ctx->events_discarded++; | |
573 | ||
574 | return 0; | |
575 | }} | |
576 | ||
577 | /* back-end is not full: open new packet */ | |
27bc6f1e | 578 | ctx->use_cur_last_event_ts = 1; |
e5aa0be3 | 579 | ctx->cbs.open_packet(ctx->data); |
27bc6f1e | 580 | ctx->use_cur_last_event_ts = 0; |
e5aa0be3 PP |
581 | assert(ev_size <= (ctx->packet_size - ctx->at)); |
582 | }} | |
583 | ||
584 | return 1; | |
585 | }} | |
586 | ||
587 | static | |
f66be07f | 588 | void _commit_event(void *vctx) |
e5aa0be3 | 589 | {{ |
f66be07f PP |
590 | struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx); |
591 | ||
e5aa0be3 PP |
592 | /* is packet full? */ |
593 | if ({prefix}packet_is_full(ctx)) {{ | |
594 | /* yes: close it now */ | |
595 | ctx->cbs.close_packet(ctx->data); | |
596 | }} | |
597 | }}''' | |
598 | ||
599 | ||
600 | _BITFIELD = '''#ifndef _$PREFIX$BITFIELD_H | |
601 | #define _$PREFIX$BITFIELD_H | |
9a0782f7 PP |
602 | |
603 | /* | |
604 | * BabelTrace | |
605 | * | |
606 | * Bitfields read/write functions. | |
607 | * | |
4a90140d | 608 | * Copyright (c) 2010-2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
9a0782f7 | 609 | * |
1378f213 PP |
610 | * Permission is hereby granted, free of charge, to any person obtaining |
611 | * a copy of this software and associated documentation files (the | |
612 | * "Software"), to deal in the Software without restriction, including | |
613 | * without limitation the rights to use, copy, modify, merge, publish, | |
614 | * distribute, sublicense, and/or sell copies of the Software, and to | |
615 | * permit persons to whom the Software is furnished to do so, subject to | |
616 | * the following conditions: | |
9a0782f7 | 617 | * |
1378f213 PP |
618 | * The above copyright notice and this permission notice shall be |
619 | * included in all copies or substantial portions of the Software. | |
9a0782f7 | 620 | * |
1378f213 PP |
621 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
622 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
623 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
624 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
625 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
626 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
627 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
9a0782f7 PP |
628 | * SOFTWARE. |
629 | */ | |
630 | ||
8079a626 | 631 | #include <limits.h> |
9a0782f7 | 632 | |
f66be07f PP |
633 | #ifdef __cplusplus |
634 | # define CAST_PTR(_type, _value) \\ | |
635 | static_cast<_type>(static_cast<void *>(_value)) | |
636 | #else | |
637 | # define CAST_PTR(_type, _value) ((void *) (_value)) | |
638 | #endif | |
639 | ||
e5aa0be3 | 640 | #define $PREFIX$BYTE_ORDER $ENDIAN_DEF$ |
9a0782f7 PP |
641 | |
642 | /* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */ | |
193ac49b PP |
643 | #define _$prefix$bt_piecewise_rshift(_vtype, _v, _shift) \\ |
644 | do { \\ | |
645 | unsigned long ___shift = (_shift); \\ | |
646 | unsigned long sb = (___shift) / (sizeof(_v) * CHAR_BIT - 1); \\ | |
647 | unsigned long final = (___shift) % (sizeof(_v) * CHAR_BIT - 1); \\ | |
9a0782f7 PP |
648 | \\ |
649 | for (; sb; sb--) \\ | |
193ac49b PP |
650 | _v >>= sizeof(_v) * CHAR_BIT - 1; \\ |
651 | _v >>= final; \\ | |
652 | } while (0) | |
9a0782f7 | 653 | |
9a0782f7 | 654 | /* |
e5aa0be3 | 655 | * $prefix$bt_bitfield_write - write integer to a bitfield in native endianness |
9a0782f7 PP |
656 | * |
657 | * Save integer to the bitfield, which starts at the "start" bit, has "len" | |
658 | * bits. | |
659 | * The inside of a bitfield is from high bits to low bits. | |
660 | * Uses native endianness. | |
661 | * For unsigned "v", pad MSB with 0 if bitfield is larger than v. | |
662 | * For signed "v", sign-extend v if bitfield is larger than v. | |
663 | * | |
664 | * On little endian, bytes are placed from the less significant to the most | |
665 | * significant. Also, consecutive bitfields are placed from lower bits to higher | |
666 | * bits. | |
667 | * | |
668 | * On big endian, bytes are places from most significant to less significant. | |
669 | * Also, consecutive bitfields are placed from higher to lower bits. | |
670 | */ | |
671 | ||
193ac49b | 672 | #define _$prefix$bt_bitfield_write_le(_ptr, type, _start, _length, _vtype, _v) \\ |
9a0782f7 | 673 | do { \\ |
193ac49b | 674 | _vtype __v = (_v); \\ |
f66be07f | 675 | type *__ptr = CAST_PTR(type *, _ptr); \\ |
9a0782f7 PP |
676 | unsigned long __start = (_start), __length = (_length); \\ |
677 | type mask, cmask; \\ | |
678 | unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\ | |
679 | unsigned long start_unit, end_unit, this_unit; \\ | |
680 | unsigned long end, cshift; /* cshift is "complement shift" */ \\ | |
681 | \\ | |
682 | if (!__length) \\ | |
683 | break; \\ | |
684 | \\ | |
685 | end = __start + __length; \\ | |
686 | start_unit = __start / ts; \\ | |
687 | end_unit = (end + (ts - 1)) / ts; \\ | |
688 | \\ | |
689 | /* Trim v high bits */ \\ | |
690 | if (__length < sizeof(__v) * CHAR_BIT) \\ | |
193ac49b | 691 | __v &= ~((~(_vtype) 0) << __length); \\ |
9a0782f7 PP |
692 | \\ |
693 | /* We can now append v with a simple "or", shift it piece-wise */ \\ | |
694 | this_unit = start_unit; \\ | |
695 | if (start_unit == end_unit - 1) { \\ | |
696 | mask = ~((~(type) 0) << (__start % ts)); \\ | |
697 | if (end % ts) \\ | |
698 | mask |= (~(type) 0) << (end % ts); \\ | |
699 | cmask = (type) __v << (__start % ts); \\ | |
700 | cmask &= ~mask; \\ | |
701 | __ptr[this_unit] &= mask; \\ | |
702 | __ptr[this_unit] |= cmask; \\ | |
703 | break; \\ | |
704 | } \\ | |
705 | if (__start % ts) { \\ | |
706 | cshift = __start % ts; \\ | |
707 | mask = ~((~(type) 0) << cshift); \\ | |
708 | cmask = (type) __v << cshift; \\ | |
709 | cmask &= ~mask; \\ | |
710 | __ptr[this_unit] &= mask; \\ | |
711 | __ptr[this_unit] |= cmask; \\ | |
193ac49b | 712 | _$prefix$bt_piecewise_rshift(_vtype, __v, ts - cshift); \\ |
9a0782f7 PP |
713 | __start += ts - cshift; \\ |
714 | this_unit++; \\ | |
715 | } \\ | |
716 | for (; this_unit < end_unit - 1; this_unit++) { \\ | |
717 | __ptr[this_unit] = (type) __v; \\ | |
193ac49b | 718 | _$prefix$bt_piecewise_rshift(_vtype, __v, ts); \\ |
9a0782f7 PP |
719 | __start += ts; \\ |
720 | } \\ | |
721 | if (end % ts) { \\ | |
722 | mask = (~(type) 0) << (end % ts); \\ | |
723 | cmask = (type) __v; \\ | |
724 | cmask &= ~mask; \\ | |
725 | __ptr[this_unit] &= mask; \\ | |
726 | __ptr[this_unit] |= cmask; \\ | |
727 | } else \\ | |
728 | __ptr[this_unit] = (type) __v; \\ | |
729 | } while (0) | |
730 | ||
193ac49b | 731 | #define _$prefix$bt_bitfield_write_be(_ptr, type, _start, _length, _vtype, _v) \\ |
9a0782f7 | 732 | do { \\ |
193ac49b | 733 | _vtype __v = (_v); \\ |
f66be07f | 734 | type *__ptr = CAST_PTR(type *, _ptr); \\ |
9a0782f7 PP |
735 | unsigned long __start = (_start), __length = (_length); \\ |
736 | type mask, cmask; \\ | |
737 | unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\ | |
738 | unsigned long start_unit, end_unit, this_unit; \\ | |
739 | unsigned long end, cshift; /* cshift is "complement shift" */ \\ | |
740 | \\ | |
741 | if (!__length) \\ | |
742 | break; \\ | |
743 | \\ | |
744 | end = __start + __length; \\ | |
745 | start_unit = __start / ts; \\ | |
746 | end_unit = (end + (ts - 1)) / ts; \\ | |
747 | \\ | |
748 | /* Trim v high bits */ \\ | |
749 | if (__length < sizeof(__v) * CHAR_BIT) \\ | |
193ac49b | 750 | __v &= ~((~(_vtype) 0) << __length); \\ |
9a0782f7 PP |
751 | \\ |
752 | /* We can now append v with a simple "or", shift it piece-wise */ \\ | |
753 | this_unit = end_unit - 1; \\ | |
754 | if (start_unit == end_unit - 1) { \\ | |
755 | mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \\ | |
756 | if (__start % ts) \\ | |
757 | mask |= (~((type) 0)) << (ts - (__start % ts)); \\ | |
758 | cmask = (type) __v << ((ts - (end % ts)) % ts); \\ | |
759 | cmask &= ~mask; \\ | |
760 | __ptr[this_unit] &= mask; \\ | |
761 | __ptr[this_unit] |= cmask; \\ | |
762 | break; \\ | |
763 | } \\ | |
764 | if (end % ts) { \\ | |
765 | cshift = end % ts; \\ | |
766 | mask = ~((~(type) 0) << (ts - cshift)); \\ | |
767 | cmask = (type) __v << (ts - cshift); \\ | |
768 | cmask &= ~mask; \\ | |
769 | __ptr[this_unit] &= mask; \\ | |
770 | __ptr[this_unit] |= cmask; \\ | |
b13ea096 | 771 | _$prefix$bt_piecewise_rshift(_vtype, __v, cshift); \\ |
9a0782f7 PP |
772 | end -= cshift; \\ |
773 | this_unit--; \\ | |
774 | } \\ | |
775 | for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \\ | |
776 | __ptr[this_unit] = (type) __v; \\ | |
b13ea096 | 777 | _$prefix$bt_piecewise_rshift(_vtype, __v, ts); \\ |
9a0782f7 PP |
778 | end -= ts; \\ |
779 | } \\ | |
780 | if (__start % ts) { \\ | |
781 | mask = (~(type) 0) << (ts - (__start % ts)); \\ | |
782 | cmask = (type) __v; \\ | |
783 | cmask &= ~mask; \\ | |
784 | __ptr[this_unit] &= mask; \\ | |
785 | __ptr[this_unit] |= cmask; \\ | |
786 | } else \\ | |
787 | __ptr[this_unit] = (type) __v; \\ | |
788 | } while (0) | |
789 | ||
790 | /* | |
e5aa0be3 PP |
791 | * $prefix$bt_bitfield_write_le - write integer to a bitfield in little endian |
792 | * $prefix$bt_bitfield_write_be - write integer to a bitfield in big endian | |
9a0782f7 PP |
793 | */ |
794 | ||
e5aa0be3 | 795 | #if ($PREFIX$BYTE_ORDER == LITTLE_ENDIAN) |
9a0782f7 | 796 | |
193ac49b PP |
797 | #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \\ |
798 | _$prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) | |
9a0782f7 | 799 | |
193ac49b PP |
800 | #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \\ |
801 | _$prefix$bt_bitfield_write_be(ptr, unsigned char, _start, _length, _vtype, _v) | |
9a0782f7 | 802 | |
e5aa0be3 | 803 | #elif ($PREFIX$BYTE_ORDER == BIG_ENDIAN) |
9a0782f7 | 804 | |
193ac49b PP |
805 | #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \\ |
806 | _$prefix$bt_bitfield_write_le(ptr, unsigned char, _start, _length, _vtype, _v) | |
9a0782f7 | 807 | |
193ac49b PP |
808 | #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \\ |
809 | _$prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) | |
9a0782f7 | 810 | |
e5aa0be3 | 811 | #else /* ($PREFIX$BYTE_ORDER == PDP_ENDIAN) */ |
9a0782f7 PP |
812 | |
813 | #error "Byte order not supported" | |
814 | ||
815 | #endif | |
816 | ||
e5aa0be3 PP |
817 | #endif /* _$PREFIX$BITFIELD_H */ |
818 | ''' |