various fixes for arena allocator

This commit is contained in:
Lorenzo Torres 2025-11-12 15:15:27 +01:00
parent c0afc54ca1
commit 2f8a8ed763
2 changed files with 40 additions and 63 deletions

View file

@ -3,54 +3,39 @@
#include "log.h" #include "log.h"
#include <stdlib.h> #include <stdlib.h>
struct arena_allocator *arena_init(usize size) arena arena_init(usize size)
{ {
struct arena_allocator *allocator = return (arena){
(struct arena_allocator *)malloc(sizeof(struct arena_allocator)); .capacity = size,
allocator->size = size; .position = 0,
allocator->base = (usize) malloc(size); .memory = malloc(size),
allocator->position = 0; };
return allocator;
} }
void arena_deinit(struct arena_allocator *allocator) void *arena_alloc(arena *a, usize size)
{ {
#ifdef DEBUG if (a->position + size > a->capacity) return NULL;
if (!allocator) { void *ret = (void *)((usize)a->memory + (usize)a->position);
log_error("attempt to free NULL arena\n"); a->position += size;
return; return ret;
}
#endif
free((void *)allocator->base);
free((void *)allocator);
} }
void *arena_alloc(struct arena_allocator *allocator, usize size) snapshot arena_snapshot(arena a)
{ {
if (allocator->position + size >= allocator->size) { return a.position;
allocator->size = allocator->position + size;
allocator->base =
(usize) realloc((void *)allocator->base,
allocator->size + allocator->size / 2);
}
void *ptr = (void *)(allocator->base + allocator->position);
allocator->position += size;
return ptr;
} }
void *arena_zalloc(struct arena_allocator *allocator, usize size) void arena_reset_to_snapshot(arena *a, snapshot s)
{ {
void *ptr = arena_alloc(allocator, size); a->position = s;
for (usize i = 0; i < size; i++) {
((u8 *) ptr)[i] = 0x0;
} }
return ptr; void arena_reset(arena *a)
}
void arena_bump(struct arena_allocator *allocator)
{ {
allocator->position = 0; arena_reset_to_snapshot(a, 0);
}
void arena_deinit(arena a)
{
free(a.memory);
} }

View file

@ -1,39 +1,31 @@
/* SPDX-License-Identifier:BSD-3-Clause */ /* SPDX-License-Identifier:BSD-3-Clause */
#ifndef ARENA_H #ifndef ARENA_H
#define ARENA_H #define ARENA_H
#include "../types.h" #include "../types.h"
/* typedef struct {
* An arena is a fast allocator that just keeps everything in a contiguous usize capacity;
* chunk of memory and moves a "pointer" when allocating new memory. The
* allocated memory is then free'd all at once.
*/
struct arena_allocator {
usize size;
usize base;
usize position; usize position;
}; void* memory;
} arena;
extern struct arena_allocator *global_arena; typedef usize snapshot;
/* Create a new arena allocator of size `size` */
struct arena_allocator *arena_init(usize size);
/* Destroy the allocator and */
void arena_deinit(struct arena_allocator *allocator);
/* /*
* Allocate a chunk of memory of size `size` on the arena. * NOTE(ernesto): faulty initialization is signalided by the arena.memory
* being null. It is the responsability of the caller to check for fulty
* initialization.
*/ */
void *arena_alloc(struct arena_allocator *allocator, usize size); arena arena_init(usize size);
/* /*
* Same as `arena_alloc()` but also set all the allocated memory to zero. * Returns null on unsuccessfull allocation.
* In this implemention an allocation is only unsuccessfull if the arena
* does not have enough memory to allocate the requested space
*/ */
void *arena_zalloc(struct arena_allocator *allocator, usize size); void *arena_alloc(arena *a, usize size);
/* snapshot arena_snapshot(arena a);
* Free all the allocated memory at once. This just sets the allocator cursor void arena_reset_to_snapshot(arena *a, snapshot s);
* to its starting position. void arena_reset(arena *a);
*/ /* This call should never fail, also, do we even care if it does? */
void arena_bump(struct arena_allocator *allocator); void arena_deinit(arena a);
#endif #endif