#include #include #include static struct arena_chunk* arena_create_chunk (size_t capacity) { size_t size = sizeof (struct arena_chunk) + sizeof (uintptr_t) * capacity; struct arena_chunk* chunk = malloc (size); if (chunk == NULL) return NULL; chunk->next = NULL; chunk->size = 0; chunk->capacity = capacity; return chunk; } static void arena_destroy_chunk (struct arena_chunk* chunk) { free (chunk); } void arena_reset (struct arena* arena) { for (struct arena_chunk* chunk = arena->begin; chunk != NULL; chunk = chunk->next) { chunk->size = 0; } arena->end = arena->begin; } void arena_destroy (struct arena* arena) { struct arena_chunk* chunk = arena->begin; while (chunk) { struct arena_chunk* chunk1 = chunk; chunk = chunk->next; arena_destroy_chunk (chunk1); } arena->begin = NULL; arena->end = NULL; } void* arena_malloc (struct arena* arena, size_t size) { size_t size1 = (size + sizeof (uintptr_t) - 1) / sizeof (uintptr_t); if (arena->end == NULL) { size_t capacity = ARENA_CHUNK_CAPACITY; if (capacity < size1) { capacity = size1; } arena->end = arena_create_chunk (capacity); if (arena->end == NULL) { return NULL; } arena->begin = arena->end; } while (arena->end->size + size1 > arena->end->capacity && arena->end->next != NULL) { arena->end = arena->end->next; } if (arena->end->size + size1 > arena->end->capacity) { size_t capacity = ARENA_CHUNK_CAPACITY; if (capacity < size1) { capacity = size1; } arena->end = arena_create_chunk (capacity); arena->end = arena->end->next; } void* result = &arena->end->memory[arena->end->size]; arena->end->size += size1; return result; } void* arena_realloc (struct arena* arena, void* memory, size_t prev_size, size_t new_size) { if (new_size <= prev_size) return memory; void* new_memory = arena_malloc (arena, new_size); for (size_t i = 0; i < prev_size; i++) ((uint8_t*)new_memory)[i] = ((uint8_t*)memory)[i]; return new_memory; }