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