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 %} | |
e18cf9d6 | 32 | {% set const_params = true %} |
1cf325c4 | 33 | {% include 'license-header.j2' %} |
e72875eb | 34 | |
d6483c83 PP |
35 | |
36 | #include <stdint.h> | |
37 | #include <string.h> | |
38 | #include <assert.h> | |
39 | ||
40 | #include "{{ header_file_name }}" | |
41 | #include "{{ bitfield_header_file_name }}" | |
42 | ||
629cfd44 PP |
43 | #define _ALIGN(_at_var, _align) \ |
44 | do { \ | |
45 | (_at_var) = ((_at_var) + ((_align) - 1)) & -(_align); \ | |
d6483c83 PP |
46 | } while (0) |
47 | ||
48 | #ifdef __cplusplus | |
49 | # define _TO_VOID_PTR(_value) static_cast<void *>(_value) | |
50 | # define _FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value) | |
51 | #else | |
52 | # define _TO_VOID_PTR(_value) ((void *) (_value)) | |
53 | # define _FROM_VOID_PTR(_type, _value) ((_type *) (_value)) | |
54 | #endif | |
55 | ||
56 | #define _BITS_TO_BYTES(_x) ((_x) >> 3) | |
57 | #define _BYTES_TO_BITS(_x) ((_x) << 3) | |
58 | ||
59 | union _f2u { | |
60 | float f; | |
61 | uint32_t u; | |
62 | }; | |
63 | ||
64 | union _d2u { | |
65 | double f; | |
66 | uint64_t u; | |
67 | }; | |
68 | ||
e18cf9d6 | 69 | uint32_t {{ prefix }}packet_size(const void * const ctx) |
d6483c83 | 70 | { |
e18cf9d6 | 71 | return _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, ctx)->packet_size; |
d6483c83 PP |
72 | } |
73 | ||
e18cf9d6 | 74 | int {{ prefix }}packet_is_full(const void * const vctx) |
d6483c83 | 75 | { |
e18cf9d6 | 76 | const struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
77 | |
78 | return ctx->at == ctx->packet_size; | |
79 | } | |
80 | ||
e18cf9d6 | 81 | int {{ prefix }}packet_is_empty(const void * const vctx) |
d6483c83 | 82 | { |
e18cf9d6 | 83 | const struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
84 | |
85 | return ctx->at <= ctx->off_content; | |
86 | } | |
87 | ||
e18cf9d6 | 88 | uint32_t {{ prefix }}packet_events_discarded(const void * const vctx) |
d6483c83 | 89 | { |
e18cf9d6 | 90 | return _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx)->events_discarded; |
d6483c83 PP |
91 | } |
92 | ||
e18cf9d6 | 93 | uint8_t *{{ prefix }}packet_buf(const void * const vctx) |
d6483c83 | 94 | { |
e18cf9d6 | 95 | return _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx)->buf; |
d6483c83 PP |
96 | } |
97 | ||
e18cf9d6 | 98 | uint32_t {{ prefix }}packet_buf_size(const void * const vctx) |
d6483c83 | 99 | { |
e18cf9d6 | 100 | const struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
101 | |
102 | return _BITS_TO_BYTES(ctx->packet_size); | |
103 | } | |
104 | ||
e18cf9d6 PP |
105 | void {{ prefix }}packet_set_buf(void * const vctx, uint8_t * const buf, |
106 | const uint32_t buf_size) | |
d6483c83 | 107 | { |
e18cf9d6 | 108 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
109 | |
110 | ctx->buf = buf; | |
111 | ctx->packet_size = _BYTES_TO_BITS(buf_size); | |
112 | } | |
113 | ||
e18cf9d6 | 114 | int {{ prefix }}packet_is_open(const void * const vctx) |
d6483c83 | 115 | { |
e18cf9d6 | 116 | return _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx)->packet_is_open; |
d6483c83 PP |
117 | } |
118 | ||
e18cf9d6 | 119 | int {{ prefix }}is_in_tracing_section(const void * const vctx) |
d6483c83 | 120 | { |
e18cf9d6 | 121 | return _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx)->in_tracing_section; |
d6483c83 PP |
122 | } |
123 | ||
e18cf9d6 | 124 | volatile const int *{{ prefix }}is_in_tracing_section_ptr(const void * const vctx) |
d6483c83 | 125 | { |
e18cf9d6 | 126 | return &_FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx)->in_tracing_section; |
d6483c83 PP |
127 | } |
128 | ||
e18cf9d6 | 129 | int {{ prefix }}is_tracing_enabled(const void * const vctx) |
d6483c83 | 130 | { |
e18cf9d6 | 131 | return _FROM_VOID_PTR(const struct {{ ctx_struct_name }}, vctx)->is_tracing_enabled; |
d6483c83 PP |
132 | } |
133 | ||
e18cf9d6 | 134 | void {{ prefix }}enable_tracing(void * const vctx, const int enable) |
d6483c83 PP |
135 | { |
136 | _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx)->is_tracing_enabled = enable; | |
137 | } | |
138 | ||
139 | static | |
e18cf9d6 | 140 | void _write_c_str(struct {{ ctx_struct_name }} * const ctx, const char * const src) |
d6483c83 | 141 | { |
e18cf9d6 | 142 | const uint32_t sz = strlen(src) + 1; |
d6483c83 PP |
143 | |
144 | memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz); | |
145 | ctx->at += _BYTES_TO_BITS(sz); | |
146 | } | |
147 | ||
148 | static | |
e18cf9d6 | 149 | int _reserve_ev_space(void * const vctx, const uint32_t ev_size) |
d6483c83 | 150 | { |
d02c7d33 | 151 | int ret; |
e18cf9d6 | 152 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 | 153 | |
9318c705 | 154 | /* Event _cannot_ fit? */ |
d6483c83 | 155 | if (ev_size > (ctx->packet_size - ctx->off_content)) { |
d02c7d33 | 156 | goto no_space; |
d6483c83 PP |
157 | } |
158 | ||
9318c705 | 159 | /* Packet is full? */ |
d6483c83 | 160 | if ({{ prefix }}packet_is_full(ctx)) { |
9318c705 | 161 | /* Yes: is the back-end full? */ |
d6483c83 | 162 | if (ctx->cbs.is_backend_full(ctx->data)) { |
9318c705 | 163 | /* Yes: discard event */ |
d02c7d33 | 164 | goto no_space; |
d6483c83 PP |
165 | } |
166 | ||
9318c705 | 167 | /* Back-end is _not_ full: open new packet */ |
d6483c83 PP |
168 | ctx->use_cur_last_event_ts = 1; |
169 | ctx->cbs.open_packet(ctx->data); | |
170 | ctx->use_cur_last_event_ts = 0; | |
171 | } | |
172 | ||
9318c705 | 173 | /* Event fits the current packet? */ |
d6483c83 | 174 | if (ev_size > (ctx->packet_size - ctx->at)) { |
9318c705 | 175 | /* No: close packet now */ |
d6483c83 PP |
176 | ctx->use_cur_last_event_ts = 1; |
177 | ctx->cbs.close_packet(ctx->data); | |
178 | ctx->use_cur_last_event_ts = 0; | |
179 | ||
9318c705 | 180 | /* Is the back-end full? */ |
d6483c83 | 181 | if (ctx->cbs.is_backend_full(ctx->data)) { |
9318c705 | 182 | /* Yes: discard event */ |
d02c7d33 | 183 | goto no_space; |
d6483c83 PP |
184 | } |
185 | ||
9318c705 | 186 | /* Back-end is _not_ full: open new packet */ |
d6483c83 PP |
187 | ctx->use_cur_last_event_ts = 1; |
188 | ctx->cbs.open_packet(ctx->data); | |
189 | ctx->use_cur_last_event_ts = 0; | |
190 | assert(ev_size <= (ctx->packet_size - ctx->at)); | |
191 | } | |
192 | ||
d02c7d33 PP |
193 | ret = 1; |
194 | goto end; | |
195 | ||
196 | no_space: | |
197 | ctx->events_discarded++; | |
198 | ret = 0; | |
199 | ||
200 | end: | |
201 | return ret; | |
d6483c83 PP |
202 | } |
203 | ||
204 | static | |
e18cf9d6 | 205 | void _commit_ev(void * const vctx) |
d6483c83 | 206 | { |
e18cf9d6 | 207 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 | 208 | |
9318c705 | 209 | /* Is the packet full? */ |
d6483c83 | 210 | if ({{ prefix }}packet_is_full(ctx)) { |
9318c705 | 211 | /* Yes: close it now */ |
d6483c83 PP |
212 | ctx->cbs.close_packet(ctx->data); |
213 | } | |
214 | } | |
215 | ||
216 | {% include 'c/ctx-init-func-proto.j2' %} | |
217 | ||
218 | { | |
e18cf9d6 | 219 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
220 | ctx->cbs = cbs; |
221 | ctx->data = data; | |
222 | ctx->buf = buf; | |
223 | ctx->packet_size = _BYTES_TO_BITS(buf_size); | |
224 | ctx->at = 0; | |
225 | ctx->events_discarded = 0; | |
226 | ctx->packet_is_open = 0; | |
227 | ctx->in_tracing_section = 0; | |
228 | ctx->is_tracing_enabled = 1; | |
229 | ctx->use_cur_last_event_ts = 0; | |
230 | } | |
231 | ||
232 | {% for stream_type in cfg.trace.type.stream_types | sort %} | |
233 | {% set def_clk_type = stream_type.default_clock_type %} | |
234 | {% set sctx_name %}{{ prefix }}{{ stream_type.name }}{% endset %} | |
235 | {% set this_stream_ops = stream_ops[stream_type] %} | |
236 | {% include 'c/open-func-proto.j2' %} | |
237 | ||
238 | { | |
239 | {{ macros.open_close_func_preamble(stream_type) | indent_tab }} | |
240 | ||
241 | /* | |
242 | * This function is either called by a tracing function, or | |
243 | * directly by the platform. | |
244 | * | |
245 | * If it's called by a tracing function, then | |
246 | * `ctx->in_tracing_section` is 1, so it's safe to open | |
247 | * the packet here (alter the packet), even if tracing was | |
248 | * disabled in the meantime because we're already in a tracing | |
249 | * section (which finishes at the end of the tracing function | |
250 | * call). | |
251 | * | |
252 | * If it's called directly by the platform, then if tracing is | |
253 | * disabled, we don't want to alter the packet, and return | |
254 | * immediately. | |
255 | */ | |
256 | if (!ctx->is_tracing_enabled && !saved_in_tracing_section) { | |
257 | ctx->in_tracing_section = 0; | |
d02c7d33 | 258 | goto end; |
d6483c83 PP |
259 | } |
260 | ||
9318c705 | 261 | /* We can alter the packet */ |
d6483c83 PP |
262 | ctx->in_tracing_section = 1; |
263 | ||
9318c705 | 264 | /* Do not open a packet that is already open */ |
d6483c83 PP |
265 | if (ctx->packet_is_open) { |
266 | ctx->in_tracing_section = saved_in_tracing_section; | |
d02c7d33 | 267 | goto end; |
d6483c83 PP |
268 | } |
269 | ||
270 | ctx->at = 0; | |
271 | {% set pkt_header_ops = this_stream_ops.pkt_header_ops %} | |
272 | {% if pkt_header_ops %} | |
273 | ||
9318c705 | 274 | /* Serialize packet header */ |
d6483c83 PP |
275 | { |
276 | {% for op in pkt_header_ops %} | |
277 | {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }} | |
278 | ||
279 | {% endfor %} | |
280 | } | |
281 | {% endif %} | |
282 | ||
9318c705 | 283 | /* Serialize packet context */ |
d6483c83 PP |
284 | { |
285 | {% for op in this_stream_ops.pkt_ctx_ops %} | |
286 | {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }} | |
287 | ||
288 | {% endfor %} | |
289 | } | |
290 | ||
9318c705 | 291 | /* Save content beginning's offset */ |
d6483c83 PP |
292 | ctx->off_content = ctx->at; |
293 | ||
9318c705 | 294 | /* Mark current packet as open */ |
d6483c83 PP |
295 | ctx->packet_is_open = 1; |
296 | ||
9318c705 | 297 | /* Not tracing anymore */ |
d6483c83 | 298 | ctx->in_tracing_section = saved_in_tracing_section; |
d02c7d33 PP |
299 | |
300 | end: | |
301 | return; | |
d6483c83 PP |
302 | } |
303 | ||
304 | {% include 'c/close-func-proto.j2' %} | |
305 | ||
306 | { | |
307 | {{ macros.open_close_func_preamble(stream_type) | indent_tab }} | |
308 | ||
309 | /* | |
310 | * This function is either called by a tracing function, or | |
311 | * directly by the platform. | |
312 | * | |
313 | * If it's called by a tracing function, then | |
314 | * `ctx->in_tracing_section` is 1, so it's safe to close | |
315 | * the packet here (alter the packet), even if tracing was | |
316 | * disabled in the meantime, because we're already in a tracing | |
317 | * section (which finishes at the end of the tracing function | |
318 | * call). | |
319 | * | |
320 | * If it's called directly by the platform, then if tracing is | |
321 | * disabled, we don't want to alter the packet, and return | |
322 | * immediately. | |
323 | */ | |
324 | if (!ctx->is_tracing_enabled && !saved_in_tracing_section) { | |
325 | ctx->in_tracing_section = 0; | |
d02c7d33 | 326 | goto end; |
d6483c83 PP |
327 | } |
328 | ||
9318c705 | 329 | /* We can alter the packet */ |
d6483c83 PP |
330 | ctx->in_tracing_section = 1; |
331 | ||
9318c705 | 332 | /* Do not close a packet that is not open */ |
d6483c83 PP |
333 | if (!ctx->packet_is_open) { |
334 | ctx->in_tracing_section = saved_in_tracing_section; | |
d02c7d33 | 335 | goto end; |
d6483c83 PP |
336 | } |
337 | ||
9318c705 | 338 | /* Save content size */ |
d6483c83 | 339 | ctx->content_size = ctx->at; |
03088329 PP |
340 | {% set name = 'timestamp_end' %} |
341 | {% if name in stream_type._pkt_ctx_ft.members %} | |
342 | {% set op = stream_op_pkt_ctx_op(stream_type, name) %} | |
d6483c83 | 343 | |
9318c705 | 344 | /* Go back to `timestamp_end` field offset */ |
d6483c83 PP |
345 | ctx->at = sctx->off_{{ c_common.op_src(op) }}; |
346 | ||
347 | {% set src = 'ts' %} | |
adb5316b | 348 | {% filter indent_tab(indent_first=true) %} |
d6483c83 PP |
349 | {% include 'c/serialize-write-saved-int-statements.j2' %} |
350 | ||
351 | {% endfilter %} | |
352 | {% endif %} | |
03088329 PP |
353 | {% set name = 'content_size' %} |
354 | {% if name in stream_type._pkt_ctx_ft.members %} | |
355 | {% set op = stream_op_pkt_ctx_op(stream_type, name) %} | |
d6483c83 | 356 | |
9318c705 | 357 | /* Go back to `content_size` field offset */ |
d6483c83 PP |
358 | ctx->at = sctx->off_{{ c_common.op_src(op) }}; |
359 | ||
03088329 | 360 | {% set src %}ctx->{{ name }}{% endset %} |
adb5316b | 361 | {% filter indent_tab(indent_first=true) %} |
d6483c83 PP |
362 | {% include 'c/serialize-write-saved-int-statements.j2' %} |
363 | ||
364 | {% endfilter %} | |
365 | {% endif %} | |
03088329 PP |
366 | {% set name = 'events_discarded' %} |
367 | {% if name in stream_type._pkt_ctx_ft.members %} | |
368 | {% set op = stream_op_pkt_ctx_op(stream_type, name) %} | |
d6483c83 | 369 | |
9318c705 | 370 | /* Go back to `events_discarded` field offset */ |
d6483c83 PP |
371 | ctx->at = sctx->off_{{ c_common.op_src(op) }}; |
372 | ||
03088329 | 373 | {% set src %}ctx->{{ name }}{% endset %} |
adb5316b | 374 | {% filter indent_tab(indent_first=true) %} |
d6483c83 PP |
375 | {% include 'c/serialize-write-saved-int-statements.j2' %} |
376 | ||
377 | {% endfilter %} | |
378 | {% endif %} | |
379 | ||
9318c705 | 380 | /* Go back to end of packet */ |
d6483c83 PP |
381 | ctx->at = ctx->packet_size; |
382 | ||
9318c705 | 383 | /* Mark packet as closed */ |
d6483c83 PP |
384 | ctx->packet_is_open = 0; |
385 | ||
9318c705 | 386 | /* Not tracing anymore */ |
d6483c83 | 387 | ctx->in_tracing_section = saved_in_tracing_section; |
d02c7d33 PP |
388 | |
389 | end: | |
390 | return; | |
d6483c83 PP |
391 | } |
392 | {% if stream_type._ev_header_ft %} | |
393 | ||
e18cf9d6 PP |
394 | static void _serialize_ev_header_{{ stream_type.name }}(void * const vctx, |
395 | const uint32_t ev_type_id) | |
d6483c83 | 396 | { |
e18cf9d6 | 397 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 | 398 | {% if def_clk_type %} |
e18cf9d6 | 399 | struct {{ sctx_name }}_ctx * const sctx = _FROM_VOID_PTR(struct {{ sctx_name }}_ctx, vctx); |
d6483c83 PP |
400 | const {{ cg_opts.clock_type_c_types[def_clk_type] }} ts = sctx->cur_last_event_ts; |
401 | {% endif %} | |
402 | ||
9318c705 | 403 | /* Serialize event header */ |
d6483c83 PP |
404 | { |
405 | {% for op in this_stream_ops.ev_header_ops %} | |
406 | {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }} | |
407 | ||
408 | {% endfor %} | |
409 | } | |
410 | } | |
411 | {% endif %} | |
412 | {% if stream_type.event_common_context_field_type %} | |
413 | ||
e18cf9d6 | 414 | static void _serialize_ev_common_ctx_{{ stream_type.name }}(void * const vctx{{ stream_type | serialize_ev_common_ctx_func_params_str(const_params) }}) |
d6483c83 | 415 | { |
e18cf9d6 | 416 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 | 417 | |
9318c705 | 418 | /* Serialize event common context */ |
d6483c83 PP |
419 | { |
420 | {% for op in this_stream_ops.ev_common_ctx_ops %} | |
421 | {{ op.serialize_str(stream_type=stream_type) | indent_tab(2) }} | |
422 | ||
423 | {% endfor %} | |
424 | } | |
425 | } | |
426 | {% endif %} | |
427 | {# internal serialization functions #} | |
428 | {% for ev_type in stream_type.event_types | sort %} | |
429 | ||
e18cf9d6 | 430 | static void _serialize_ev_{{ stream_type.name }}_{{ ev_type.name }}(void * const vctx{{ (stream_type, ev_type) | trace_func_params_str(const_params) }}) |
d6483c83 | 431 | { |
e18cf9d6 | 432 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
433 | {% if stream_type._ev_header_ft %} |
434 | ||
9318c705 | 435 | /* Serialize header */ |
d6483c83 PP |
436 | _serialize_ev_header_{{ stream_type.name }}(ctx, {{ ev_type.id }}); |
437 | {% endif %} | |
438 | {% if stream_type.event_common_context_field_type %} | |
439 | ||
9318c705 | 440 | /* Serialize common context */ |
1c650e47 | 441 | {% set params = macros.ft_call_params(root_ft_prefixes.ECC, stream_type.event_common_context_field_type) %} |
d6483c83 PP |
442 | _serialize_ev_common_ctx_{{ stream_type.name }}(ctx{{ params }}); |
443 | {% endif %} | |
444 | {% set this_ev_ops = this_stream_ops.ev_ops[ev_type] %} | |
445 | {% if this_ev_ops.spec_ctx_ops %} | |
446 | ||
9318c705 | 447 | /* Serialize specific context */ |
d6483c83 PP |
448 | { |
449 | {% for op in this_ev_ops.spec_ctx_ops %} | |
450 | {{ op.serialize_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }} | |
451 | ||
452 | {% endfor %} | |
453 | } | |
454 | {% endif %} | |
455 | {% if this_ev_ops.payload_ops %} | |
456 | ||
9318c705 | 457 | /* Serialize payload */ |
d6483c83 PP |
458 | { |
459 | {% for op in this_ev_ops.payload_ops %} | |
460 | {{ op.serialize_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }} | |
461 | ||
462 | {% endfor %} | |
463 | } | |
464 | {% endif %} | |
465 | } | |
466 | {% endfor %} | |
467 | {# internal size functions #} | |
468 | {% for ev_type in stream_type.event_types | sort %} | |
469 | {% set this_ev_ops = this_stream_ops.ev_ops[ev_type] %} | |
470 | ||
b622b24f | 471 | static uint32_t _ev_size_{{ stream_type.name }}_{{ ev_type.name }}(void * const vctx{{ (stream_type, ev_type) | trace_func_params_str(const_params, only_dyn=true) }}) |
d6483c83 | 472 | { |
e18cf9d6 | 473 | struct {{ ctx_struct_name }} * const ctx = _FROM_VOID_PTR(struct {{ ctx_struct_name }}, vctx); |
d6483c83 PP |
474 | uint32_t at = ctx->at; |
475 | {% if this_stream_ops.ev_header_ops %} | |
476 | ||
9318c705 | 477 | /* Add header size */ |
d6483c83 PP |
478 | { |
479 | {% for op in this_stream_ops.ev_header_ops %} | |
480 | {{ op.size_str(stream_type=stream_type) | indent_tab(2) }} | |
481 | ||
482 | {% endfor %} | |
483 | } | |
484 | {% endif %} | |
485 | {% if this_stream_ops.ev_common_ctx_ops %} | |
486 | ||
9318c705 | 487 | /* Add common context size */ |
d6483c83 PP |
488 | { |
489 | {% for op in this_stream_ops.ev_common_ctx_ops %} | |
490 | {{ op.size_str(stream_type=stream_type) | indent_tab(2) }} | |
491 | ||
492 | {% endfor %} | |
493 | } | |
494 | {% endif %} | |
495 | {% if this_ev_ops.spec_ctx_ops %} | |
496 | ||
9318c705 | 497 | /* Add specific context size */ |
d6483c83 PP |
498 | { |
499 | {% for op in this_ev_ops.spec_ctx_ops %} | |
500 | {{ op.size_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }} | |
501 | ||
502 | {% endfor %} | |
503 | } | |
504 | {% endif %} | |
505 | {% if this_ev_ops.payload_ops %} | |
506 | ||
9318c705 | 507 | /* Add payload size */ |
d6483c83 PP |
508 | { |
509 | {% for op in this_ev_ops.payload_ops %} | |
510 | {{ op.size_str(stream_type=stream_type, ev_type=ev_type) | indent_tab(2) }} | |
511 | ||
512 | {% endfor %} | |
513 | } | |
514 | {% endif %} | |
515 | ||
516 | return at - ctx->at; | |
517 | } | |
518 | {% endfor %} | |
519 | {# public tracing functions #} | |
520 | {% for ev_type in stream_type.event_types | sort %} | |
521 | ||
522 | {% include 'c/trace-func-proto.j2' %} | |
523 | ||
524 | { | |
e18cf9d6 | 525 | struct {{ ctx_struct_name }} * const ctx = &sctx->parent; |
d6483c83 PP |
526 | uint32_t ev_size; |
527 | ||
528 | {% if def_clk_type %} | |
9318c705 | 529 | /* Save time */ |
d6483c83 PP |
530 | sctx->cur_last_event_ts = ctx->cbs.{{ def_clk_type.name }}_clock_get_value(ctx->data); |
531 | ||
532 | {% endif %} | |
d6483c83 | 533 | if (!ctx->is_tracing_enabled) { |
d02c7d33 | 534 | goto end; |
d6483c83 PP |
535 | } |
536 | ||
9318c705 | 537 | /* We can alter the packet */ |
d6483c83 PP |
538 | ctx->in_tracing_section = 1; |
539 | ||
9318c705 | 540 | /* Compute event size */ |
b622b24f PP |
541 | {% set ev_common_ctx_params = macros.ft_call_params(root_ft_prefixes.ECC, stream_type.event_common_context_field_type, true) %} |
542 | {% set spec_ctx_params = macros.ft_call_params(root_ft_prefixes.SC, ev_type.specific_context_field_type, true) %} | |
543 | {% set payload_params = macros.ft_call_params(root_ft_prefixes.P, ev_type.payload_field_type, true) %} | |
d6483c83 PP |
544 | {% set params %}{{ ev_common_ctx_params }}{{ spec_ctx_params }}{{ payload_params }}{% endset %} |
545 | ev_size = _ev_size_{{ stream_type.name }}_{{ ev_type.name }}(_TO_VOID_PTR(ctx){{ params }}); | |
546 | ||
9318c705 | 547 | /* Is there enough space to serialize? */ |
d6483c83 PP |
548 | if (!_reserve_ev_space(_TO_VOID_PTR(ctx), ev_size)) { |
549 | /* no: forget this */ | |
550 | ctx->in_tracing_section = 0; | |
d02c7d33 | 551 | goto end; |
d6483c83 PP |
552 | } |
553 | ||
9318c705 | 554 | /* Serialize event */ |
b622b24f PP |
555 | {% set ev_common_ctx_params = macros.ft_call_params(root_ft_prefixes.ECC, stream_type.event_common_context_field_type) %} |
556 | {% set spec_ctx_params = macros.ft_call_params(root_ft_prefixes.SC, ev_type.specific_context_field_type) %} | |
557 | {% set payload_params = macros.ft_call_params(root_ft_prefixes.P, ev_type.payload_field_type) %} | |
558 | {% set params %}{{ ev_common_ctx_params }}{{ spec_ctx_params }}{{ payload_params }}{% endset %} | |
d6483c83 PP |
559 | _serialize_ev_{{ stream_type.name }}_{{ ev_type.name }}(_TO_VOID_PTR(ctx){{ params }}); |
560 | ||
9318c705 | 561 | /* Commit event */ |
d6483c83 PP |
562 | _commit_ev(_TO_VOID_PTR(ctx)); |
563 | ||
9318c705 | 564 | /* Not tracing anymore */ |
d6483c83 | 565 | ctx->in_tracing_section = 0; |
d02c7d33 PP |
566 | |
567 | end: | |
568 | return; | |
d6483c83 PP |
569 | } |
570 | {% endfor %} | |
571 | {% endfor %} |