feat: initial commit, basic arena
This commit is contained in:
94
niarena.h
Normal file
94
niarena.h
Normal 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
|
||||
Reference in New Issue
Block a user