Commit | Line | Data |
---|---|---|
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 | ||
88 | union _f2u { | |
89 | float f; | |
90 | uint32_t u; | |
91 | }; | |
92 | ||
93 | union _d2u { | |
94 | double f; | |
95 | uint64_t u; | |
96 | }; | |
97 | ||
98 | uint32_t {{ prefix }}packet_size(void *ctx) | |
99 | { | |
100 | return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, ctx)->packet_size; | |
101 | } | |
102 | ||
103 | int {{ 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 | ||
110 | int {{ 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 | ||
117 | uint32_t {{ prefix }}packet_events_discarded(void *vctx) | |
118 | { | |
119 | return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->events_discarded; | |
120 | } | |
121 | ||
122 | uint8_t *{{ prefix }}packet_buf(void *vctx) | |
123 | { | |
124 | return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->buf; | |
125 | } | |
126 | ||
127 | uint32_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 | ||
134 | void {{ 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 | ||
142 | int {{ prefix }}packet_is_open(void *vctx) | |
143 | { | |
144 | return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->packet_is_open; | |
145 | } | |
146 | ||
147 | int {{ prefix }}is_in_tracing_section(void *vctx) | |
148 | { | |
149 | return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->in_tracing_section; | |
150 | } | |
151 | ||
152 | volatile 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 | ||
157 | int {{ prefix }}is_tracing_enabled(void *vctx) | |
158 | { | |
159 | return _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->is_tracing_enabled; | |
160 | } | |
161 | ||
162 | void {{ prefix }}enable_tracing(void *vctx, int enable) | |
163 | { | |
164 | _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->is_tracing_enabled = enable; | |
165 | } | |
166 | ||
167 | static | |
168 | void _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 | ||
176 | static | |
177 | int _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 | ||
226 | static | |
227 | void _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 | ||
407 | static 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 | ||
427 | static 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 | ||
443 | static 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 | ||
484 | static 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 %} |