23inline size_t align_up(
size_t n)
33 uintptr_t b = (uintptr_t)base;
35 size_t adj = (size_t)(ab - b);
36 a->
base = (uint8_t *)ab;
55 while (off < a->persist_end)
57 ABlk *b = (ABlk *)(a->
base + off);
58 if (!b->used && b->size >= n)
63 ABlk *nb = (ABlk *)(a->
base + off + AHDR + n);
64 nb->size = b->size - n - AHDR;
70 void *pl = a->
base + off + AHDR;
71 memset(pl, 0, b->size);
74 off += AHDR + b->size;
79 size_t need = AHDR + n;
100 ABlk *b = (ABlk *)((uint8_t *)p - AHDR);
110 while (off < a->persist_end)
112 ABlk *cur = (ABlk *)(a->
base + off);
113 size_t next_off = off + AHDR + cur->size;
114 if (!cur->used && next_off < a->persist_end)
116 ABlk *nxt = (ABlk *)(a->
base + next_off);
119 cur->size += AHDR + nxt->size;
129 while (off < a->persist_end)
132 ABlk *cur = (ABlk *)(a->
base + off);
133 off += AHDR + cur->size;
153 size_t nt = (a->
scratch_top - n) & ~(
size_t)(align - 1);
192 return mid > AHDR ? mid - AHDR : 0;
228 for (
size_t i = 0; i < s->
count; i++)
241 uint8_t *b = (uint8_t *)p;
242 for (
size_t i = 0; i < s->
count; i++)
245 if (b >= r->
base && b < r->base + r->
size)
255 for (
size_t i = 0; i < s->
count; i++)
273 for (
size_t i = 0; i < s->
count; i++)
281 for (
size_t i = 0; i < n; i++)
287 for (
size_t i = 0; i < s->
count; i++)
294 for (
size_t i = 0; i < s->
count; i++)
302 for (
size_t i = 0; i < s->
count; i++)
310 for (
size_t i = 0; i < s->
count; i++)
size_t det_arena_persist_used(const DetArena *a)
Persistent payload bytes currently allocated.
void det_arena_set_persist_free(DetArenaSet *s, void *p)
Free a persistent pointer, routed to its owning region by address.
void det_arena_persist_free(DetArena *a, void *p)
Free a pointer previously returned by det_arena_persist_alloc().
void det_arena_set_init(DetArenaSet *s)
Initialize an empty set (no regions yet).
void * det_arena_set_scratch_alloc(DetArenaSet *s, size_t n)
Scratch alloc from the first region that fits (see det_arena_scratch_alloc()).
size_t det_arena_set_scratch_used(const DetArenaSet *s)
Scratch bytes allocated, summed over all regions.
size_t det_arena_free_bytes(const DetArena *a)
Free bytes in the middle (max a single new allocation could take, minus a header).
void * det_arena_set_persist_alloc(DetArenaSet *s, size_t n)
Persistent alloc from the first region that fits (see det_arena_persist_alloc()).
void det_arena_set_scratch_release(DetArenaSet *s, const DetArenaMark *m)
Restore every region's scratch position to m (frees scratch made since).
void det_arena_set_scratch_reset(DetArenaSet *s)
Reset scratch in every region.
void * det_arena_persist_alloc(DetArena *a, size_t n)
Allocate n zero-initialized bytes of long-lived storage.
void * det_arena_set_scratch_alloc_aligned(DetArenaSet *s, size_t n, size_t align)
Aligned scratch alloc from the first region that fits (see det_arena_scratch_alloc_aligned()).
void det_arena_scratch_reset(DetArena *a)
Free ALL scratch allocations in O(1).
void det_arena_init(DetArena *a, void *base, size_t size)
Initialize a over the region [base, base+size).
size_t det_arena_scratch_used(const DetArena *a)
Scratch bytes currently allocated.
void det_arena_scratch_release(DetArena *a, size_t mark)
Free every scratch allocation made since mark (a value from det_arena_scratch_mark()).
DetArenaMark det_arena_set_scratch_mark(const DetArenaSet *s)
Capture the scratch position of every region.
void * det_arena_scratch_alloc(DetArena *a, size_t n)
Bump-allocate n transient bytes at the baseline alignment (DET_ARENA_ALIGN).
size_t det_arena_set_free_bytes(const DetArenaSet *s)
Total free middle bytes summed over all regions.
void * det_arena_scratch_alloc_aligned(DetArena *a, size_t n, size_t align)
Bump-allocate n bytes of transient storage, aligned to align.
size_t det_arena_scratch_mark(const DetArena *a)
Capture the current scratch position (a savepoint for det_arena_scratch_release()).
bool det_arena_set_add(DetArenaSet *s, void *base, size_t size)
Add a region [base, base+size); regions are searched in the order added.
size_t det_arena_set_persist_used(const DetArenaSet *s)
Persistent payload bytes allocated, summed over all regions.
Unified double-ended server arena (Phase 1: core allocator, one region).
#define DET_ARENA_ALIGN
Baseline alignment (bytes) applied to every allocation and to headers.
#define DET_ARENA_MAX_REGIONS
Max regions in a DetArenaSet (DRAM base + PSRAM extension).
#define DET_ARENA_MAX_ALIGN
Strongest alignment a scratch borrow may request; the region base is aligned to it.
A scratch savepoint across every region of a DetArenaSet.
size_t top[DET_ARENA_MAX_REGIONS]
A set of DetArena regions searched in insertion (preference) order.
size_t count
Regions in use.
DetArena region[DET_ARENA_MAX_REGIONS]
Double-ended arena over one region [base, base+size).
size_t size
Region length in bytes.
size_t scratch_hw
High-water of scratch use (size - min scratch_top).
size_t persist_used
Bytes currently handed out by the persistent pool (payload).
size_t scratch_top
Scratch occupies [scratch_top, size).
size_t persist_hw
High-water of persist_end (for sizing).
uint8_t * base
Region start.
size_t persist_end
Persistent pool occupies [0, persist_end).