|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
The fixed decode arena that lets a protobuf codec run with no heap. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_c6link.h"#include "ra8_c6link_internal.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_c6link_arena_t : uint32_t { k_ra8_c6link_arena_align = 8U , k_ra8_c6link_arena_mask = 7U } |
| Alignment the arena hands out blocks at. More... | |
Functions | |
| void * | priv_c6link_arena_alloc (void *ctx, size_t size) |
| Take a block from the link's decode arena. | |
| void | priv_c6link_arena_free (void *ctx, void *pointer) |
| Return a block to the link's decode arena. | |
| void | priv_c6link_arena_reset (ra8_c6link_t *link) |
| Empty the link's decode arena. | |
| void | priv_c6link_arena_bind (ProtobufCAllocator *out, ra8_c6link_t *link) |
| Bind an allocator descriptor to a link's arena. | |
The fixed decode arena that lets a protobuf codec run with no heap.
rpc__unpack() allocates: one block for the message, one per nested message, one per repeated field and one per binary field. This firmware has no heap – _sbrk is a strong symbol that reports a fatal error – so the codec is handed an allocator over a caller-supplied buffer instead.
A bump allocator is the right shape for it. Every allocation a decode makes is released by the matching rpc__free_unpacked(), and the RPC layer empties the arena immediately afterwards, so the peak requirement is one message rather than one run and no fragmentation can accumulate. That is what keeps the whole control plane inside NASA Power of 10 Rule 3: the only storage decision is the caller's single = {} array, made before the link opens.
The free row is not a no-op. protobuf-c unwinds its own partial work when a decode fails part-way, and those releases are strictly newest-first, so rolling the bump offset back when the freed block is the newest one reclaims exactly the space a failed decode would otherwise strand.
Definition in file ra8_c6link_arena.c.
| enum ra8_c6link_arena_t : uint32_t |
Alignment the arena hands out blocks at.
protobuf-c stores uint64_t fields (WifiInitConfig::feature_caps is one) inside blocks it gets from this allocator, so eight-byte alignment is a correctness requirement on the target and not a performance choice.
| Enumerator | |
|---|---|
| k_ra8_c6link_arena_align | Alignment, in bytes, of every block the arena hands out. |
| k_ra8_c6link_arena_mask | k_ra8_c6link_arena_align minus one, as a rounding mask. |
Definition at line 60 of file ra8_c6link_arena.c.
| void * priv_c6link_arena_alloc | ( | void * | ctx, |
| size_t | size ) |
Take a block from the link's decode arena.
The alloc row of the ::ProtobufCAllocator handed to the generated codec. Bumps a pointer through the caller-supplied arena, eight-byte aligned. There is no fallback to a heap: this firmware has none, and an over-request must fail the decode rather than fault.
| [in] | ctx | The ra8_c6link_t whose arena to draw from; must be non-null. |
| [in] | size | Bytes requested; zero yields a non-null zero-length block, which is what protobuf-c expects. |
| NULL | The arena is exhausted, or ctx was null. |
Definition at line 67 of file ra8_c6link_arena.c.
References ra8_c6link::arena, ra8_c6link::arena_bytes, ra8_c6link::arena_last, ra8_c6link::arena_used, k_ra8_c6link_arena_mask, and RA8_PRIV.
Referenced by priv_c6link_arena_bind().
| void priv_c6link_arena_bind | ( | ProtobufCAllocator * | out, |
| ra8_c6link_t * | link ) |
Bind an allocator descriptor to a link's arena.
Fills the ::ProtobufCAllocator the generated codec is handed. Passing null to the codec instead would select protobuf-c's default allocator, which calls malloc; in this firmware _sbrk is a strong symbol that reports a fatal error, so that path faults rather than failing.
| [out] | out | Descriptor to fill; must be non-null. |
| [in] | link | Link whose arena backs it; must be non-null. |
link is open. out outlives every decode it is passed to. out are set. Definition at line 116 of file ra8_c6link_arena.c.
References priv_c6link_arena_alloc(), priv_c6link_arena_free(), and RA8_PRIV.
Referenced by internal_mdl_take_accepted(), internal_mdl_take_cancelled(), internal_mdl_take_chunk(), and priv_c6link_rpc_consume().
| void priv_c6link_arena_free | ( | void * | ctx, |
| void * | pointer ) |
Return a block to the link's decode arena.
The free row of the allocator. A bump arena cannot free out of order, but it can free the newest block: when pointer is the most recent allocation the bump offset rolls back to it, which is what turns the codec's own unwind-on-error path into genuinely reclaimed space rather than waste. Any other pointer is retained until priv_c6link_arena_reset runs, which the RPC layer does after every decode.
| [in] | ctx | The ra8_c6link_t whose arena owns the block; null is ignored. |
| [in] | pointer | Block to release; null is ignored. |
pointer came from priv_c6link_arena_alloc on the same link. pointer. Definition at line 94 of file ra8_c6link_arena.c.
References ra8_c6link::arena, ra8_c6link::arena_last, ra8_c6link::arena_used, and RA8_PRIV.
Referenced by priv_c6link_arena_bind().
| void priv_c6link_arena_reset | ( | ra8_c6link_t * | link | ) |
Empty the link's decode arena.
Called after every message is decoded and released, so each decode starts from a known offset and no leak can accumulate across messages. That is what bounds the arena requirement to one message rather than to a run.
| [in,out] | link | Link whose arena to empty; null is ignored. |
Definition at line 107 of file ra8_c6link_arena.c.
References ra8_c6link::arena_last, ra8_c6link::arena_used, and RA8_PRIV.
Referenced by priv_c6link_rpc_consume().