1 # The MIT License (MIT)
3 # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
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:
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
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.
24 _FUNC_INIT_PROTO
= '''/* initialize context */
29 struct {prefix}platform_callbacks cbs,
34 _FUNC_INIT_BODY
= '''{{
35 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
39 ctx->packet_size = _BYTES_TO_BITS(buf_size);
41 ctx->events_discarded = 0;
42 ctx->packet_is_open = 0;
43 ctx->in_tracing_section = 0;
44 ctx->is_tracing_enabled = 1;
45 ctx->use_cur_last_event_ts = 0;
49 _FUNC_OPEN_PROTO_BEGIN
= '''/* open packet for stream `{sname}` */
50 void {prefix}{sname}_open_packet(
51 struct {prefix}{sname}_ctx *ctx'''
54 _FUNC_OPEN_PROTO_END
= ')'
57 _FUNC_OPEN_BODY_BEGIN
= '''{{
59 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
62 * This function is either called by a tracing function, or
63 * directly by the platform.
65 * If it's called by a tracing function, then
66 * ctx->parent.in_tracing_section is 1, so it's safe to open
67 * the packet here (alter the packet), even if tracing was
68 * disabled in the meantime because we're already in a tracing
69 * section (which finishes at the end of the tracing function
72 * If it's called directly by the platform, then if tracing is
73 * disabled, we don't want to alter the packet, and return
76 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
77 ctx->parent.in_tracing_section = 0;
81 /* we can modify the packet */
82 ctx->parent.in_tracing_section = 1;
86 _FUNC_OPEN_BODY_END
= '''
87 /* save content beginning's offset */
88 ctx->parent.off_content = ctx->parent.at;
90 /* mark current packet as open */
91 ctx->parent.packet_is_open = 1;
93 /* not tracing anymore */
94 ctx->parent.in_tracing_section = saved_in_tracing_section;
98 _FUNC_CLOSE_PROTO
= '''/* close packet for stream `{sname}` */
99 void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)'''
102 _FUNC_CLOSE_BODY_BEGIN
= '''{{
104 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
107 * This function is either called by a tracing function, or
108 * directly by the platform.
110 * If it's called by a tracing function, then
111 * ctx->parent.in_tracing_section is 1, so it's safe to close
112 * the packet here (alter the packet), even if tracing was
113 * disabled in the meantime, because we're already in a tracing
114 * section (which finishes at the end of the tracing function
117 * If it's called directly by the platform, then if tracing is
118 * disabled, we don't want to alter the packet, and return
121 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
122 ctx->parent.in_tracing_section = 0;
126 /* we can modify the packet */
127 ctx->parent.in_tracing_section = 1;
131 _FUNC_CLOSE_BODY_END
= '''
132 /* go back to end of packet */
133 ctx->parent.at = ctx->parent.packet_size;
135 /* mark packet as closed */
136 ctx->parent.packet_is_open = 0;
138 /* not tracing anymore */
139 ctx->parent.in_tracing_section = saved_in_tracing_section;
143 _FUNC_TRACE_PROTO_BEGIN
= '''/* trace (stream `{sname}`, event `{evname}`) */
144 void {prefix}{sname}_trace_{evname}(
145 struct {prefix}{sname}_ctx *ctx'''
148 _FUNC_TRACE_PROTO_END
= ')'
151 _FUNC_TRACE_BODY
= '''{{
157 if (!ctx->parent.is_tracing_enabled) {{
161 /* we can modify the packet */
162 ctx->parent.in_tracing_section = 1;
165 ev_size = _get_event_size_{sname}_{evname}(TO_VOID_PTR(ctx){params});
167 /* do we have enough space to serialize? */
168 if (!_reserve_event_space(TO_VOID_PTR(ctx), ev_size)) {{
169 /* no: forget this */
170 ctx->parent.in_tracing_section = 0;
174 /* serialize event */
175 _serialize_event_{sname}_{evname}(TO_VOID_PTR(ctx){params});
178 _commit_event(TO_VOID_PTR(ctx));
180 /* not tracing anymore */
181 ctx->parent.in_tracing_section = 0;
185 _FUNC_GET_EVENT_SIZE_PROTO_BEGIN
= '''static uint32_t _get_event_size_{sname}_{evname}(
189 _FUNC_GET_EVENT_SIZE_PROTO_END
= ')'
192 _FUNC_GET_EVENT_SIZE_BODY_BEGIN
= '''{{
193 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
194 uint32_t at = ctx->at;'''
197 _FUNC_GET_EVENT_SIZE_BODY_END
= ''' return at - ctx->at;
201 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN
= '''static void _serialize_stream_event_header_{sname}(
206 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END
= ')'
209 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN
= '''{{
210 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
213 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END
= '}'
216 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN
= '''static void _serialize_stream_event_context_{sname}(
220 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END
= ')'
223 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN
= '''{{
224 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
227 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END
= '}'
230 _FUNC_SERIALIZE_EVENT_PROTO_BEGIN
= '''static void _serialize_event_{sname}_{evname}(
234 _FUNC_SERIALIZE_EVENT_PROTO_END
= ')'
237 _FUNC_SERIALIZE_EVENT_BODY_BEGIN
= '''{{
238 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
241 _FUNC_SERIALIZE_EVENT_BODY_END
= '}'
245 * The MIT License (MIT)
247 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
249 * Permission is hereby granted, free of charge, to any person obtaining
250 * a copy of this software and associated documentation files (the
251 * "Software"), to deal in the Software without restriction, including
252 * without limitation the rights to use, copy, modify, merge, publish,
253 * distribute, sublicense, and/or sell copies of the Software, and to
254 * permit persons to whom the Software is furnished to do so, subject to
255 * the following conditions:
257 * The above copyright notice and this permission notice shall be
258 * included in all copies or substantial portions of the Software.
260 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
261 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
262 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
263 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
264 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
265 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
266 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
269 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
271 * The following C code was generated by barectf {version}
274 * For more details, see <http://barectf.org>.
281 #include "{header_filename}"
282 #include "{bitfield_header_filename}"
284 #define _ALIGN(_at, _align) \\
286 (_at) = ((_at) + ((_align) - 1)) & -(_align); \\
290 # define TO_VOID_PTR(_value) static_cast<void *>(_value)
291 # define FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value)
293 # define TO_VOID_PTR(_value) ((void *) (_value))
294 # define FROM_VOID_PTR(_type, _value) ((_type *) (_value))
297 #define _BITS_TO_BYTES(_x) ((_x) >> 3)
298 #define _BYTES_TO_BITS(_x) ((_x) << 3)
310 uint32_t {prefix}packet_size(void *ctx)
312 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_size;
315 int {prefix}packet_is_full(void *ctx)
317 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
319 return cctx->at == cctx->packet_size;
322 int {prefix}packet_is_empty(void *ctx)
324 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
326 return cctx->at <= cctx->off_content;
329 uint32_t {prefix}packet_events_discarded(void *ctx)
331 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->events_discarded;
334 uint8_t *{prefix}packet_buf(void *ctx)
336 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->buf;
339 uint32_t {prefix}packet_buf_size(void *ctx)
341 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
343 return _BITS_TO_BYTES(cctx->packet_size);
346 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size)
348 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
351 cctx->packet_size = _BYTES_TO_BITS(buf_size);
354 int {prefix}packet_is_open(void *ctx)
356 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_is_open;
359 int {prefix}is_in_tracing_section(void *ctx)
361 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
364 volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx)
366 return &FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
369 int {prefix}is_tracing_enabled(void *ctx)
371 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled;
374 void {prefix}enable_tracing(void *ctx, int enable)
376 FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled = enable;
380 void _write_cstring(struct {prefix}ctx *ctx, const char *src)
382 uint32_t sz = strlen(src) + 1;
384 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
385 ctx->at += _BYTES_TO_BITS(sz);
389 int _reserve_event_space(void *vctx, uint32_t ev_size)
391 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
393 /* event _cannot_ fit? */
394 if (ev_size > (ctx->packet_size - ctx->off_content)) {{
395 ctx->events_discarded++;
400 /* packet is full? */
401 if ({prefix}packet_is_full(ctx)) {{
402 /* yes: is back-end full? */
403 if (ctx->cbs.is_backend_full(ctx->data)) {{
404 /* yes: discard event */
405 ctx->events_discarded++;
410 /* back-end is not full: open new packet */
411 ctx->use_cur_last_event_ts = 1;
412 ctx->cbs.open_packet(ctx->data);
413 ctx->use_cur_last_event_ts = 0;
416 /* event fits the current packet? */
417 if (ev_size > (ctx->packet_size - ctx->at)) {{
418 /* no: close packet now */
419 ctx->use_cur_last_event_ts = 1;
420 ctx->cbs.close_packet(ctx->data);
421 ctx->use_cur_last_event_ts = 0;
423 /* is back-end full? */
424 if (ctx->cbs.is_backend_full(ctx->data)) {{
425 /* yes: discard event */
426 ctx->events_discarded++;
431 /* back-end is not full: open new packet */
432 ctx->use_cur_last_event_ts = 1;
433 ctx->cbs.open_packet(ctx->data);
434 ctx->use_cur_last_event_ts = 0;
435 assert(ev_size <= (ctx->packet_size - ctx->at));
442 void _commit_event(void *vctx)
444 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
446 /* is packet full? */
447 if ({prefix}packet_is_full(ctx)) {{
448 /* yes: close it now */
449 ctx->cbs.close_packet(ctx->data);