1 _CLOCK_CB
= '{return_ctype} (*{cname}_clock_get_value)(void *);'
4 _PLATFORM_CALLBACKS_BEGIN
= '''/* barectf platform callbacks */
5 struct {prefix}platform_callbacks {{
6 /* clock callbacks */'''
9 _PLATFORM_CALLBACKS_END
= '''
10 /* is back-end full? */
11 int (*is_backend_full)(void *);
14 void (*open_packet)(void *);
17 void (*close_packet)(void *);
21 _CTX_PARENT
= '''/* common barectf context */
23 /* platform callbacks */
24 struct {prefix}platform_callbacks cbs;
26 /* platform data (passed to callbacks) */
29 /* output buffer (will contain a CTF binary packet) */
32 /* packet size in bits */
35 /* content size in bits */
36 uint32_t content_size;
38 /* current position from beginning of packet in bits */
41 /* packet header + context size (content offset) */
44 /* events discarded */
45 uint32_t events_discarded;
47 /* current packet is opened */
52 _CTX_BEGIN
= '''/* context for stream "{sname}" */
53 struct {prefix}{sname}_ctx {{
55 struct {prefix}ctx parent;
57 /* config-specific members follow */'''
63 _FUNC_INIT_PROTO
= '''/* initialize context */
68 struct {prefix}platform_callbacks cbs,
73 _FUNC_INIT_BODY
= '''{{
74 struct {prefix}ctx *{prefix}ctx = ctx;
75 {prefix}ctx->cbs = cbs;
76 {prefix}ctx->data = data;
77 {prefix}ctx->buf = buf;
78 {prefix}ctx->packet_size = _BYTES_TO_BITS(buf_size);
80 {prefix}ctx->events_discarded = 0;
81 {prefix}ctx->packet_is_open = 0;
85 _FUNC_OPEN_PROTO_BEGIN
= '''/* open packet for stream "{sname}" */
86 void {prefix}{sname}_open_packet(
87 struct {prefix}{sname}_ctx *ctx'''
90 _FUNC_OPEN_PROTO_END
= ')'
93 _FUNC_OPEN_BODY_BEGIN
= '{'
96 _FUNC_OPEN_BODY_END
= '''
97 ctx->parent.off_content = ctx->parent.at;
99 /* mark current packet as open */
100 ctx->parent.packet_is_open = 1;
104 _FUNC_CLOSE_PROTO
= '''/* close packet for stream "{sname}" */
105 void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)'''
108 _FUNC_CLOSE_BODY_BEGIN
= '{'
111 _FUNC_CLOSE_BODY_END
= '''
112 /* go back to end of packet */
113 ctx->parent.at = ctx->parent.packet_size;
115 /* mark packet as closed */
116 ctx->parent.packet_is_open = 0;
120 _FUNC_TRACE_PROTO_BEGIN
= '''/* trace (stream "{sname}", event "{evname}") */
121 void {prefix}{sname}_trace_{evname}(
122 struct {prefix}{sname}_ctx *ctx'''
125 _FUNC_TRACE_PROTO_END
= ')'
128 _FUNC_TRACE_BODY
= '''{{
132 ev_size = _get_event_size_{sname}_{evname}((void *) ctx{params});
134 /* do we have enough space to serialize? */
135 if (!_reserve_event_space((void *) ctx, ev_size)) {{
136 /* no: forget this */
140 /* serialize event */
141 _serialize_event_{sname}_{evname}((void *) ctx{params});
144 _commit_event((void *) ctx);
148 _FUNC_GET_EVENT_SIZE_PROTO_BEGIN
= '''static uint32_t _get_event_size_{sname}_{evname}(
149 struct {prefix}ctx *ctx'''
152 _FUNC_GET_EVENT_SIZE_PROTO_END
= ')'
155 _FUNC_GET_EVENT_SIZE_BODY_BEGIN
= '''{
156 uint32_t at = ctx->at;'''
159 _FUNC_GET_EVENT_SIZE_BODY_END
= ''' return at - ctx->at;
163 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN
= '''static void _serialize_stream_event_header_{sname}(
164 struct {prefix}ctx *ctx,
168 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END
= ')'
171 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN
= '{'
174 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END
= '}'
177 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN
= '''static void _serialize_stream_event_context_{sname}(
178 struct {prefix}ctx *ctx'''
181 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END
= ')'
184 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN
= '{'
187 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END
= '}'
190 _FUNC_SERIALIZE_EVENT_PROTO_BEGIN
= '''static void _serialize_event_{sname}_{evname}(
191 struct {prefix}ctx *ctx'''
194 _FUNC_SERIALIZE_EVENT_PROTO_END
= ')'
197 _FUNC_SERIALIZE_EVENT_BODY_BEGIN
= '{'
200 _FUNC_SERIALIZE_EVENT_BODY_END
= '}'
203 _HEADER_BEGIN
= '''#ifndef _{ucprefix}H
207 * The following C code was generated by barectf {version}
210 * For more details, see <https://github.com/efficios/barectf>.
215 #include "{bitfield_header_filename}"
219 uint32_t {prefix}packet_size(void *ctx);
220 int {prefix}packet_is_full(void *ctx);
221 int {prefix}packet_is_empty(void *ctx);
222 uint32_t {prefix}packet_events_discarded(void *ctx);
223 uint8_t *{prefix}packet_buf(void *ctx);
224 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size);
225 uint32_t {prefix}packet_buf_size(void *ctx);
226 int {prefix}packet_is_open(void *ctx);'''
229 _HEADER_END
= '#endif /* _{ucprefix}H */'
233 * The following C code was generated by barectf {version}
236 * For more details, see <https://github.com/efficios/barectf>.
243 #include "{header_filename}"
245 #define _ALIGN(_at, _align) \\
247 (_at) = ((_at) + ((_align) - 1)) & -(_align); \\
250 #define _BITS_TO_BYTES(_x) ((_x) >> 3)
251 #define _BYTES_TO_BITS(_x) ((_x) << 3)
253 uint32_t {prefix}packet_size(void *ctx)
255 return ((struct {prefix}ctx *) ctx)->packet_size;
258 int {prefix}packet_is_full(void *ctx)
260 struct {prefix}ctx *cctx = ctx;
262 return cctx->at == cctx->packet_size;
265 int {prefix}packet_is_empty(void *ctx)
267 struct {prefix}ctx *cctx = ctx;
269 return cctx->at <= cctx->off_content;
272 uint32_t {prefix}packet_events_discarded(void *ctx)
274 return ((struct {prefix}ctx *) ctx)->events_discarded;
277 uint8_t *{prefix}packet_buf(void *ctx)
279 return ((struct {prefix}ctx *) ctx)->buf;
282 uint32_t {prefix}packet_buf_size(void *ctx)
284 return _BITS_TO_BYTES(((struct {prefix}ctx *) ctx)->packet_size);
287 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size)
289 struct {prefix}ctx *{prefix}ctx = ctx;
291 {prefix}ctx->buf = buf;
292 {prefix}ctx->packet_size = _BYTES_TO_BITS(buf_size);
295 int {prefix}packet_is_open(void *ctx)
297 return ((struct {prefix}ctx *) ctx)->packet_is_open;
301 void _write_cstring(struct barectf_ctx *ctx, const char *src)
303 uint32_t sz = strlen(src) + 1;
305 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
306 ctx->at += _BYTES_TO_BITS(sz);
310 int _packet_is_full(struct {prefix}ctx *ctx)
312 return {prefix}packet_is_full(ctx);
316 int _reserve_event_space(struct {prefix}ctx *ctx, uint32_t ev_size)
318 /* event _cannot_ fit? */
319 if (ev_size > (ctx->packet_size - ctx->off_content)) {{
320 ctx->events_discarded++;
325 /* packet is full? */
326 if ({prefix}packet_is_full(ctx)) {{
327 /* yes: is back-end full? */
328 if (ctx->cbs.is_backend_full(ctx->data)) {{
329 /* yes: discard event */
330 ctx->events_discarded++;
335 /* back-end is not full: open new packet */
336 ctx->cbs.open_packet(ctx->data);
339 /* event fits the current packet? */
340 if (ev_size > (ctx->packet_size - ctx->at)) {{
341 /* no: close packet now */
342 ctx->cbs.close_packet(ctx->data);
344 /* is back-end full? */
345 if (ctx->cbs.is_backend_full(ctx->data)) {{
346 /* yes: discard event */
347 ctx->events_discarded++;
352 /* back-end is not full: open new packet */
353 ctx->cbs.open_packet(ctx->data);
354 assert(ev_size <= (ctx->packet_size - ctx->at));
361 void _commit_event(struct {prefix}ctx *ctx)
363 /* is packet full? */
364 if ({prefix}packet_is_full(ctx)) {{
365 /* yes: close it now */
366 ctx->cbs.close_packet(ctx->data);
371 _BITFIELD
= '''#ifndef _$PREFIX$BITFIELD_H
372 #define _$PREFIX$BITFIELD_H
377 * Bitfields read/write functions.
379 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
381 * Permission is hereby granted, free of charge, to any person obtaining a copy
382 * of this software and associated documentation files (the "Software"), to deal
383 * in the Software without restriction, including without limitation the rights
384 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
385 * copies of the Software, and to permit persons to whom the Software is
386 * furnished to do so, subject to the following conditions:
388 * The above copyright notice and this permission notice shall be included in
389 * all copies or substantial portions of the Software.
391 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
392 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
393 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
394 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
395 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
396 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
400 #include <stdint.h> /* C99 5.2.4.2 Numerical limits */
403 #define $PREFIX$BYTE_ORDER $ENDIAN_DEF$
405 /* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
406 #define _$prefix$bt_piecewise_rshift(_v, _shift) \\
408 __typeof__(_v) ___v = (_v); \\
409 __typeof__(_shift) ___shift = (_shift); \\
410 unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1); \\
411 unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \\
414 ___v >>= sizeof(___v) * CHAR_BIT - 1; \\
418 #define _$prefix$bt_piecewise_lshift(_v, _shift) \\
420 __typeof__(_v) ___v = (_v); \\
421 __typeof__(_shift) ___shift = (_shift); \\
422 unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1); \\
423 unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \\
426 ___v <<= sizeof(___v) * CHAR_BIT - 1; \\
430 #define _$prefix$bt_is_signed_type(type) ((type) -1 < (type) 0)
432 #define _$prefix$bt_unsigned_cast(type, v) \\
434 (sizeof(v) < sizeof(type)) ? \\
435 ((type) (v)) & (~(~(type) 0 << (sizeof(v) * CHAR_BIT))) : \\
440 * $prefix$bt_bitfield_write - write integer to a bitfield in native endianness
442 * Save integer to the bitfield, which starts at the "start" bit, has "len"
444 * The inside of a bitfield is from high bits to low bits.
445 * Uses native endianness.
446 * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
447 * For signed "v", sign-extend v if bitfield is larger than v.
449 * On little endian, bytes are placed from the less significant to the most
450 * significant. Also, consecutive bitfields are placed from lower bits to higher
453 * On big endian, bytes are places from most significant to less significant.
454 * Also, consecutive bitfields are placed from higher to lower bits.
457 #define _$prefix$bt_bitfield_write_le(_ptr, type, _start, _length, _v) \\
459 __typeof__(_v) __v = (_v); \\
460 type *__ptr = (void *) (_ptr); \\
461 unsigned long __start = (_start), __length = (_length); \\
463 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\
464 unsigned long start_unit, end_unit, this_unit; \\
465 unsigned long end, cshift; /* cshift is "complement shift" */ \\
470 end = __start + __length; \\
471 start_unit = __start / ts; \\
472 end_unit = (end + (ts - 1)) / ts; \\
474 /* Trim v high bits */ \\
475 if (__length < sizeof(__v) * CHAR_BIT) \\
476 __v &= ~((~(__typeof__(__v)) 0) << __length); \\
478 /* We can now append v with a simple "or", shift it piece-wise */ \\
479 this_unit = start_unit; \\
480 if (start_unit == end_unit - 1) { \\
481 mask = ~((~(type) 0) << (__start % ts)); \\
483 mask |= (~(type) 0) << (end % ts); \\
484 cmask = (type) __v << (__start % ts); \\
486 __ptr[this_unit] &= mask; \\
487 __ptr[this_unit] |= cmask; \\
490 if (__start % ts) { \\
491 cshift = __start % ts; \\
492 mask = ~((~(type) 0) << cshift); \\
493 cmask = (type) __v << cshift; \\
495 __ptr[this_unit] &= mask; \\
496 __ptr[this_unit] |= cmask; \\
497 __v = _$prefix$bt_piecewise_rshift(__v, ts - cshift); \\
498 __start += ts - cshift; \\
501 for (; this_unit < end_unit - 1; this_unit++) { \\
502 __ptr[this_unit] = (type) __v; \\
503 __v = _$prefix$bt_piecewise_rshift(__v, ts); \\
507 mask = (~(type) 0) << (end % ts); \\
508 cmask = (type) __v; \\
510 __ptr[this_unit] &= mask; \\
511 __ptr[this_unit] |= cmask; \\
513 __ptr[this_unit] = (type) __v; \\
516 #define _$prefix$bt_bitfield_write_be(_ptr, type, _start, _length, _v) \\
518 __typeof__(_v) __v = (_v); \\
519 type *__ptr = (void *) (_ptr); \\
520 unsigned long __start = (_start), __length = (_length); \\
522 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\
523 unsigned long start_unit, end_unit, this_unit; \\
524 unsigned long end, cshift; /* cshift is "complement shift" */ \\
529 end = __start + __length; \\
530 start_unit = __start / ts; \\
531 end_unit = (end + (ts - 1)) / ts; \\
533 /* Trim v high bits */ \\
534 if (__length < sizeof(__v) * CHAR_BIT) \\
535 __v &= ~((~(__typeof__(__v)) 0) << __length); \\
537 /* We can now append v with a simple "or", shift it piece-wise */ \\
538 this_unit = end_unit - 1; \\
539 if (start_unit == end_unit - 1) { \\
540 mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \\
542 mask |= (~((type) 0)) << (ts - (__start % ts)); \\
543 cmask = (type) __v << ((ts - (end % ts)) % ts); \\
545 __ptr[this_unit] &= mask; \\
546 __ptr[this_unit] |= cmask; \\
550 cshift = end % ts; \\
551 mask = ~((~(type) 0) << (ts - cshift)); \\
552 cmask = (type) __v << (ts - cshift); \\
554 __ptr[this_unit] &= mask; \\
555 __ptr[this_unit] |= cmask; \\
556 __v = _$prefix$bt_piecewise_rshift(__v, cshift); \\
560 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \\
561 __ptr[this_unit] = (type) __v; \\
562 __v = _$prefix$bt_piecewise_rshift(__v, ts); \\
565 if (__start % ts) { \\
566 mask = (~(type) 0) << (ts - (__start % ts)); \\
567 cmask = (type) __v; \\
569 __ptr[this_unit] &= mask; \\
570 __ptr[this_unit] |= cmask; \\
572 __ptr[this_unit] = (type) __v; \\
576 * $prefix$bt_bitfield_write_le - write integer to a bitfield in little endian
577 * $prefix$bt_bitfield_write_be - write integer to a bitfield in big endian
580 #if ($PREFIX$BYTE_ORDER == LITTLE_ENDIAN)
582 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v) \\
583 _$prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v)
585 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v) \\
586 _$prefix$bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v)
588 #elif ($PREFIX$BYTE_ORDER == BIG_ENDIAN)
590 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v) \\
591 _$prefix$bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v)
593 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v) \\
594 _$prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v)
596 #else /* ($PREFIX$BYTE_ORDER == PDP_ENDIAN) */
598 #error "Byte order not supported"
602 #endif /* _$PREFIX$BITFIELD_H */