Files
Nils O. Selåsdal 6185de0694 Cleanups
2026-05-14 14:45:29 +02:00

53 lines
1.6 KiB
C

#ifndef LALLOC_H_
#define LALLOC_H_
#include <stdint.h>
#include <stddef.h>
#ifdef __ccplusplus
extern "C" {
#endif
// Internal header added in front of each allocation
typedef struct LBlockHeader LBlockHeader;
struct LBlockHeader {
uint32_t next; // offset from base
uint32_t prev; // offset from base
uint32_t 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.
* - Allocated pointers are aligned to 16 bytes.
* - Backing buffer must be aligned to 16 bytes start
* - 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
* fragmentation to a minimum
*/
typedef struct LAlloc LAlloc;
struct LAlloc {
uint8_t *base; // backing store
uint32_t size; // total size
LBlockHeader *next_alloc; // start of free block search
};
void lalloc_init(LAlloc *allocator, void *backing_store, uint32_t size);
void *lalloc(LAlloc *allocator, uint32_t size);
void lfree(LAlloc *allocator, void *ptr);
LBlockHeader *lblock_from_offset(const LAlloc *allocator, uint32_t offset);
uint32_t lblock_size(const LBlockHeader *block);
int lblock_is_free(const LBlockHeader *block);
#ifdef __ccplusplus
} // extern "C"
#endif
#endif