|
MULE 0.0.1
Multi-Use Library Essentials
|
The allocator interface, and an arena that frees everything at once.
An Allocator is one realloc-shaped function and a context pointer. Every module that allocates takes a const Allocator *, and null means the libc heap. A Str or an Arr keeps the pointer in its alloc field, so the caller picks where its bytes live once and the rest of the code does not care.
All allocation in the library goes through mem_realloc(). Only this module calls malloc, realloc and free.
An Arena hands out memory from large blocks and frees all of it in one call. Use one for data that lives and dies together, such as everything built while handling one request or parsing one file.
Data Structures | |
| struct | Allocator |
| Where a module gets its memory. More... | |
| struct | Arena |
| Bump allocator over a chain of blocks. More... | |
Allocators | |
The interface every allocating module takes. | |
| typedef void * | AllocatorFn(void *ctx, void *old, size_t old_size, size_t new_size) |
Allocate, resize or free, depending on old and new_size. | |
| void * | mem_realloc (const Allocator *a, void *old, size_t old_size, size_t new_size) |
Resize old from old_size to new_size bytes through a. | |
Arenas | |
Bump allocation from blocks that are freed together. | |
| void * | arena_alloc (Arena *a, size_t size, size_t align) |
Hand out size bytes from a. | |
| const Allocator * | arena_allocator (Arena *a) |
An Allocator that draws from a. | |
| void | arena_reset (Arena *a) |
| Forget every allocation and keep the newest block for reuse. | |
| void | arena_free (Arena *a) |
| Release every block. | |
| #define | MEM_ARENA_BLOCK ((size_t)64 * 1024) |
| Bytes in a regular arena block. | |
| struct Allocator |
| Data Fields | ||
|---|---|---|
| AllocatorFn * | fn | Called with ctx and the mem_realloc arguments. |
| void * | ctx | Passed to fn unchanged. |
| struct Arena |
Bump allocator over a chain of blocks.
Do not copy or move an Arena once arena_allocator() has been called on it.
| Data Fields | ||
|---|---|---|
| ArenaBlock * | head |
Newest block. Older blocks chain behind it. |
| void * | last | Most recent allocation, for in-place growth. |
| Allocator | allocator | Filled by arena_allocator(). |
| #define MEM_ARENA_BLOCK ((size_t)64 * 1024) |
| typedef void * AllocatorFn(void *ctx, void *old, size_t old_size, size_t new_size) |
Allocate, resize or free, depending on old and new_size.
It has the same contract as mem_realloc(), with ctx from the Allocator.
| void * mem_realloc | ( | const Allocator * | a, |
| void * | old, | ||
| size_t | old_size, | ||
| size_t | new_size ) |
Resize old from old_size to new_size bytes through a.
| a | The allocator, or null for the libc heap. |
| old | The block to resize, or null to allocate a new one. |
| old_size | The size old was allocated with. Ignored when old is null. |
| new_size | The size wanted. Zero frees old. |
old untouched. A free returns null too, so p = mem_realloc(a, p, n, 0); frees and clears. | void * arena_alloc | ( | Arena * | a, |
| size_t | size, | ||
| size_t | align ) |
An Allocator that draws from a.
It lives as long as a.
a must not move after this call. | void arena_reset | ( | Arena * | a | ) |