Files
2026-10-31 11:14:30 -03:00

144 lines
2.9 KiB
C

#include "arena.h"
#include <string.h>
char* arena_strdup(Arena* ref_arena, const char* s){
char* str = (char*) arena_alloc(ref_arena, strlen(s) + 1);
if(str == NULL){
return NULL;
}
strcpy(str, s);
return str;
}
void* arena_chunk_alloc(Arena* ref_arena, Chunk* chunk, size_t s){
size_t aligned = (chunk->offset + (ARENA_MEMORY_ALIGN - 1)) & ~(ARENA_MEMORY_ALIGN -1);
if ((aligned + s <= chunk->size)){
chunk->offset = aligned;
void* start = (void *)(chunk->buffer + chunk->offset);
chunk->offset = aligned + s;
return start;
}
return NULL;
}
Chunk* arena_chunk_create(size_t s){
printf("Creating a new chunk of %zu bytes\n", s);
Chunk* chunk1 = (Chunk*)malloc(sizeof(Chunk));
if(chunk1 == NULL){
return NULL;
}
chunk1->size = s;
chunk1->offset = 0;
chunk1->next = NULL;
chunk1->buffer = (unsigned char *)malloc(s);
if(chunk1->buffer == NULL){
perror("Error creando chunk...\n");
free(chunk1);
chunk1 = NULL;
return NULL;
}
printf("Chunk creado correctamente\n");
return chunk1;
}
void arena_chunk_free(Chunk* chunk){
printf("Liberando %zu bytes de memoria\n", chunk->size);
if(chunk->buffer != NULL){
free(chunk->buffer);
chunk->buffer = NULL;
}
free(chunk);
}
void* arena_alloc(Arena* ref_arena, size_t s){
if(ref_arena == NULL){
return NULL;
}
if(ref_arena->current == NULL){
return NULL;
}
Chunk* current_chunk = ref_arena->current;
void* ptr = arena_chunk_alloc(ref_arena, current_chunk, s);
if(ptr == NULL){
size_t new_size = current_chunk->size * 2;
if(new_size < s){
new_size = s;
}
Chunk *new_chunk = arena_chunk_create(new_size);
if(new_chunk == NULL){
return NULL;
}
current_chunk->next = new_chunk;
new_chunk->next = NULL;
ref_arena->current = new_chunk;
return arena_alloc(ref_arena, s);
}
return ptr;
}
Arena arena_create(size_t s){
Arena new_arena = {
.current = NULL,
.first = NULL
};
Chunk* chunk1 = arena_chunk_create(s);
if(chunk1 == NULL){
perror("Error creando arena\n");
exit(1);
}
new_arena.current = chunk1;
new_arena.first = chunk1;
printf("Arena creada correctamente\n");
return new_arena;
}
void arena_free(Arena* ref_arena){
Chunk* item = ref_arena->first;
while (item != NULL) {
Chunk *next = item->next;
arena_chunk_free(item);
item = next;
}
ref_arena->first = NULL;
ref_arena->current = NULL;
printf("Arena liberada\n");
}
void arena_print(Arena* ref_arena){
printf("ARENA INFO\n");
printf("==========\n");
printf("first: %p\n", ref_arena->first);
printf("next: %p\n", ref_arena->current);
printf("==========\n");
}