42 lines
1.5 KiB
C
42 lines
1.5 KiB
C
#pragma once
|
|
#include "core.h"
|
|
|
|
// Internal header added in front of each allocation
|
|
typedef struct LBlockHeader LBlockHeader;
|
|
struct LBlockHeader {
|
|
U32 next; // offset from base
|
|
U32 prev; // offset from base
|
|
U32 size_and_flags; // size | free_bit
|
|
// Padding to ensure we always return 16 byte aligned pointers.
|
|
uint8_t pad[4];
|
|
};
|
|
_Static_assert(sizeof(LBlockHeader) == 16, "sizeof(BlockHeader) is not 16");
|
|
|
|
/**
|
|
* General purpose allocator from a pre-defined backing store
|
|
* - Allocated pointers are aligned to 16 bytes.
|
|
* - Backing buffer must be aligned to 16 bytes
|
|
* - 4Gb - 16 is max for the allocator backing buffer.
|
|
* - Allocation of > 0 bytes returns a size aligned up to 16 bytes
|
|
* - Allocation of 0 bytes returns a valid pointer with 0 usable space
|
|
* The allocator maintains a doubly linked list of blocks,
|
|
* when blocks are free'd, adjacent blocks are merged to keep.
|
|
* This is also known as a buddy allocator
|
|
* fragmentation to a minimum
|
|
*/
|
|
typedef struct LAlloc LAlloc;
|
|
struct LAlloc {
|
|
uint8_t *base; // backing store
|
|
U32 size; // total size
|
|
LBlockHeader *next_alloc; // start of free block search
|
|
};
|
|
|
|
void lalloc_init(LAlloc *allocator, void *backing_store, U32 size);
|
|
|
|
void *lalloc(LAlloc *allocator, U32 size);
|
|
void lfree(LAlloc *allocator, void *ptr);
|
|
|
|
LBlockHeader *lblock_from_offset(const LAlloc *allocator, U32 offset);
|
|
U32 lblock_size(const LBlockHeader *block);
|
|
int lblock_is_free(const LBlockHeader *block);
|