feat: initial commit, basic arena

This commit is contained in:
2026-01-09 00:35:24 +02:00
parent ed1fa16625
commit 1dd4a788a8
8 changed files with 289 additions and 1 deletions

94
niarena.h Normal file
View File

@@ -0,0 +1,94 @@
#pragma once
#include "../ni-const/niconst.h"
// If custom memory management is provided, including this
// header can be skipped
#ifndef NIAREA_NO_STDLIB
#include <stdlib.h>
#endif
// The size can be defined by overriding this constant
#ifndef NIARENA_ARENA_SIZE
#define NIARENA_ARENA_SIZE NICONST_MIB_B(4)
#endif
// Custom memory management can be defined as well.
// Either both or none must be defined
#if (!defined(NIARENA_MALLOC) && defined(NIARENA_FREE)) || (defined(NIARENA_MALLOC) && !defined(NIARENA_FREE))
#error "Either both NIARENA_MALLOC and NIARENA_FREE have to be defined or neither of them"
#endif
#ifndef NIARENA_MALLOC
#define NIARENA_MALLOC(sz) malloc(sz)
#endif
#ifndef NIARENA_FREE
#define NIARENA_FREE(p) free(p)
#endif
// Definitions
typedef struct _NIArena {
void *buffer;
size_t capacity;
size_t offset;
} NIArena;
const char *niarena_get_error(void);
NIArena *niarena_new(void);
void *niarena_alloc(NIArena *arena, size_t size);
void niarena_delete(NIArena *arena);
#ifdef NIARENA_IMPLEMENTATION
static const char *niarena__error_reason = "";
static void
niarena_error(const char *reason)
{
niarena__error_reason = reason;
}
const char *
niarena_get_error(void)
{
return niarena__error_reason;
}
NIArena *
niarena_new(void)
{
NIArena *arena = NIARENA_MALLOC(sizeof(NIArena));
if(arena == NULL) {
niarena_error("niarena_new: out of memory allocating arena");
return NULL;
}
arena->buffer = NIARENA_MALLOC(NIARENA_ARENA_SIZE);
if(arena->buffer == NULL) {
NIARENA_FREE(arena);
niarena_error("niarena_new: out of memory allocating buffer");
return NULL;
}
arena->capacity = NIARENA_ARENA_SIZE;
return arena;
}
void *
niarena_alloc(NIArena *arena, size_t size)
{
if((arena->capacity - arena->offset) < size) {
// The allocation is invalid, but the contents of the arena
// can still be used (previous allocations).
niarena_error("niarena_alloc: out of memory inside of the arena");
return NULL;
}
arena->offset += size;
return (void *)((char *)arena->buffer + arena->offset);
}
void
niarena_delete(NIArena *arena)
{
NIARENA_FREE(arena->buffer);
NIARENA_FREE(arena);
}
#endif