|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
First-fit allocator over one caller-owned miniz workspace. More...
#include "epub_miniz_alloc.h"#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"Go to the source code of this file.
Data Structures | |
| struct | priv_blk_t |
| Header prefixing every arena block. More... | |
Enumerations | |
| enum | priv_alloc_const_t : size_t { k_priv_hdr_bytes , k_priv_align = alignof(max_align_t) , k_priv_walk_max , k_priv_blk_free = 1U , k_priv_blk_used = 0U } |
| Private allocator geometry and sentinel values. More... | |
Functions | |
| static uintptr_t | internal_pointer_address (const void *pointer) |
| Copy a pointer representation into an integer address. | |
| static bool | internal_ready (const epub_miniz_arena_t *arena) |
| Validate an arena descriptor before using caller-owned storage. | |
| static priv_blk_t * | internal_cell_at (const epub_miniz_arena_t *arena, size_t off) |
Cast byte offset off to an aligned block header. | |
| static uint8_t * | internal_end (const epub_miniz_arena_t *arena) |
| Return the arena's one-past byte sentinel. | |
| static uint8_t * | internal_payload (priv_blk_t *block) |
Return the payload immediately following block. | |
| static priv_blk_t * | internal_header (const epub_miniz_arena_t *arena, void *address) |
| Return the header for an allocation payload. | |
| static priv_blk_t * | internal_next (const epub_miniz_arena_t *arena, priv_blk_t *block) |
Return the block immediately following block. | |
| static bool | internal_in_pool (const epub_miniz_arena_t *arena, const void *address) |
| Test whether an address lies in the payload-bearing arena range. | |
| static size_t | internal_align_up (size_t bytes) |
| Align a pool-bounded request upward to a complete arena cell. | |
| static bool | internal_request_bytes (size_t items, size_t size, size_t *out_bytes) |
| Validate and multiply a miniz count/size request exactly once. | |
| static void | internal_split (const epub_miniz_arena_t *arena, priv_blk_t *block, size_t need) |
| Split a block if its remainder can hold another allocation. | |
| static void | internal_coalesce (const epub_miniz_arena_t *arena) |
| Merge all adjacent free blocks in an arena. | |
| ra8_err_t | epub_miniz_arena_init (epub_miniz_arena_t *arena, void *workspace, size_t workspace_bytes) |
| Initialise or reset a miniz arena over caller-owned storage. | |
| void | epub_miniz_arena_deinit (epub_miniz_arena_t *arena) |
| Invalidate an arena descriptor after miniz has released its blocks. | |
| void * | epub_miniz_alloc (void *opaque, size_t items, size_t size) |
| miniz-compatible allocator (mz_alloc_func). | |
| void | epub_miniz_free (void *opaque, void *address) |
| miniz-compatible free (mz_free_func). | |
| void * | epub_miniz_realloc (void *opaque, void *address, size_t items, size_t size) |
| miniz-compatible realloc (mz_realloc_func). | |
First-fit allocator over one caller-owned miniz workspace.
Each EPUB or CBZ object embeds its own aligned workspace and arena descriptor. Miniz receives that descriptor through m_pAlloc_opaque. Blocks form an implicit list with in-band headers; allocation is first-fit, free coalesces adjacent blocks, and realloc preserves the original block when a grow cannot be satisfied. No global arena and no host heap fallback exist.
Definition in file epub_miniz_alloc.c.
| enum priv_alloc_const_t : size_t |
Private allocator geometry and sentinel values.
Definition at line 30 of file epub_miniz_alloc.c.
| void * epub_miniz_alloc | ( | void * | opaque, |
| size_t | items, | ||
| size_t | size ) |
miniz-compatible allocator (mz_alloc_func).
Returns a block of at least items * size bytes from opaque's arena, aligned to max_align_t. First-fit over the free list; splits an oversized free block when the remainder can hold a header plus a minimum payload. Returns NULL on overflow of items * size or pool exhaustion.
| [in] | opaque | Pointer to an initialised epub_miniz_arena_t. |
| [in] | items | Element count. |
| [in] | size | Element size, bytes. |
opaque names a live arena (NULL is rejected). Definition at line 318 of file epub_miniz_alloc.c.
References internal_align_up(), internal_cell_at(), internal_end(), internal_next(), internal_payload(), internal_ready(), internal_request_bytes(), internal_split(), priv_blk_t::is_free, k_priv_align, k_priv_blk_free, k_priv_blk_used, k_priv_walk_max, and priv_blk_t::size.
Referenced by epub_miniz_realloc(), internal_set_alloc(), and priv_epub_set_miniz_alloc().
| void epub_miniz_arena_deinit | ( | epub_miniz_arena_t * | arena | ) |
Invalidate an arena descriptor after miniz has released its blocks.
Clears only the descriptor; caller-owned workspace bytes remain available for a later explicit reinitialization.
| [in,out] | arena | Arena to invalidate; NULL is accepted. |
arena have been released. arena as its allocation context. Definition at line 311 of file epub_miniz_alloc.c.
Referenced by epub_close(), epub_open(), epub_open_streamed(), priv_comic_cbz_close(), and priv_comic_cbz_open().
|
nodiscard |
Initialise or reset a miniz arena over caller-owned storage.
| [out] | arena | Descriptor to initialise. |
| [in,out] | workspace | Maximally-aligned backing storage. |
| [in] | workspace_bytes | Writable bytes at workspace. |
| k_ra8_ok | Workspace accepted and reset to one free block. |
| k_ra8_err_null_ptr | arena or workspace is NULL. |
| k_ra8_err_invalid_size | Fewer than k_epub_miniz_pool_bytes bytes were supplied. |
| k_ra8_err_invalid_arg | workspace is not aligned for max_align_t. |
arena is live when reinitialising it. arena and workspace are unchanged. Definition at line 288 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::capacity, internal_cell_at(), internal_pointer_address(), priv_blk_t::is_free, k_epub_miniz_pool_bytes, k_priv_blk_free, k_priv_hdr_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, and priv_blk_t::size.
Referenced by internal_set_alloc(), and priv_epub_set_miniz_alloc().
| void epub_miniz_free | ( | void * | opaque, |
| void * | address ) |
miniz-compatible free (mz_free_func).
Marks address's block free and coalesces it with adjacent free blocks. A NULL address, invalid arena, or pointer outside that arena is ignored.
| [in] | opaque | Pointer to the owning epub_miniz_arena_t. |
| [in] | address | Block previously returned by epub_miniz_alloc / epub_miniz_realloc, or NULL. |
address is NULL or a live block from this allocator. opaque is the same live arena that allocated address. address's block is free and merged with any free neighbours. address leaves the pool unchanged.Definition at line 347 of file epub_miniz_alloc.c.
References internal_coalesce(), internal_header(), internal_in_pool(), priv_blk_t::is_free, and k_priv_blk_free.
Referenced by epub_miniz_realloc(), internal_set_alloc(), and priv_epub_set_miniz_alloc().
| void * epub_miniz_realloc | ( | void * | opaque, |
| void * | address, | ||
| size_t | items, | ||
| size_t | size ) |
miniz-compatible realloc (mz_realloc_func).
Grows or shrinks address to at least items * size bytes. Keeps the block in place when it already fits; otherwise allocates a new block, copies the old payload, and frees the old block. realloc(NULL, n) allocates; realloc(p, 0) frees and returns NULL.
| [in] | opaque | Pointer to the owning epub_miniz_arena_t. |
| [in] | address | Existing block, or NULL. |
| [in] | items | New element count. |
| [in] | size | New element size, bytes. |
address remains valid).opaque names a live arena. address is NULL or a live block from that arena. address, that block is still valid.Definition at line 358 of file epub_miniz_alloc.c.
References epub_miniz_alloc(), epub_miniz_free(), internal_align_up(), internal_header(), internal_in_pool(), internal_request_bytes(), memcpy(), and priv_blk_t::size.
Referenced by internal_set_alloc(), and priv_epub_set_miniz_alloc().
|
static |
Align a pool-bounded request upward to a complete arena cell.
Applies the power-of-two maximum-alignment mask after request bounds have already excluded arithmetic overflow.
| [in] | bytes | Unaligned request no larger than the arena capacity. |
bytes. | 0 | Returned when bytes is zero. |
| aligned | A multiple of k_priv_align not smaller than bytes. |
bytes passed internal_request_bytes. Definition at line 190 of file epub_miniz_alloc.c.
References k_priv_align.
Referenced by epub_miniz_alloc(), and epub_miniz_realloc().
|
static |
Cast byte offset off to an aligned block header.
| [in] | arena | Live arena. |
| [in] | off | Aligned byte offset, at most the arena capacity. |
Definition at line 107 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base.
Referenced by epub_miniz_alloc(), epub_miniz_arena_init(), internal_coalesce(), internal_header(), internal_next(), and internal_split().
|
static |
Merge all adjacent free blocks in an arena.
Walks the implicit bounded block list and folds each contiguous free run into its first header without moving live payload bytes.
| [in,out] | arena | Live arena whose in-band headers may be updated. |
arena is ready and its block chain is geometrically valid. Definition at line 270 of file epub_miniz_alloc.c.
References internal_cell_at(), internal_end(), internal_next(), priv_blk_t::is_free, k_priv_blk_free, k_priv_hdr_bytes, k_priv_walk_max, and priv_blk_t::size.
Referenced by epub_miniz_free().
|
static |
Return the arena's one-past byte sentinel.
Definition at line 115 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base, and epub_miniz_arena_t::capacity.
Referenced by epub_miniz_alloc(), and internal_coalesce().
|
static |
Return the header for an allocation payload.
Definition at line 129 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base, internal_cell_at(), internal_pointer_address(), and k_priv_hdr_bytes.
Referenced by epub_miniz_free(), and epub_miniz_realloc().
|
static |
Test whether an address lies in the payload-bearing arena range.
Rejects inactive arenas and excludes the header-only prefix and one-past byte without dereferencing the candidate address.
| [in] | arena | Arena descriptor to validate and bound the comparison. |
| [in] | address | Candidate allocation payload address. |
| true | Address is at or after the first payload byte and before end. |
| false | Arena is invalid or address lies outside the numeric range. |
arena is null or points to a readable descriptor. address may be null or any non-dereferenced pointer value. Definition at line 162 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base, epub_miniz_arena_t::capacity, internal_pointer_address(), internal_ready(), and k_priv_hdr_bytes.
Referenced by epub_miniz_free(), and epub_miniz_realloc().
|
static |
Return the block immediately following block.
Definition at line 138 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base, internal_cell_at(), internal_payload(), internal_pointer_address(), and priv_blk_t::size.
Referenced by epub_miniz_alloc(), and internal_coalesce().
|
static |
Return the payload immediately following block.
Definition at line 122 of file epub_miniz_alloc.c.
References k_priv_hdr_bytes.
Referenced by epub_miniz_alloc(), internal_next(), and internal_split().
|
static |
Copy a pointer representation into an integer address.
Uses a bytewise copy so the conversion does not violate pointer aliasing rules checked by the static analyzer.
| [in] | pointer | Object pointer whose representation is copied. |
| 0 | The null pointer representation when it is all-zero on this target. |
pointer may carry any object-pointer representation. Definition at line 60 of file epub_miniz_alloc.c.
References memcpy().
Referenced by epub_miniz_arena_init(), internal_header(), internal_in_pool(), internal_next(), internal_ready(), and internal_split().
|
static |
Validate an arena descriptor before using caller-owned storage.
Checks lifecycle, exact capacity, backing pointer, and alignment.
| [in] | arena | Descriptor to inspect. |
| true | Arena is initialized with exact aligned backing storage. |
| false | Arena is null, inactive, malformed, or misaligned. |
arena is null or points to a readable descriptor. Definition at line 83 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base, epub_miniz_arena_t::capacity, epub_miniz_arena_t::initialized, internal_pointer_address(), and k_epub_miniz_pool_bytes.
Referenced by epub_miniz_alloc(), and internal_in_pool().
|
static |
Validate and multiply a miniz count/size request exactly once.
| [in] | items | Element count. |
| [in] | size | Element size. |
| [out] | out_bytes | Product on success; unchanged on failure. |
Performs multiplication only after its overflow guard and rejects requests larger than the complete caller-owned pool.
| true | Product is representable, bounded, and stored in out_bytes. |
| false | Multiplication overflows or the product exceeds pool capacity. |
out_bytes is non-null and writable. items and size may be any representable size_t values. out_bytes exactly once. out_bytes unchanged. Definition at line 214 of file epub_miniz_alloc.c.
References k_epub_miniz_pool_bytes.
Referenced by epub_miniz_alloc(), and epub_miniz_realloc().
|
static |
Split a block if its remainder can hold another allocation.
Leaves unusably small tails inside the live block; otherwise emits one aligned free block with its own in-band header.
| [in] | arena | Live arena owning block. |
| [in,out] | block | Free block selected for allocation. |
| [in] | need | Aligned payload bytes required by the allocation. |
arena is ready and block is a valid free arena block. need is aligned, non-zero, and no greater than block->size. need payload bytes. Definition at line 242 of file epub_miniz_alloc.c.
References epub_miniz_arena_t::base, internal_cell_at(), internal_payload(), internal_pointer_address(), priv_blk_t::is_free, k_priv_align, k_priv_blk_free, k_priv_hdr_bytes, and priv_blk_t::size.
Referenced by epub_miniz_alloc().