Files
r/src/core/memory.c
T

108 lines
2.5 KiB
C
Raw Normal View History

// retoor <retoor@molodetz.nl>
#include "memory.h"
#include <stdlib.h>
#include <string.h>
arena_t *arena_create(size_t chunk_size) {
if (chunk_size == 0) chunk_size = 4096;
arena_t *arena = calloc(1, sizeof(arena_t));
if (!arena) return NULL;
arena->block_size = chunk_size;
arena->current_block = malloc(chunk_size);
if (!arena->current_block) {
free(arena);
return NULL;
}
arena_block_t *block_info = calloc(1, sizeof(arena_block_t));
if (!block_info) {
free(arena->current_block);
free(arena);
return NULL;
}
block_info->data = arena->current_block;
block_info->size = chunk_size;
arena->blocks = block_info;
arena->block_count = 1;
return arena;
}
void *arena_alloc(arena_t *arena, size_t size) {
if (!arena || size == 0) return NULL;
size_t aligned_size = (size + 7) & ~7;
if (arena->block_used + aligned_size > arena->block_size) {
arena_block_t *new_block = calloc(1, sizeof(arena_block_t));
if (!new_block) return NULL;
char *new_data = malloc(arena->block_size);
if (!new_data) {
free(new_block);
return NULL;
}
new_block->data = new_data;
new_block->size = arena->block_size;
new_block->next = arena->blocks;
arena->blocks = new_block;
arena->current_block = new_data;
arena->block_used = 0;
arena->block_count++;
}
void *ptr = arena->current_block + arena->block_used;
arena->block_used += aligned_size;
return ptr;
}
char *arena_strdup(arena_t *arena, const char *str) {
if (!arena || !str) return NULL;
size_t len = strlen(str);
char *copy = arena_alloc(arena, len + 1);
if (!copy) return NULL;
memcpy(copy, str, len + 1);
return copy;
}
void arena_reset(arena_t *arena) {
if (!arena) return;
arena->block_used = 0;
arena_block_t *block = arena->blocks;
while (block) {
arena_block_t *next = block->next;
if (block != arena->blocks) {
free(block->data);
free(block);
}
block = next;
}
arena->blocks->next = NULL;
arena->current_block = arena->blocks->data;
arena->block_count = 1;
}
void arena_destroy(arena_t *arena) {
if (!arena) return;
arena_block_t *block = arena->blocks;
while (block) {
arena_block_t *next = block->next;
free(block->data);
free(block);
block = next;
}
free(arena);
}