ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_img_arena.h File Reference

Heap-free scratch allocator hooks for the stb_image single-TU build. More...

#include <stddef.h>
#include "reflow_image.h"
Include dependency graph for ra8_img_arena.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void ra8_img_arena_bind (ra8_img_arena_t *arena)
 Bind arena as the active scratch for subsequent decode allocations.
void ra8_img_arena_unbind (void)
 Unbind the active arena; subsequent allocation hooks fail with nullptr.
void * ra8_img_arena_malloc (size_t n)
 stb_image STBI_MALLOC hook: bump n bytes from the bound arena.
void ra8_img_arena_free (void *p)
 stb_image STBI_FREE hook: release a block; auto-reset when none live.
void * ra8_img_arena_realloc_sized (void *p, size_t oldsz, size_t newsz)
 stb_image STBI_REALLOC_SIZED hook: fresh-allocate, copy, free old.

Detailed Description

Heap-free scratch allocator hooks for the stb_image single-TU build.

stb_image decodes JPEG/PNG/GIF/BMP through STBI_MALLOC / STBI_FREE / STBI_REALLOC_SIZED. The firmware has no heap (_sbrk traps after init), so stb_image_impl.c redirects those macros to the functions below, which bump-allocate out of a caller-bound arena (ra8_img_arena_t). Unlike the stb_truetype arena (a fixed file-scope array), an image decode's scratch sizing spans three orders of magnitude – a few KiB for a thumbnail, a few MiB for a full-page cover – so the backing store is supplied per call by the consumer via ra8_img_arena_bind() rather than baked in here.

The allocator is a bump arena with reference-counted auto-reset: each ra8_img_arena_malloc() bumps offset and increments live; each ra8_img_arena_free() decrements live and, when it reaches zero, rewinds offset to the base. stb_image frees all of its scratch before returning, so the arena fully drains after each decode – no caller bookkeeping, robust to any free order, immune to fragmentation. On exhaustion the malloc hook returns nullptr; stb_image propagates that as a decode failure rather than corrupting memory.

NASA Power-of-10 Rule 3 (no dynamic allocation after init): the backing store is caller-owned static/SRAM/SDRAM storage, never malloc.

[Ring 4 / Reflow] {World: NS}

Since
0.1.0

Definition in file ra8_img_arena.h.

Function Documentation

◆ ra8_img_arena_bind()

void ra8_img_arena_bind ( ra8_img_arena_t * arena)

Bind arena as the active scratch for subsequent decode allocations.

Records arena in a file-static slot and resets it to empty (offset = 0, live = 0). Every ra8_img_arena_malloc() / _free() / _realloc until the next ra8_img_arena_bind() or ra8_img_arena_unbind() operates on it.

Parameters
[in,out]arenaArena to make active; reset to empty on entry. NULL unbinds (equivalent to ra8_img_arena_unbind()).
Returns
None.
Precondition
arena, if non-NULL, has base pointing at cap writable bytes.
Called single-threaded around one decode (decoding is not re-entrant).
Postcondition
The active arena is arena and, if non-NULL, it is empty.
A subsequent ra8_img_arena_malloc() draws from arena.
Note
Not thread-safe: image decoding is single-threaded.
Since
0.1.0

Definition at line 38 of file ra8_img_arena.c.

References ra8_img_arena_t::live, ra8_img_arena_t::offset, and s_arena.

Referenced by internal_decode_stb(), internal_probe_page(), internal_transcode_image(), and ra8_img_decode_blit().

◆ ra8_img_arena_free()

void ra8_img_arena_free ( void * p)

stb_image STBI_FREE hook: release a block; auto-reset when none live.

Decrements the bound arena's live-block count; the bump offset is not tracked per block. When the count reaches zero the arena has fully drained, so the offset rewinds to the base. A nullptr argument, or no bound arena, is ignored.

Parameters
[in]pPointer to release; nullptr is ignored.
Returns
None.
Precondition
p was returned by ra8_img_arena_malloc()/_realloc_sized(), or is nullptr.
Called single-threaded from the decoder.
Postcondition
The live-block count is decremented (never below zero).
When the live-block count reaches zero the arena offset rewinds to base.
Note
Not thread-safe: image decoding is single-threaded.
Since
0.1.0

Definition at line 73 of file ra8_img_arena.c.

References ra8_img_arena_t::live, ra8_img_arena_t::offset, and s_arena.

Referenced by ra8_img_arena_realloc_sized().

◆ ra8_img_arena_malloc()

void * ra8_img_arena_malloc ( size_t n)

stb_image STBI_MALLOC hook: bump n bytes from the bound arena.

Rounds n up to the 16-byte alignment, bumps the bound arena's offset, and increments its live-block count. Fails with nullptr when no arena is bound, when n exceeds the capacity, or when the request does not fit the remaining capacity.

Parameters
[in]nByte count requested by stb_image.
Returns
16-byte-aligned pointer into the bound arena, or nullptr.
Return values
nullptrNo arena bound, or the request does not fit.
Precondition
Either an arena is bound (then a decode is in progress) or the call fails.
Called single-threaded from the decoder.
Postcondition
On success the live-block count is incremented and the offset advances.
On failure the arena state is unchanged.
Note
Not thread-safe: image decoding is single-threaded.
Since
0.1.0

Definition at line 52 of file ra8_img_arena.c.

References ra8_img_arena_t::base, ra8_img_arena_t::cap, k_ra8_img_align_mask, ra8_img_arena_t::live, ra8_img_arena_t::offset, and s_arena.

Referenced by ra8_img_arena_realloc_sized().

◆ ra8_img_arena_realloc_sized()

void * ra8_img_arena_realloc_sized ( void * p,
size_t oldsz,
size_t newsz )

stb_image STBI_REALLOC_SIZED hook: fresh-allocate, copy, free old.

A bump arena cannot grow a block in place, so this allocates newsz fresh, copies min(oldsz, newsz) bytes from p, and releases p. The old block's space is not reclaimed until the arena next drains – which is why the caller sizes the arena for the decode's peak, not its net, footprint.

Parameters
[in]pExisting block (may be nullptr -> behaves as malloc).
[in]oldszCurrent size of p in bytes (0 if p is nullptr).
[in]newszRequested new size in bytes.
Returns
Pointer to newsz bytes with the old contents copied, or nullptr.
Return values
nullptrNo arena bound, or the new request does not fit.
Precondition
p was returned by a prior hook call, or is nullptr.
Called single-threaded from the decoder.
Postcondition
On success the first min(oldsz, newsz) bytes match p's old contents.
On failure p remains valid and the arena state is unchanged.
Note
Not thread-safe: image decoding is single-threaded.
Since
0.1.0

Definition at line 87 of file ra8_img_arena.c.

References memcpy(), ra8_img_arena_free(), and ra8_img_arena_malloc().

◆ ra8_img_arena_unbind()

void ra8_img_arena_unbind ( void )

Unbind the active arena; subsequent allocation hooks fail with nullptr.

Clears the file-static active-arena slot. Used to fence the stb hooks outside a decode so a stray allocation cannot scribble on a stale buffer.

Returns
None.
Precondition
None.
Called single-threaded around one decode.
Postcondition
The active-arena slot is NULL.
A subsequent ra8_img_arena_malloc() returns nullptr until the next bind.
Note
Not thread-safe: image decoding is single-threaded.
Since
0.1.0

Definition at line 47 of file ra8_img_arena.c.

References s_arena.

Referenced by internal_arena_release(), internal_decode_stb(), internal_encode_source(), internal_probe_page(), and internal_transcode_image().