Fixing the missing initialization of the field 'initialized' in the global context...
[barectf.git] / barectf / templates.py
CommitLineData
e5aa0be3
PP
1_CLOCK_CB = '{return_ctype} (*{cname}_clock_get_value)(void *);'
2
3
4_PLATFORM_CALLBACKS_BEGIN = '''/* barectf platform callbacks */
5struct {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 */
22struct {prefix}ctx {{
23 /* platform callbacks */
24 struct {prefix}platform_callbacks cbs;
25
26 /* platform data (passed to callbacks) */
27 void *data;
28
67bd189f 29 /* output buffer (will contain a CTF binary packet) */
e5aa0be3 30 uint8_t *buf;
67bd189f 31
e5aa0be3 32 /* packet size in bits */
8079a626 33 uint32_t packet_size;
67bd189f 34
e5aa0be3
PP
35 /* content size in bits */
36 uint32_t content_size;
37
38 /* current position from beginning of packet in bits */
67bd189f
PP
39 uint32_t at;
40
e5aa0be3
PP
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}" */
53struct {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 */
64void {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}" */
86void {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}" */
105void {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}") */
121void {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'''
df892ed5 166
df892ed5 167
e5aa0be3 168_FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END = ')'
67bd189f 169
df892ed5 170
e5aa0be3 171_FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN = '{'
df892ed5 172
df892ed5 173
e5aa0be3 174_FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END = '}'
df892ed5 175
6b9ba5f3 176
e5aa0be3
PP
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 */
67bd189f
PP
212
213#include <stdint.h>
214
e5aa0be3 215#include "{bitfield_header_filename}"
445687b2 216
e5aa0be3 217struct {prefix}ctx;
67bd189f 218
e5aa0be3
PP
219uint32_t {prefix}packet_size(void *ctx);
220int {prefix}packet_is_full(void *ctx);
221int {prefix}packet_is_empty(void *ctx);
222uint32_t {prefix}packet_events_discarded(void *ctx);
223uint8_t *{prefix}packet_buf(void *ctx);
224void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size);
225uint32_t {prefix}packet_buf_size(void *ctx);
226int {prefix}packet_is_open(void *ctx);'''
67bd189f 227
67bd189f 228
e5aa0be3 229_HEADER_END = '#endif /* _{ucprefix}H */'
67bd189f 230
67bd189f 231
e5aa0be3
PP
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 */
445687b2 238
e5aa0be3 239#include <stdint.h>
8079a626 240#include <string.h>
e5aa0be3
PP
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)
8079a626 249
e5aa0be3
PP
250#define _BITS_TO_BYTES(_x) ((_x) >> 3)
251#define _BYTES_TO_BITS(_x) ((_x) << 3)
445687b2 252
e5aa0be3
PP
253uint32_t {prefix}packet_size(void *ctx)
254{{
255 return ((struct {prefix}ctx *) ctx)->packet_size;
256}}
9a0782f7 257
e5aa0be3
PP
258int {prefix}packet_is_full(void *ctx)
259{{
260 struct {prefix}ctx *cctx = ctx;
261
262 return cctx->at == cctx->packet_size;
263}}
264
265int {prefix}packet_is_empty(void *ctx)
266{{
267 struct {prefix}ctx *cctx = ctx;
268
269 return cctx->at <= cctx->off_content;
270}}
271
272uint32_t {prefix}packet_events_discarded(void *ctx)
273{{
274 return ((struct {prefix}ctx *) ctx)->events_discarded;
275}}
276
277uint8_t *{prefix}packet_buf(void *ctx)
278{{
279 return ((struct {prefix}ctx *) ctx)->buf;
280}}
281
282uint32_t {prefix}packet_buf_size(void *ctx)
283{{
284 return _BITS_TO_BYTES(((struct {prefix}ctx *) ctx)->packet_size);
285}}
286
287void {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
295int {prefix}packet_is_open(void *ctx)
296{{
297 return ((struct {prefix}ctx *) ctx)->packet_is_open;
298}}
299
300static
301void _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
309static inline
310int _packet_is_full(struct {prefix}ctx *ctx)
311{{
312 return {prefix}packet_is_full(ctx);
313}}
314
315static
316int _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
360static
361void _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
9a0782f7
PP
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 */
8079a626 401#include <limits.h>
9a0782f7 402
e5aa0be3 403#define $PREFIX$BYTE_ORDER $ENDIAN_DEF$
9a0782f7
PP
404
405/* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
e5aa0be3 406#define _$prefix$bt_piecewise_rshift(_v, _shift) \\
9a0782f7 407({ \\
e5aa0be3
PP
408 __typeof__(_v) ___v = (_v); \\
409 __typeof__(_shift) ___shift = (_shift); \\
9a0782f7
PP
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
e5aa0be3 418#define _$prefix$bt_piecewise_lshift(_v, _shift) \\
9a0782f7 419({ \\
e5aa0be3
PP
420 __typeof__(_v) ___v = (_v); \\
421 __typeof__(_shift) ___shift = (_shift); \\
9a0782f7
PP
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
e5aa0be3 430#define _$prefix$bt_is_signed_type(type) ((type) -1 < (type) 0)
9a0782f7 431
e5aa0be3 432#define _$prefix$bt_unsigned_cast(type, v) \\
9a0782f7
PP
433({ \\
434 (sizeof(v) < sizeof(type)) ? \\
435 ((type) (v)) & (~(~(type) 0 << (sizeof(v) * CHAR_BIT))) : \\
436 (type) (v); \\
437})
438
439/*
e5aa0be3 440 * $prefix$bt_bitfield_write - write integer to a bitfield in native endianness
9a0782f7
PP
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
e5aa0be3 457#define _$prefix$bt_bitfield_write_le(_ptr, type, _start, _length, _v) \\
9a0782f7 458do { \\
e5aa0be3 459 __typeof__(_v) __v = (_v); \\
9a0782f7
PP
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) \\
e5aa0be3 476 __v &= ~((~(__typeof__(__v)) 0) << __length); \\
9a0782f7
PP
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; \\
e5aa0be3 497 __v = _$prefix$bt_piecewise_rshift(__v, ts - cshift); \\
9a0782f7
PP
498 __start += ts - cshift; \\
499 this_unit++; \\
500 } \\
501 for (; this_unit < end_unit - 1; this_unit++) { \\
502 __ptr[this_unit] = (type) __v; \\
e5aa0be3 503 __v = _$prefix$bt_piecewise_rshift(__v, ts); \\
9a0782f7
PP
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
e5aa0be3 516#define _$prefix$bt_bitfield_write_be(_ptr, type, _start, _length, _v) \\
9a0782f7 517do { \\
e5aa0be3 518 __typeof__(_v) __v = (_v); \\
9a0782f7
PP
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) \\
e5aa0be3 535 __v &= ~((~(__typeof__(__v)) 0) << __length); \\
9a0782f7
PP
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; \\
e5aa0be3 556 __v = _$prefix$bt_piecewise_rshift(__v, cshift); \\
9a0782f7
PP
557 end -= cshift; \\
558 this_unit--; \\
559 } \\
560 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \\
561 __ptr[this_unit] = (type) __v; \\
e5aa0be3 562 __v = _$prefix$bt_piecewise_rshift(__v, ts); \\
9a0782f7
PP
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/*
e5aa0be3
PP
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
9a0782f7
PP
578 */
579
e5aa0be3 580#if ($PREFIX$BYTE_ORDER == LITTLE_ENDIAN)
9a0782f7 581
e5aa0be3
PP
582#define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v) \\
583 _$prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v)
9a0782f7 584
e5aa0be3
PP
585#define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v) \\
586 _$prefix$bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v)
9a0782f7 587
e5aa0be3 588#elif ($PREFIX$BYTE_ORDER == BIG_ENDIAN)
9a0782f7 589
e5aa0be3
PP
590#define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _v) \\
591 _$prefix$bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v)
9a0782f7 592
e5aa0be3
PP
593#define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v) \\
594 _$prefix$bt_bitfield_write_be(ptr, type, _start, _length, _v)
9a0782f7 595
e5aa0be3 596#else /* ($PREFIX$BYTE_ORDER == PDP_ENDIAN) */
9a0782f7
PP
597
598#error "Byte order not supported"
599
600#endif
601
e5aa0be3
PP
602#endif /* _$PREFIX$BITFIELD_H */
603'''
This page took 0.052307 seconds and 4 git commands to generate.