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;
104 ABlk *b = (ABlk *)((uint8_t *)p - AHDR);
118 while (off < a->persist_end)
120 ABlk *cur = (ABlk *)(a->
base + off);
121 size_t next_off = off + AHDR + cur->size;
122 if (!cur->used && next_off < a->persist_end)
124 ABlk *nxt = (ABlk *)(a->
base + next_off);
127 cur->size += AHDR + nxt->size;
137 while (off < a->persist_end)
140 ABlk *cur = (ABlk *)(a->
base + off);
141 off += AHDR + cur->size;
165 return mid > AHDR ? mid - AHDR : 0;
200 for (
size_t i = 0; i < s->
count; i++)
217 uint8_t *b = (uint8_t *)p;
218 for (
size_t i = 0; i < s->
count; i++)
221 if (b >= r->
base && b < r->base + r->
size)
231 for (
size_t i = 0; i < s->
count; i++)
251 for (
size_t i = 0; i < s->
count; i++)
261 for (
size_t i = 0; i < n; i++)
269 for (
size_t i = 0; i < s->
count; i++)
278 for (
size_t i = 0; i < s->
count; i++)
288 for (
size_t i = 0; i < s->
count; i++)
298 for (
size_t i = 0; i < s->
count; i++)
size_t pc_arena_set_scratch_used(const pc_arena_set *s)
Scratch bytes allocated, summed over all regions.
void * pc_arena_set_scratch_alloc_aligned(pc_arena_set *s, size_t n, size_t align)
Aligned scratch alloc from the first region that fits (see pc_arena_scratch_alloc_aligned()).
bool pc_arena_set_add(pc_arena_set *s, void *base, size_t size)
Add a region [base, base+size); regions are searched in the order added.
void * pc_arena_scratch_alloc(pc_arena *a, size_t n)
Bump-allocate n transient bytes at the baseline alignment (PC_ARENA_ALIGN).
void * pc_arena_set_scratch_alloc(pc_arena_set *s, size_t n)
Scratch alloc from the first region that fits (see pc_arena_scratch_alloc()).
size_t pc_arena_set_persist_used(const pc_arena_set *s)
Persistent payload bytes allocated, summed over all regions.
void pc_arena_set_scratch_reset(pc_arena_set *s)
Reset scratch in every region.
void pc_arena_set_persist_free(pc_arena_set *s, void *p)
Free a persistent pointer, routed to its owning region by address.
void pc_arena_set_scratch_release(pc_arena_set *s, const pc_arena_mark *m)
Restore every region's scratch position to m (frees scratch made since).
pc_arena_mark pc_arena_set_scratch_mark(const pc_arena_set *s)
Capture the scratch position of every region.
void pc_arena_persist_free(pc_arena *a, void *p)
Free a pointer previously returned by pc_arena_persist_alloc().
size_t pc_arena_free_bytes(const pc_arena *a)
Free bytes in the middle (max a single new allocation could take, minus a header).
void * pc_arena_set_persist_alloc(pc_arena_set *s, size_t n)
Persistent alloc from the first region that fits (see pc_arena_persist_alloc()).
void pc_arena_set_init(pc_arena_set *s)
Initialize an empty set (no regions yet).
size_t pc_arena_persist_used(const pc_arena *a)
Persistent payload bytes currently allocated.
void * pc_arena_persist_alloc(pc_arena *a, size_t n)
Allocate n zero-initialized bytes of long-lived storage.
void pc_arena_init(pc_arena *a, void *base, size_t size)
Initialize a over the region [base, base+size).
size_t pc_arena_set_free_bytes(const pc_arena_set *s)
Total free middle bytes summed over all regions.
Unified double-ended server arena (Phase 1: core allocator, one region).
void pc_arena_scratch_reset(pc_arena *a)
Free ALL scratch allocations in O(1).
#define PC_ARENA_MAX_ALIGN
Strongest alignment a scratch borrow may request; the region base is aligned to it.
#define PC_ARENA_ALIGN
Baseline alignment (bytes) applied to every allocation and to headers.
#define PC_ARENA_MAX_REGIONS
Max regions in a pc_arena_set (DRAM base + PSRAM extension).
void pc_arena_scratch_release(pc_arena *a, size_t mark)
Free every scratch allocation made since mark (a value from pc_arena_scratch_mark()).
void * pc_arena_scratch_alloc_aligned(pc_arena *a, size_t n, size_t align)
Bump-allocate n bytes of transient storage, aligned to align.
size_t pc_arena_scratch_used(const pc_arena *a)
Scratch bytes currently allocated.
A scratch savepoint across every region of a pc_arena_set.
size_t top[PC_ARENA_MAX_REGIONS]
A set of pc_arena regions searched in insertion (preference) order.
pc_arena region[PC_ARENA_MAX_REGIONS]
size_t count
Regions in use.
Double-ended arena over one region [base, base+size).
size_t persist_used
Bytes currently handed out by the persistent pool (payload).
size_t scratch_top
Scratch occupies [scratch_top, size).
uint8_t * base
Region start.
size_t scratch_hw
High-water of scratch use (size - min scratch_top).
size_t persist_hw
High-water of persist_end (for sizing).
size_t size
Region length in bytes.
size_t persist_end
Persistent pool occupies [0, persist_end).