#include #include "alloc.h" #include "list.h" #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif struct block_t { link_t link; uint8_t data[1]; }; void allocator_init (allocator_t *allocator) { list_init (&allocator->blocks); } void * allocator_alloc (allocator_t *allocator, size_t size) { block_t *block = malloc (sizeof (block_t) - 1 + size); if (!block) return NULL; list_prepend (&allocator->blocks, &block->link); return &(block->data[1]); } #define GET_BLOCK(mem) \ ((block_t *)(((uint8_t *)mem) - offsetof (block_t, data))) void * allocator_realloc (allocator_t *allocator, void *mem, size_t size) { block_t *old_block, *new_block; if (mem == NULL) return allocator_alloc (allocator, size); old_block = GET_BLOCK (mem); list_unlink (&old_block->link); new_block = realloc (old_block, sizeof (block_t) - 1 + size); if (!new_block) { list_prepend (&allocator->blocks, &old_block->link); return NULL; } else { list_prepend (&allocator->blocks, &new_block->link); return new_block->data; } } void allocator_free (allocator_t *allocator, void *mem) { block_t *block = GET_BLOCK (mem); list_unlink (&block->link); free (block); } void allocator_fini (allocator_t *allocator) { while (!list_is_empty (&allocator->blocks)) { block_t *block = CONTAINER_OF (block_t, link, allocator->blocks.head); list_unlink (&block->link); free (block); } }