barectf v2.0.0
[barectf.git] / barectf / templates.py
1 _CLOCK_CB = '{return_ctype} (*{cname}_clock_get_value)(void *);'
2
3
4 _PLATFORM_CALLBACKS_BEGIN = '''/* barectf platform callbacks */
5 struct {prefix}platform_callbacks {{
6 /* clock callbacks */'''
7
8
9 _PLATFORM_CALLBACKS_END = '''
10 /* is back-end full? */
11 int (*is_backend_full)(void *);
12
13 /* open packet */
14 void (*open_packet)(void *);
15
16 /* close packet */
17 void (*close_packet)(void *);
18 };'''
19
20
21 _CTX_PARENT = '''/* common barectf context */
22 struct {prefix}ctx {{
23 /* platform callbacks */
24 struct {prefix}platform_callbacks cbs;
25
26 /* platform data (passed to callbacks) */
27 void *data;
28
29 /* output buffer (will contain a CTF binary packet) */
30 uint8_t *buf;
31
32 /* packet size in bits */
33 uint32_t packet_size;
34
35 /* content size in bits */
36 uint32_t content_size;
37
38 /* current position from beginning of packet in bits */
39 uint32_t at;
40
41 /* packet header + context size (content offset) */
42 uint32_t off_content;
43
44 /* events discarded */
45 uint32_t events_discarded;
46
47 /* current packet is opened */
48 int packet_is_open;
49 }};'''
50
51
52 _CTX_BEGIN = '''/* context for stream "{sname}" */
53 struct {prefix}{sname}_ctx {{
54 /* parent */
55 struct {prefix}ctx parent;
56
57 /* config-specific members follow */'''
58
59
60 _CTX_END = '};'
61
62
63 _FUNC_INIT_PROTO = '''/* initialize context */
64 void {prefix}init(
65 void *ctx,
66 uint8_t *buf,
67 uint32_t buf_size,
68 struct {prefix}platform_callbacks cbs,
69 void *data
70 )'''
71
72
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);
79 {prefix}ctx->at = 0;
80 {prefix}ctx->events_discarded = 0;
81 {prefix}ctx->packet_is_open = 0;
82 }}'''
83
84
85 _FUNC_OPEN_PROTO_BEGIN = '''/* open packet for stream "{sname}" */
86 void {prefix}{sname}_open_packet(
87 struct {prefix}{sname}_ctx *ctx'''
88
89
90 _FUNC_OPEN_PROTO_END = ')'
91
92
93 _FUNC_OPEN_BODY_BEGIN = '{'
94
95
96 _FUNC_OPEN_BODY_END = '''
97 ctx->parent.off_content = ctx->parent.at;
98
99 /* mark current packet as open */
100 ctx->parent.packet_is_open = 1;
101 }'''
102
103
104 _FUNC_CLOSE_PROTO = '''/* close packet for stream "{sname}" */
105 void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)'''
106
107
108 _FUNC_CLOSE_BODY_BEGIN = '{'
109
110
111 _FUNC_CLOSE_BODY_END = '''
112 /* go back to end of packet */
113 ctx->parent.at = ctx->parent.packet_size;
114
115 /* mark packet as closed */
116 ctx->parent.packet_is_open = 0;
117 }'''
118
119
120 _FUNC_TRACE_PROTO_BEGIN = '''/* trace (stream "{sname}", event "{evname}") */
121 void {prefix}{sname}_trace_{evname}(
122 struct {prefix}{sname}_ctx *ctx'''
123
124
125 _FUNC_TRACE_PROTO_END = ')'
126
127
128 _FUNC_TRACE_BODY = '''{{
129 uint32_t ev_size;
130
131 /* get event size */
132 ev_size = _get_event_size_{sname}_{evname}((void *) ctx{params});
133
134 /* do we have enough space to serialize? */
135 if (!_reserve_event_space((void *) ctx, ev_size)) {{
136 /* no: forget this */
137 return;
138 }}
139
140 /* serialize event */
141 _serialize_event_{sname}_{evname}((void *) ctx{params});
142
143 /* commit event */
144 _commit_event((void *) ctx);
145 }}'''
146
147
148 _FUNC_GET_EVENT_SIZE_PROTO_BEGIN = '''static uint32_t _get_event_size_{sname}_{evname}(
149 struct {prefix}ctx *ctx'''
150
151
152 _FUNC_GET_EVENT_SIZE_PROTO_END = ')'
153
154
155 _FUNC_GET_EVENT_SIZE_BODY_BEGIN = '''{
156 uint32_t at = ctx->at;'''
157
158
159 _FUNC_GET_EVENT_SIZE_BODY_END = ''' return at - ctx->at;
160 }'''
161
162
163 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN = '''static void _serialize_stream_event_header_{sname}(
164 struct {prefix}ctx *ctx,
165 uint32_t event_id'''
166
167
168 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END = ')'
169
170
171 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN = '{'
172
173
174 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END = '}'
175
176
177 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN = '''static void _serialize_stream_event_context_{sname}(
178 struct {prefix}ctx *ctx'''
179
180
181 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END = ')'
182
183
184 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN = '{'
185
186
187 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END = '}'
188
189
190 _FUNC_SERIALIZE_EVENT_PROTO_BEGIN = '''static void _serialize_event_{sname}_{evname}(
191 struct {prefix}ctx *ctx'''
192
193
194 _FUNC_SERIALIZE_EVENT_PROTO_END = ')'
195
196
197 _FUNC_SERIALIZE_EVENT_BODY_BEGIN = '{'
198
199
200 _FUNC_SERIALIZE_EVENT_BODY_END = '}'
201
202
203 _HEADER_BEGIN = '''#ifndef _{ucprefix}H
204 #define _{ucprefix}H
205
206 /*
207 * The following C code was generated by barectf {version}
208 * on {date}.
209 *
210 * For more details, see <https://github.com/efficios/barectf>.
211 */
212
213 #include <stdint.h>
214
215 #include "{bitfield_header_filename}"
216
217 struct {prefix}ctx;
218
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);'''
227
228
229 _HEADER_END = '#endif /* _{ucprefix}H */'
230
231
232 _C_SRC = '''/*
233 * The following C code was generated by barectf {version}
234 * on {date}.
235 *
236 * For more details, see <https://github.com/efficios/barectf>.
237 */
238
239 #include <stdint.h>
240 #include <string.h>
241 #include <assert.h>
242
243 #include "{header_filename}"
244
245 #define _ALIGN(_at, _align) \\
246 do {{ \\
247 (_at) = ((_at) + ((_align) - 1)) & -(_align); \\
248 }} while (0)
249
250 #define _BITS_TO_BYTES(_x) ((_x) >> 3)
251 #define _BYTES_TO_BITS(_x) ((_x) << 3)
252
253 uint32_t {prefix}packet_size(void *ctx)
254 {{
255 return ((struct {prefix}ctx *) ctx)->packet_size;
256 }}
257
258 int {prefix}packet_is_full(void *ctx)
259 {{
260 struct {prefix}ctx *cctx = ctx;
261
262 return cctx->at == cctx->packet_size;
263 }}
264
265 int {prefix}packet_is_empty(void *ctx)
266 {{
267 struct {prefix}ctx *cctx = ctx;
268
269 return cctx->at <= cctx->off_content;
270 }}
271
272 uint32_t {prefix}packet_events_discarded(void *ctx)
273 {{
274 return ((struct {prefix}ctx *) ctx)->events_discarded;
275 }}
276
277 uint8_t *{prefix}packet_buf(void *ctx)
278 {{
279 return ((struct {prefix}ctx *) ctx)->buf;
280 }}
281
282 uint32_t {prefix}packet_buf_size(void *ctx)
283 {{
284 return _BITS_TO_BYTES(((struct {prefix}ctx *) ctx)->packet_size);
285 }}
286
287 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size)
288 {{
289 struct {prefix}ctx *{prefix}ctx = ctx;
290
291 {prefix}ctx->buf = buf;
292 {prefix}ctx->packet_size = _BYTES_TO_BITS(buf_size);
293 }}
294
295 int {prefix}packet_is_open(void *ctx)
296 {{
297 return ((struct {prefix}ctx *) ctx)->packet_is_open;
298 }}
299
300 static
301 void _write_cstring(struct barectf_ctx *ctx, const char *src)
302 {{
303 uint32_t sz = strlen(src) + 1;
304
305 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
306 ctx->at += _BYTES_TO_BITS(sz);
307 }}
308
309 static inline
310 int _packet_is_full(struct {prefix}ctx *ctx)
311 {{
312 return {prefix}packet_is_full(ctx);
313 }}
314
315 static
316 int _reserve_event_space(struct {prefix}ctx *ctx, uint32_t ev_size)
317 {{
318 /* event _cannot_ fit? */
319 if (ev_size > (ctx->packet_size - ctx->off_content)) {{
320 ctx->events_discarded++;
321
322 return 0;
323 }}
324
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++;
331
332 return 0;
333 }}
334
335 /* back-end is not full: open new packet */
336 ctx->cbs.open_packet(ctx->data);
337 }}
338
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);
343
344 /* is back-end full? */
345 if (ctx->cbs.is_backend_full(ctx->data)) {{
346 /* yes: discard event */
347 ctx->events_discarded++;
348
349 return 0;
350 }}
351
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));
355 }}
356
357 return 1;
358 }}
359
360 static
361 void _commit_event(struct {prefix}ctx *ctx)
362 {{
363 /* is packet full? */
364 if ({prefix}packet_is_full(ctx)) {{
365 /* yes: close it now */
366 ctx->cbs.close_packet(ctx->data);
367 }}
368 }}'''
369
370
371 _BITFIELD = '''#ifndef _$PREFIX$BITFIELD_H
372 #define _$PREFIX$BITFIELD_H
373
374 /*
375 * BabelTrace
376 *
377 * Bitfields read/write functions.
378 *
379 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
380 *
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:
387 *
388 * The above copyright notice and this permission notice shall be included in
389 * all copies or substantial portions of the Software.
390 *
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
397 * SOFTWARE.
398 */
399
400 #include <stdint.h> /* C99 5.2.4.2 Numerical limits */
401 #include <limits.h>
402
403 #define $PREFIX$BYTE_ORDER $ENDIAN_DEF$
404
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) \\
407 ({ \\
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); \\
412 \\
413 for (; sb; sb--) \\
414 ___v >>= sizeof(___v) * CHAR_BIT - 1; \\
415 ___v >>= final; \\
416 })
417
418 #define _$prefix$bt_piecewise_lshift(_v, _shift) \\
419 ({ \\
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); \\
424 \\
425 for (; sb; sb--) \\
426 ___v <<= sizeof(___v) * CHAR_BIT - 1; \\
427 ___v <<= final; \\
428 })
429
430 #define _$prefix$bt_is_signed_type(type) ((type) -1 < (type) 0)
431
432 #define _$prefix$bt_unsigned_cast(type, v) \\
433 ({ \\
434 (sizeof(v) < sizeof(type)) ? \\
435 ((type) (v)) & (~(~(type) 0 << (sizeof(v) * CHAR_BIT))) : \\
436 (type) (v); \\
437 })
438
439 /*
440 * $prefix$bt_bitfield_write - write integer to a bitfield in native endianness
441 *
442 * Save integer to the bitfield, which starts at the "start" bit, has "len"
443 * bits.
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.
448 *
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
451 * bits.
452 *
453 * On big endian, bytes are places from most significant to less significant.
454 * Also, consecutive bitfields are placed from higher to lower bits.
455 */
456
457 #define _$prefix$bt_bitfield_write_le(_ptr, type, _start, _length, _v) \\
458 do { \\
459 __typeof__(_v) __v = (_v); \\
460 type *__ptr = (void *) (_ptr); \\
461 unsigned long __start = (_start), __length = (_length); \\
462 type mask, cmask; \\
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" */ \\
466 \\
467 if (!__length) \\
468 break; \\
469 \\
470 end = __start + __length; \\
471 start_unit = __start / ts; \\
472 end_unit = (end + (ts - 1)) / ts; \\
473 \\
474 /* Trim v high bits */ \\
475 if (__length < sizeof(__v) * CHAR_BIT) \\
476 __v &= ~((~(__typeof__(__v)) 0) << __length); \\
477 \\
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)); \\
482 if (end % ts) \\
483 mask |= (~(type) 0) << (end % ts); \\
484 cmask = (type) __v << (__start % ts); \\
485 cmask &= ~mask; \\
486 __ptr[this_unit] &= mask; \\
487 __ptr[this_unit] |= cmask; \\
488 break; \\
489 } \\
490 if (__start % ts) { \\
491 cshift = __start % ts; \\
492 mask = ~((~(type) 0) << cshift); \\
493 cmask = (type) __v << cshift; \\
494 cmask &= ~mask; \\
495 __ptr[this_unit] &= mask; \\
496 __ptr[this_unit] |= cmask; \\
497 __v = _$prefix$bt_piecewise_rshift(__v, ts - cshift); \\
498 __start += ts - cshift; \\
499 this_unit++; \\
500 } \\
501 for (; this_unit < end_unit - 1; this_unit++) { \\
502 __ptr[this_unit] = (type) __v; \\
503 __v = _$prefix$bt_piecewise_rshift(__v, ts); \\
504 __start += ts; \\
505 } \\
506 if (end % ts) { \\
507 mask = (~(type) 0) << (end % ts); \\
508 cmask = (type) __v; \\
509 cmask &= ~mask; \\
510 __ptr[this_unit] &= mask; \\
511 __ptr[this_unit] |= cmask; \\
512 } else \\
513 __ptr[this_unit] = (type) __v; \\
514 } while (0)
515
516 #define _$prefix$bt_bitfield_write_be(_ptr, type, _start, _length, _v) \\
517 do { \\
518 __typeof__(_v) __v = (_v); \\
519 type *__ptr = (void *) (_ptr); \\
520 unsigned long __start = (_start), __length = (_length); \\
521 type mask, cmask; \\
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" */ \\
525 \\
526 if (!__length) \\
527 break; \\
528 \\
529 end = __start + __length; \\
530 start_unit = __start / ts; \\
531 end_unit = (end + (ts - 1)) / ts; \\
532 \\
533 /* Trim v high bits */ \\
534 if (__length < sizeof(__v) * CHAR_BIT) \\
535 __v &= ~((~(__typeof__(__v)) 0) << __length); \\
536 \\
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)); \\
541 if (__start % ts) \\
542 mask |= (~((type) 0)) << (ts - (__start % ts)); \\
543 cmask = (type) __v << ((ts - (end % ts)) % ts); \\
544 cmask &= ~mask; \\
545 __ptr[this_unit] &= mask; \\
546 __ptr[this_unit] |= cmask; \\
547 break; \\
548 } \\
549 if (end % ts) { \\
550 cshift = end % ts; \\
551 mask = ~((~(type) 0) << (ts - cshift)); \\
552 cmask = (type) __v << (ts - cshift); \\
553 cmask &= ~mask; \\
554 __ptr[this_unit] &= mask; \\
555 __ptr[this_unit] |= cmask; \\
556 __v = _$prefix$bt_piecewise_rshift(__v, cshift); \\
557 end -= cshift; \\
558 this_unit--; \\
559 } \\
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); \\
563 end -= ts; \\
564 } \\
565 if (__start % ts) { \\
566 mask = (~(type) 0) << (ts - (__start % ts)); \\
567 cmask = (type) __v; \\
568 cmask &= ~mask; \\
569 __ptr[this_unit] &= mask; \\
570 __ptr[this_unit] |= cmask; \\
571 } else \\
572 __ptr[this_unit] = (type) __v; \\
573 } while (0)
574
575 /*
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
578 */
579
580 #if ($PREFIX$BYTE_ORDER == LITTLE_ENDIAN)
581
582 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v) \\
583 _$prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v)
584
585 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v) \\
586 _$prefix$bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v)
587
588 #elif ($PREFIX$BYTE_ORDER == BIG_ENDIAN)
589
590 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v) \\
591 _$prefix$bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v)
592
593 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v) \\
594 _$prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v)
595
596 #else /* ($PREFIX$BYTE_ORDER == PDP_ENDIAN) */
597
598 #error "Byte order not supported"
599
600 #endif
601
602 #endif /* _$PREFIX$BITFIELD_H */
603 '''
This page took 0.04103 seconds and 5 git commands to generate.