barectf/templates/metadata/*.j2: normalize
[deliverable/barectf.git] / barectf / templates / c / barectf.c.j2
CommitLineData
d6483c83
PP
1{% import 'common.j2' as common %}
2{% import 'c/common.j2' as c_common %}
3{% import 'c/barectf.c-macros.j2' as macros %}
4{% set prefix = common.prefix %}
5{% set ucprefix = common.ucprefix %}
6{% set ctx_struct_name = c_common.ctx_struct_name %}
7{% set cg_opts = cfg.options.code_generation_options %}
8/*
9 * The MIT License (MIT)
10 *
11 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34 *
35 * The following C code was generated by barectf v{{ barectf_version.__version__ }}
36 * on {{ common.gen_date }}.
37 *
38 * For more details, see <https://barectf.org/>.
39 */
40
41#include <stdint.h>
42#include <string.h>
43#include <assert.h>
44
45#include "{{ header_file_name }}"
46#include "{{ bitfield_header_file_name }}"
47
48#define _ALIGN(_at, _align) \
49 do { \
50 (_at) = ((_at) + ((_align) - 1)) & -(_align); \
51 } while (0)
52
53#ifdef __cplusplus
54# define _TO_VOID_PTR(_value) static_cast<void *>(_value)
55# define _FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value)
56#else
57# define _TO_VOID_PTR(_value) ((void *) (_value))
58# define _FROM_VOID_PTR(_type, _value) ((_type *) (_value))
59#endif
60
61#define _BITS_TO_BYTES(_x) ((_x) >> 3)
62#define _BYTES_TO_BITS(_x) ((_x) << 3)
63
64union _f2u {
65 float f;
66 uint32_t u;
67};
68
69union _d2u {
70 double f;
71 uint64_t u;
72};
73
74uint32_t {{ prefix }}packet_size(void *ctx)
75{
76 return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, ctx)->packet_size;
77}
78
79int {{ prefix }}packet_is_full(void *vctx)
80{
81 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
82
83 return ctx->at == ctx->packet_size;
84}
85
86int {{ prefix }}packet_is_empty(void *vctx)
87{
88 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
89
90 return ctx->at <= ctx->off_content;
91}
92
93uint32_t {{ prefix }}packet_events_discarded(void *vctx)
94{
95 return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->events_discarded;
96}
97
98uint8_t *{{ prefix }}packet_buf(void *vctx)
99{
100 return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->buf;
101}
102
103uint32_t {{ prefix }}packet_buf_size(void *vctx)
104{
105 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
106
107 return _BITS_TO_BYTES(ctx->packet_size);
108}
109
110void {{ prefix }}packet_set_buf(void *vctx, uint8_t *buf, uint32_t buf_size)
111{
112 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
113
114 ctx->buf = buf;
115 ctx->packet_size = _BYTES_TO_BITS(buf_size);
116}
117
118int {{ prefix }}packet_is_open(void *vctx)
119{
120 return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->packet_is_open;
121}
122
123int {{ prefix }}is_in_tracing_section(void *vctx)
124{
125 return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->in_tracing_section;
126}
127
128volatile const int *{{ prefix }}is_in_tracing_section_ptr(void *vctx)
129{
130 return &_FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->in_tracing_section;
131}
132
133int {{ prefix }}is_tracing_enabled(void *vctx)
134{
135 return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->is_tracing_enabled;
136}
137
138void {{ prefix }}enable_tracing(void *vctx, int enable)
139{
140 _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->is_tracing_enabled = enable;
141}
142
143static
144void _write_c_str(struct {{ ctx_struct_name }} *ctx, const char *src)
145{
146 uint32_t sz = strlen(src) + 1;
147
148 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
149 ctx->at += _BYTES_TO_BITS(sz);
150}
151
152static
153int _reserve_ev_space(void *vctx, uint32_t ev_size)
154{
155 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
156
157 /* event _cannot_ fit? */
158 if (ev_size > (ctx->packet_size - ctx->off_content)) {
159 ctx->events_discarded++;
160 return 0;
161 }
162
163 /* packet is full? */
164 if ({{ prefix }}packet_is_full(ctx)) {
165 /* yes: is back-end full? */
166 if (ctx->cbs.is_backend_full(ctx->data)) {
167 /* yes: discard event */
168 ctx->events_discarded++;
169 return 0;
170 }
171
172 /* back-end is not full: open new packet */
173 ctx->use_cur_last_event_ts = 1;
174 ctx->cbs.open_packet(ctx->data);
175 ctx->use_cur_last_event_ts = 0;
176 }
177
178 /* event fits the current packet? */
179 if (ev_size > (ctx->packet_size - ctx->at)) {
180 /* no: close packet now */
181 ctx->use_cur_last_event_ts = 1;
182 ctx->cbs.close_packet(ctx->data);
183 ctx->use_cur_last_event_ts = 0;
184
185 /* is back-end full? */
186 if (ctx->cbs.is_backend_full(ctx->data)) {
187 /* yes: discard event */
188 ctx->events_discarded++;
189 return 0;
190 }
191
192 /* back-end is not full: open new packet */
193 ctx->use_cur_last_event_ts = 1;
194 ctx->cbs.open_packet(ctx->data);
195 ctx->use_cur_last_event_ts = 0;
196 assert(ev_size <= (ctx->packet_size - ctx->at));
197 }
198
199 return 1;
200}
201
202static
203void _commit_ev(void *vctx)
204{
205 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
206
207 /* is packet full? */
208 if ({{ prefix }}packet_is_full(ctx)) {
209 /* yes: close it now */
210 ctx->cbs.close_packet(ctx->data);
211 }
212}
213
214{% include 'c/ctx-init-func-proto.j2' %}
215
216{
217 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
218 ctx->cbs = cbs;
219 ctx->data = data;
220 ctx->buf = buf;
221 ctx->packet_size = _BYTES_TO_BITS(buf_size);
222 ctx->at = 0;
223 ctx->events_discarded = 0;
224 ctx->packet_is_open = 0;
225 ctx->in_tracing_section = 0;
226 ctx->is_tracing_enabled = 1;
227 ctx->use_cur_last_event_ts = 0;
228}
229
230{% for stream_type in cfg.trace.type.stream_types | sort %}
231 {% set def_clk_type = stream_type.default_clock_type %}
232 {% set sctx_name %}{{ prefix }}{{ stream_type.name }}{% endset %}
233 {% set this_stream_ops = stream_ops[stream_type] %}
234 {% include 'c/open-func-proto.j2' %}
235
236{
237 {{ macros.open_close_func_preamble(stream_type) | indent_tab }}
238
239 /*
240 * This function is either called by a tracing function, or
241 * directly by the platform.
242 *
243 * If it's called by a tracing function, then
244 * `ctx->in_tracing_section` is 1, so it's safe to open
245 * the packet here (alter the packet), even if tracing was
246 * disabled in the meantime because we're already in a tracing
247 * section (which finishes at the end of the tracing function
248 * call).
249 *
250 * If it's called directly by the platform, then if tracing is
251 * disabled, we don't want to alter the packet, and return
252 * immediately.
253 */
254 if (!ctx->is_tracing_enabled && !saved_in_tracing_section) {
255 ctx->in_tracing_section = 0;
256 return;
257 }
258
259 /* we can alter the packet */
260 ctx->in_tracing_section = 1;
261
262 /* do not open a packet that is already open */
263 if (ctx->packet_is_open) {
264 ctx->in_tracing_section = saved_in_tracing_section;
265 return;
266 }
267
268 ctx->at = 0;
269 {% set pkt_header_ops = this_stream_ops.pkt_header_ops %}
270 {% if pkt_header_ops %}
271
272 /* serialize packet header */
273 {
274 {% for op in pkt_header_ops %}
275 {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }}
276
277 {% endfor %}
278 }
279 {% endif %}
280
281 /* serialize packet context */
282 {
283 {% for op in this_stream_ops.pkt_ctx_ops %}
284 {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }}
285
286 {% endfor %}
287 }
288
289 /* save content beginning's offset */
290 ctx->off_content = ctx->at;
291
292 /* mark current packet as open */
293 ctx->packet_is_open = 1;
294
295 /* not tracing anymore */
296 ctx->in_tracing_section = saved_in_tracing_section;
297}
298
299 {% include 'c/close-func-proto.j2' %}
300
301{
302 {{ macros.open_close_func_preamble(stream_type) | indent_tab }}
303
304 /*
305 * This function is either called by a tracing function, or
306 * directly by the platform.
307 *
308 * If it's called by a tracing function, then
309 * `ctx->in_tracing_section` is 1, so it's safe to close
310 * the packet here (alter the packet), even if tracing was
311 * disabled in the meantime, because we're already in a tracing
312 * section (which finishes at the end of the tracing function
313 * call).
314 *
315 * If it's called directly by the platform, then if tracing is
316 * disabled, we don't want to alter the packet, and return
317 * immediately.
318 */
319 if (!ctx->is_tracing_enabled && !saved_in_tracing_section) {
320 ctx->in_tracing_section = 0;
321 return;
322 }
323
324 /* we can alter the packet */
325 ctx->in_tracing_section = 1;
326
327 /* do not close a packet that is not open */
328 if (!ctx->packet_is_open) {
329 ctx->in_tracing_section = saved_in_tracing_section;
330 return;
331 }
332
333 /* save content size */
334 ctx->content_size = ctx->at;
335 {% if 'timestamp_end' in stream_type._pkt_ctx_ft.members %}
336 {% set op = stream_op_pkt_ctx_op(stream_type, 'timestamp_end') %}
337
338 /* go back to `timestamp_end` field offset */
339 ctx->at = sctx->off_{{ c_common.op_src(op) }};
340
341 {% set src = 'ts' %}
342 {% filter indent_tab(indent_first=True) %}
343 {% include 'c/serialize-write-saved-int-statements.j2' %}
344
345 {% endfilter %}
346 {% endif %}
347 {% if 'content_size' in stream_type._pkt_ctx_ft.members %}
348 {% set op = stream_op_pkt_ctx_op(stream_type, 'content_size') %}
349
350 /* go back to `content_size` field offset */
351 ctx->at = sctx->off_{{ c_common.op_src(op) }};
352
353 {% set src = 'ctx->content_size' %}
354 {% filter indent_tab(indent_first=True) %}
355 {% include 'c/serialize-write-saved-int-statements.j2' %}
356
357 {% endfilter %}
358 {% endif %}
359 {% if 'events_discarded' in stream_type._pkt_ctx_ft.members %}
360 {% set op = stream_op_pkt_ctx_op(stream_type, 'events_discarded') %}
361
362 /* go back to `events_discarded` field offset */
363 ctx->at = sctx->off_{{ c_common.op_src(op) }};
364
365 {% set src = 'ctx->events_discarded' %}
366 {% filter indent_tab(indent_first=True) %}
367 {% include 'c/serialize-write-saved-int-statements.j2' %}
368
369 {% endfilter %}
370 {% endif %}
371
372 /* go back to end of packet */
373 ctx->at = ctx->packet_size;
374
375 /* mark packet as closed */
376 ctx->packet_is_open = 0;
377
378 /* not tracing anymore */
379 ctx->in_tracing_section = saved_in_tracing_section;
380}
381 {% if stream_type._ev_header_ft %}
382
383static void _serialize_ev_header_{{ stream_type.name }}(void *vctx,
384 uint32_t ev_type_id)
385{
386 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
387 {% if def_clk_type %}
388 struct {{ sctx_name }}_ctx *sctx = _FROM_VOID_PTR(struct {{ sctx_name }}_ctx, vctx);
389 const {{ cg_opts.clock_type_c_types[def_clk_type] }} ts = sctx->cur_last_event_ts;
390 {% endif %}
391
392 /* serialize event header */
393 {
394 {% for op in this_stream_ops.ev_header_ops %}
395 {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }}
396
397 {% endfor %}
398 }
399}
400 {% endif %}
401 {% if stream_type.event_common_context_field_type %}
402
403static void _serialize_ev_common_ctx_{{ stream_type.name }}(void *vctx{{ stream_type | serialize_ev_common_ctx_func_params_str }})
404{
405 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
406
407 /* serialize event common context */
408 {
409 {% for op in this_stream_ops.ev_common_ctx_ops %}
410 {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }}
411
412 {% endfor %}
413 }
414}
415 {% endif %}
416 {# internal serialization functions #}
417 {% for ev_type in stream_type.event_types | sort %}
418
419static void _serialize_ev_{{ stream_type.name }}_{{ ev_type.name }}(void *vctx{{ (stream_type, ev_type) | trace_func_params_str }})
420{
421 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
422 {% if stream_type._ev_header_ft %}
423
424 /* serialize header */
425 _serialize_ev_header_{{ stream_type.name }}(ctx, {{ ev_type.id }});
426 {% endif %}
427 {% if stream_type.event_common_context_field_type %}
428
429 /* serialize common context */
430 {% set params = macros.ft_call_params(root_ft_prefixes.SEC, stream_type.event_common_context_field_type) %}
431 _serialize_ev_common_ctx_{{ stream_type.name }}(ctx{{ params }});
432 {% endif %}
433 {% set this_ev_ops = this_stream_ops.ev_ops[ev_type] %}
434 {% if this_ev_ops.spec_ctx_ops %}
435
436 /* serialize specific context */
437 {
438 {% for op in this_ev_ops.spec_ctx_ops %}
439 {{ op.serialize_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }}
440
441 {% endfor %}
442 }
443 {% endif %}
444 {% if this_ev_ops.payload_ops %}
445
446 /* serialize payload */
447 {
448 {% for op in this_ev_ops.payload_ops %}
449 {{ op.serialize_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }}
450
451 {% endfor %}
452 }
453 {% endif %}
454}
455 {% endfor %}
456 {# internal size functions #}
457 {% for ev_type in stream_type.event_types | sort %}
458 {% set this_ev_ops = this_stream_ops.ev_ops[ev_type] %}
459
460static uint32_t _ev_size_{{ stream_type.name }}_{{ ev_type.name }}(void *vctx{{ (stream_type, ev_type) | trace_func_params_str }})
461{
462 struct {{ ctx_struct_name }} *ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx);
463 uint32_t at = ctx->at;
464 {% if this_stream_ops.ev_header_ops %}
465
466 /* add header size */
467 {
468 {% for op in this_stream_ops.ev_header_ops %}
469 {{ op.size_str(stream_type=stream_type) | indent_tab(2) }}
470
471 {% endfor %}
472 }
473 {% endif %}
474 {% if this_stream_ops.ev_common_ctx_ops %}
475
476 /* add common context size */
477 {
478 {% for op in this_stream_ops.ev_common_ctx_ops %}
479 {{ op.size_str(stream_type=stream_type) | indent_tab(2) }}
480
481 {% endfor %}
482 }
483 {% endif %}
484 {% if this_ev_ops.spec_ctx_ops %}
485
486 /* add specific context size */
487 {
488 {% for op in this_ev_ops.spec_ctx_ops %}
489 {{ op.size_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }}
490
491 {% endfor %}
492 }
493 {% endif %}
494 {% if this_ev_ops.payload_ops %}
495
496 /* add payload size */
497 {
498 {% for op in this_ev_ops.payload_ops %}
499 {{ op.size_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }}
500
501 {% endfor %}
502 }
503 {% endif %}
504
505 return at - ctx->at;
506}
507 {% endfor %}
508 {# public tracing functions #}
509 {% for ev_type in stream_type.event_types | sort %}
510
511 {% include 'c/trace-func-proto.j2' %}
512
513{
514 struct {{ ctx_struct_name }} *ctx = &sctx->parent;
515 uint32_t ev_size;
516
517 {% if def_clk_type %}
518 /* save time */
519 sctx->cur_last_event_ts = ctx->cbs.{{ def_clk_type.name }}_clock_get_value(ctx->data);
520
521 {% endif %}
522
523 if (!ctx->is_tracing_enabled) {
524 return;
525 }
526
527 /* we can alter the packet */
528 ctx->in_tracing_section = 1;
529
530 /* compute event size */
531 {% set ev_common_ctx_params = macros.ft_call_params(root_ft_prefixes.SEC, stream_type.event_common_context_field_type) %}
532 {% set spec_ctx_params = macros.ft_call_params(root_ft_prefixes.EC, ev_type.specific_context_field_type) %}
533 {% set payload_params = macros.ft_call_params(root_ft_prefixes.EP, ev_type.payload_field_type) %}
534 {% set params %}{{ ev_common_ctx_params }}{{ spec_ctx_params }}{{ payload_params }}{% endset %}
535 ev_size = _ev_size_{{ stream_type.name }}_{{ ev_type.name }}(_TO_VOID_PTR(ctx){{ params }});
536
537 /* do we have enough space to serialize? */
538 if (!_reserve_ev_space(_TO_VOID_PTR(ctx), ev_size)) {
539 /* no: forget this */
540 ctx->in_tracing_section = 0;
541 return;
542 }
543
544 /* serialize event */
545 _serialize_ev_{{ stream_type.name }}_{{ ev_type.name }}(_TO_VOID_PTR(ctx){{ params }});
546
547 /* commit event */
548 _commit_ev(_TO_VOID_PTR(ctx));
549
550 /* not tracing anymore */
551 ctx->in_tracing_section = 0;
552}
553 {% endfor %}
554{% endfor %}
This page took 0.044364 seconds and 4 git commands to generate.