Module alloc::allocator
allocation traits shared by every allocator.
std/alloc has four allocators over a buffer of their own (or one you hand them); each suits a different allocation pattern:
BumpAllocator (bump.h) arena: O(1) alloc, frees everything at once
with reset(); dealloc of one block is a no-op.
PoolAllocator (pool.h) variable sizes, first fit, coalescing frees.
SlabAllocator (slab.h) one fixed object size, O(1) alloc and free.
TlsfAllocator (tlsf.h) variable sizes, O(1) alloc and free with
bounded fragmentation (real-time use).
The interface is split into one trait per capability, composed into the two roles generic code asks for, and the typed helpers are written once against the smallest trait they need:
Allocate alloc(size, align)
Deallocate dealloc(ptr)
Resettable reset(): frees every block at once
Allocator Allocate + Deallocate: BumpAllocator (no-op dealloc),
PoolAllocator, SlabAllocator, TlsfAllocator,
SecureAllocator (crypto/secure_alloc.h),
CountingAllocator<A> (below)
ArenaAllocator Allocate + Resettable: allocate freely, then reset() —
BumpAllocator, PoolAllocator, SlabAllocator,
TlsfAllocator
Traits are structural: a type conforms by having the methods, so your own allocator works with alloc_t / alloc_array_t / dealloc_t (and with any generic<A: Allocator> code) as soon as it defines alloc and dealloc with these signatures. Each call is resolved at compile time (no dispatch at run time).
struct BumpAllocator arena = BumpAllocator::new(4096UL);
?&heap Packet p = alloc_t(&arena); // T = Packet, from the target
?&heap float xs = alloc_array_t(&arena, 64UL); // 64 floats
...
arena.destroy();
Alignment each allocator honours ('align' must be a power of two; 0 is taken as 1; anything else gives null):
bump any power of two (measured on the address, padding the arena).
pool up to 8; null beyond.
slab up to the largest power of two dividing its object size, at most
8; null beyond, and null when size > its object size.
tlsf up to 8; null beyond.
The bounds for pool, slab and tlsf assume an 8-aligned backing buffer: always true for X::new; for X::over it's the buffer you pass.
Structs
| CountingAllocator | Forwards every call to the allocator it borrows and counts them: blocks handed out and given back, failed requests, bytes requested. It is an Allocator itself, so it slots in wherever the allocator it wraps would (leak checks in tests, sizing an arena or pool from a real workload). |
Traits
| Allocate | |
| Deallocate | |
| Allocator | |
| ArenaAllocator |
Functions
| alloc_t | One T / n Ts, aligned for T; null when the allocator can't. The memory is uninitialised. T is inferred from the target ('?&heap Packet p = alloc_t(&pool);'). alloc_array_t aborts with a diagnostic if n * sizeof(T) overflows (checked_mul_size). |
| alloc_array_t | |
| dealloc_t | Gives back a block from alloc_t / alloc_array_t on the same allocator. |