#include "arena.h" #include 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"); }