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