_CCodeGenerator.generate_header(): use Jinja 2 templates
[deliverable/barectf.git] / barectf / templates.py
1 # The MIT License (MIT)
2 #
3 # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
4 #
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:
12 #
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15 #
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.
23
24 _FUNC_INIT_PROTO = '''/* initialize context */
25 void {prefix}init(
26 void *vctx,
27 uint8_t *buf,
28 uint32_t buf_size,
29 struct {prefix}platform_callbacks cbs,
30 void *data
31 )'''
32
33
34 _FUNC_INIT_BODY = '''{{
35 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
36 ctx->cbs = cbs;
37 ctx->data = data;
38 ctx->buf = buf;
39 ctx->packet_size = _BYTES_TO_BITS(buf_size);
40 ctx->at = 0;
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;
46 }}'''
47
48
49 _FUNC_OPEN_PROTO_BEGIN = '''/* open packet for stream `{sname}` */
50 void {prefix}{sname}_open_packet(
51 struct {prefix}{sname}_ctx *ctx'''
52
53
54 _FUNC_OPEN_PROTO_END = ')'
55
56
57 _FUNC_OPEN_BODY_BEGIN = '''{{
58 {ts}
59 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
60
61 /*
62 * This function is either called by a tracing function, or
63 * directly by the platform.
64 *
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
70 * call).
71 *
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
74 * immediately.
75 */
76 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
77 ctx->parent.in_tracing_section = 0;
78 return;
79 }}
80
81 /* we can modify the packet */
82 ctx->parent.in_tracing_section = 1;
83 '''
84
85
86 _FUNC_OPEN_BODY_END = '''
87 /* save content beginning's offset */
88 ctx->parent.off_content = ctx->parent.at;
89
90 /* mark current packet as open */
91 ctx->parent.packet_is_open = 1;
92
93 /* not tracing anymore */
94 ctx->parent.in_tracing_section = saved_in_tracing_section;
95 }'''
96
97
98 _FUNC_CLOSE_PROTO = '''/* close packet for stream `{sname}` */
99 void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)'''
100
101
102 _FUNC_CLOSE_BODY_BEGIN = '''{{
103 {ts}
104 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
105
106 /*
107 * This function is either called by a tracing function, or
108 * directly by the platform.
109 *
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
115 * call).
116 *
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
119 * immediately.
120 */
121 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
122 ctx->parent.in_tracing_section = 0;
123 return;
124 }}
125
126 /* we can modify the packet */
127 ctx->parent.in_tracing_section = 1;
128 '''
129
130
131 _FUNC_CLOSE_BODY_END = '''
132 /* go back to end of packet */
133 ctx->parent.at = ctx->parent.packet_size;
134
135 /* mark packet as closed */
136 ctx->parent.packet_is_open = 0;
137
138 /* not tracing anymore */
139 ctx->parent.in_tracing_section = saved_in_tracing_section;
140 }'''
141
142
143 _FUNC_TRACE_PROTO_BEGIN = '''/* trace (stream `{sname}`, event `{evname}`) */
144 void {prefix}{sname}_trace_{evname}(
145 struct {prefix}{sname}_ctx *ctx'''
146
147
148 _FUNC_TRACE_PROTO_END = ')'
149
150
151 _FUNC_TRACE_BODY = '''{{
152 uint32_t ev_size;
153
154 /* save timestamp */
155 {save_ts}
156
157 if (!ctx->parent.is_tracing_enabled) {{
158 return;
159 }}
160
161 /* we can modify the packet */
162 ctx->parent.in_tracing_section = 1;
163
164 /* get event size */
165 ev_size = _get_event_size_{sname}_{evname}(TO_VOID_PTR(ctx){params});
166
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;
171 return;
172 }}
173
174 /* serialize event */
175 _serialize_event_{sname}_{evname}(TO_VOID_PTR(ctx){params});
176
177 /* commit event */
178 _commit_event(TO_VOID_PTR(ctx));
179
180 /* not tracing anymore */
181 ctx->parent.in_tracing_section = 0;
182 }}'''
183
184
185 _FUNC_GET_EVENT_SIZE_PROTO_BEGIN = '''static uint32_t _get_event_size_{sname}_{evname}(
186 void *vctx'''
187
188
189 _FUNC_GET_EVENT_SIZE_PROTO_END = ')'
190
191
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;'''
195
196
197 _FUNC_GET_EVENT_SIZE_BODY_END = ''' return at - ctx->at;
198 }'''
199
200
201 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN = '''static void _serialize_stream_event_header_{sname}(
202 void *vctx,
203 uint32_t event_id'''
204
205
206 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END = ')'
207
208
209 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN = '''{{
210 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
211
212
213 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END = '}'
214
215
216 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN = '''static void _serialize_stream_event_context_{sname}(
217 void *vctx'''
218
219
220 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END = ')'
221
222
223 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN = '''{{
224 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
225
226
227 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END = '}'
228
229
230 _FUNC_SERIALIZE_EVENT_PROTO_BEGIN = '''static void _serialize_event_{sname}_{evname}(
231 void *vctx'''
232
233
234 _FUNC_SERIALIZE_EVENT_PROTO_END = ')'
235
236
237 _FUNC_SERIALIZE_EVENT_BODY_BEGIN = '''{{
238 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
239
240
241 _FUNC_SERIALIZE_EVENT_BODY_END = '}'
242
243
244 _C_SRC = '''/*
245 * The MIT License (MIT)
246 *
247 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
248 *
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:
256 *
257 * The above copyright notice and this permission notice shall be
258 * included in all copies or substantial portions of the Software.
259 *
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
267 * SOFTWARE.
268 *
269 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
270 *
271 * The following C code was generated by barectf {version}
272 * on {date}.
273 *
274 * For more details, see <http://barectf.org>.
275 */
276
277 #include <stdint.h>
278 #include <string.h>
279 #include <assert.h>
280
281 #include "{header_filename}"
282 #include "{bitfield_header_filename}"
283
284 #define _ALIGN(_at, _align) \\
285 do {{ \\
286 (_at) = ((_at) + ((_align) - 1)) & -(_align); \\
287 }} while (0)
288
289 #ifdef __cplusplus
290 # define TO_VOID_PTR(_value) static_cast<void *>(_value)
291 # define FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value)
292 #else
293 # define TO_VOID_PTR(_value) ((void *) (_value))
294 # define FROM_VOID_PTR(_type, _value) ((_type *) (_value))
295 #endif
296
297 #define _BITS_TO_BYTES(_x) ((_x) >> 3)
298 #define _BYTES_TO_BITS(_x) ((_x) << 3)
299
300 union f2u {{
301 float f;
302 uint32_t u;
303 }};
304
305 union d2u {{
306 double f;
307 uint64_t u;
308 }};
309
310 uint32_t {prefix}packet_size(void *ctx)
311 {{
312 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_size;
313 }}
314
315 int {prefix}packet_is_full(void *ctx)
316 {{
317 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
318
319 return cctx->at == cctx->packet_size;
320 }}
321
322 int {prefix}packet_is_empty(void *ctx)
323 {{
324 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
325
326 return cctx->at <= cctx->off_content;
327 }}
328
329 uint32_t {prefix}packet_events_discarded(void *ctx)
330 {{
331 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->events_discarded;
332 }}
333
334 uint8_t *{prefix}packet_buf(void *ctx)
335 {{
336 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->buf;
337 }}
338
339 uint32_t {prefix}packet_buf_size(void *ctx)
340 {{
341 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
342
343 return _BITS_TO_BYTES(cctx->packet_size);
344 }}
345
346 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size)
347 {{
348 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
349
350 cctx->buf = buf;
351 cctx->packet_size = _BYTES_TO_BITS(buf_size);
352 }}
353
354 int {prefix}packet_is_open(void *ctx)
355 {{
356 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_is_open;
357 }}
358
359 int {prefix}is_in_tracing_section(void *ctx)
360 {{
361 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
362 }}
363
364 volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx)
365 {{
366 return &FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
367 }}
368
369 int {prefix}is_tracing_enabled(void *ctx)
370 {{
371 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled;
372 }}
373
374 void {prefix}enable_tracing(void *ctx, int enable)
375 {{
376 FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled = enable;
377 }}
378
379 static
380 void _write_cstring(struct {prefix}ctx *ctx, const char *src)
381 {{
382 uint32_t sz = strlen(src) + 1;
383
384 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
385 ctx->at += _BYTES_TO_BITS(sz);
386 }}
387
388 static
389 int _reserve_event_space(void *vctx, uint32_t ev_size)
390 {{
391 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
392
393 /* event _cannot_ fit? */
394 if (ev_size > (ctx->packet_size - ctx->off_content)) {{
395 ctx->events_discarded++;
396
397 return 0;
398 }}
399
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++;
406
407 return 0;
408 }}
409
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;
414 }}
415
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;
422
423 /* is back-end full? */
424 if (ctx->cbs.is_backend_full(ctx->data)) {{
425 /* yes: discard event */
426 ctx->events_discarded++;
427
428 return 0;
429 }}
430
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));
436 }}
437
438 return 1;
439 }}
440
441 static
442 void _commit_event(void *vctx)
443 {{
444 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
445
446 /* is packet full? */
447 if ({prefix}packet_is_full(ctx)) {{
448 /* yes: close it now */
449 ctx->cbs.close_packet(ctx->data);
450 }}
451 }}'''
This page took 0.037913 seconds and 4 git commands to generate.