BudgetAllocator
Description
Caller-buffer fixed-budget allocator. Carries Allocator base at offset 0 so (Allocator *)&bp is well-defined.
Fields
| Name | Description |
|---|---|
base |
Generic allocator base (function pointers, alignment, …). |
buf |
Pointer to the caller-owned memory region. |
buf_bytes |
Size of buf in bytes. |
slot_size |
Slot size in bytes (rounded up to base.alignment). |
slot_count |
Number of slots carved out of buf. |
free_head |
Head of the intrusive free list. |
Usage example (Cross-references)
Usage examples (Cross-references)
static bool test_basic_alloc_and_free(void) {
u8 buf[1024] = {0};
BudgetAllocator bp = BudgetAllocatorInit(buf, sizeof(buf), sizeof(Node));
Allocator *alloc = ALLOCATOR_OF(&bp);
Node *a = (Node *)AllocatorAlloc(alloc, sizeof(Node), true); // 256 bytes / padded(sizeof(Node)) = a few slots, exhaust them.
u8 buf[256] = {0};
BudgetAllocator bp = BudgetAllocatorInit(buf, sizeof(buf), sizeof(Node));
Allocator *alloc = ALLOCATOR_OF(&bp); static bool test_free_then_alloc_recycles(void) {
u8 buf[1024] = {0};
BudgetAllocator bp = BudgetAllocatorInit(buf, sizeof(buf), sizeof(Node));
Allocator *alloc = ALLOCATOR_OF(&bp); static bool test_oversized_request_fails(void) {
u8 buf[256] = {0};
BudgetAllocator bp = BudgetAllocatorInit(buf, sizeof(buf), sizeof(int));
Allocator *alloc = ALLOCATOR_OF(&bp);
void *big = AllocatorAlloc(alloc, 4096, true); static u8 buf[1024];
MemSet(buf, 0, sizeof(buf));
BudgetAllocator bp = BudgetAllocatorInitAligned(buf, sizeof(buf), sizeof(int), 64);
Allocator *alloc = ALLOCATOR_OF(&bp);
int *p1 = (int *)AllocatorAlloc(alloc, sizeof(int), true); // alloc must therefore return NULL on the very first call.
u8 buf[4] = {0};
BudgetAllocator bp = BudgetAllocatorInit(buf, sizeof(buf), sizeof(Node));
bool ok = (bp.slot_count == 0);- In
Budget.c:21:
static void budget_validate_self(const Allocator *self) {
if (!self || self->__magic != MISRA_BUDGET_ALLOCATOR_MAGIC) {
LOG_FATAL("type-confusion: allocator passed to budget_allocator_* is not a BudgetAllocator");
}
}- In
Budget.c:35:
void *budget_allocator_allocate(Allocator *self, size bytes, i8 zeroed) {
budget_validate_self(self);
BudgetAllocator *bp = (BudgetAllocator *)self;
if (bytes > bp->slot_size) {
return NULL;- In
Budget.c:52:
void *budget_allocator_reallocate(Allocator *self, void *ptr, size old_size, size new_size) {
budget_validate_self(self);
BudgetAllocator *bp = (BudgetAllocator *)self;
(void)old_size;- In
Budget.c:72:
void budget_allocator_deallocate(Allocator *self, void *ptr, size bytes) {
budget_validate_self(self);
BudgetAllocator *bp = (BudgetAllocator *)self;
(void)bytes;
if (!ptr) {- In
Budget.c:82:
}
static BudgetAllocator budget_build(void *buf, size buf_bytes, size slot_size, size alignment) {
BudgetAllocator empty = {0};
if (!buf || !slot_size) {- In
Budget.c:83:
static BudgetAllocator budget_build(void *buf, size buf_bytes, size slot_size, size alignment) {
BudgetAllocator empty = {0};
if (!buf || !slot_size) {
return empty;- In
Budget.c:109:
}
BudgetAllocator bp = {
.base =
{.allocate = budget_allocator_allocate,- In
Budget.c:135:
}
BudgetAllocator BudgetAllocatorInit(void *buf, size buf_bytes, size slot_size) {
return budget_build(buf, buf_bytes, slot_size, sizeof(void *));
}- In
Budget.c:139:
}
BudgetAllocator BudgetAllocatorInitAligned(void *buf, size buf_bytes, size slot_size, size alignment) {
return budget_build(buf, buf_bytes, slot_size, alignment);
}- In
Budget.c:143:
}
void BudgetAllocatorDeinit(BudgetAllocator *self) {
if (!self) {
return;- In
Allocator.h:34:
typedef struct ArenaAllocator ArenaAllocator;
typedef struct SlabAllocator SlabAllocator;
typedef struct BudgetAllocator BudgetAllocator;
// `zeroed` uses `i8` (signed char) directly instead of `bool` to
- In
Allocator.h:179:
ArenaAllocator *: (Allocator *)(allocator_ptr), \
SlabAllocator *: (Allocator *)(allocator_ptr), \
BudgetAllocator *: (Allocator *)(allocator_ptr) \
)- In
Budget.h:72:
size slot_count;
BudgetFreeSlot *free_head;
} BudgetAllocator;
void *budget_allocator_allocate(Allocator *self, size bytes, i8 zeroed);- In
Budget.h:97:
/// TAGS: Allocator, Budget, Init
///
BudgetAllocator BudgetAllocatorInit(void *buf, size buf_bytes, size slot_size);
///
- In
Budget.h:111:
/// TAGS: Allocator, Budget, Init, Alignment
///
BudgetAllocator BudgetAllocatorInitAligned(void *buf, size buf_bytes, size slot_size, size alignment);
///
- In
Budget.h:125:
/// TAGS: Allocator, Budget, Cleanup
///
void BudgetAllocatorDeinit(BudgetAllocator *self);
#ifdef __cplusplus
Last updated on