Improve modularity, introduce arena_create()

This commit is contained in:
seajee
2025-07-24 15:38:21 +02:00
parent 49e0e14d7c
commit 26fd7f1118
2 changed files with 43 additions and 16 deletions

54
arena.h
View File

@@ -3,27 +3,42 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifndef ARENA_MIN_CAPACITY #ifndef ARENA_REGION_CAPACITY
#define ARENA_MIN_CAPACITY 4096 # define ARENA_REGION_CAPACITY (8*1024)
#endif // ARENA_MIN_CAPACITY #endif // ARENA_REGION_CAPACITY
#ifndef ARENA_ASSERT
# include <assert.h>
# define ARENA_ASSERT assert
#endif // ARENA_ASSERT
#ifndef ARENA_REALLOC
# include <stdlib.h>
# define ARENA_REALLOC realloc
#endif // ARENA_REALLOC
#ifndef ARENA_FREE
# include <stdlib.h>
# define ARENA_FREE free
#endif // ARENA_FREE
typedef struct Arena_Region Arena_Region; typedef struct Arena_Region Arena_Region;
struct Arena_Region { struct Arena_Region {
Arena_Region *next;
size_t count; size_t count;
size_t capacity; size_t capacity;
Arena_Region *next;
uint8_t data[]; uint8_t data[];
}; };
typedef struct { typedef struct {
Arena_Region *head; Arena_Region *head;
Arena_Region *tail; Arena_Region *tail;
size_t region_capacity;
} Arena; } Arena;
Arena arena_create(size_t min_capacity);
void *arena_alloc(Arena *a, size_t bytes); void *arena_alloc(Arena *a, size_t bytes);
void arena_free(Arena *a); void arena_free(Arena *a);
void arena_reset(Arena *a); void arena_reset(Arena *a);
@@ -32,20 +47,30 @@ void arena_reset(Arena *a);
#ifdef ARENA_IMPLEMENTATION #ifdef ARENA_IMPLEMENTATION
Arena arena_create(size_t region_capacity)
{
Arena a = {0};
a.region_capacity = region_capacity;
return a;
}
void *arena_alloc(Arena *a, size_t bytes) void *arena_alloc(Arena *a, size_t bytes)
{ {
if (a == NULL) { if (a == NULL) {
return NULL; return NULL;
} }
size_t region_capacity = (a->region_capacity == 0
? ARENA_REGION_CAPACITY : a->region_capacity);
// Empty arena // Empty arena
if (a->head == NULL) { if (a->head == NULL) {
size_t size = (bytes > ARENA_MIN_CAPACITY ? bytes : ARENA_MIN_CAPACITY); size_t size = (bytes > region_capacity ? bytes : region_capacity);
a->head = (Arena_Region*)malloc(sizeof(*a->head) + size); a->head = (Arena_Region*)ARENA_REALLOC(NULL, sizeof(*a->head) + size);
ARENA_ASSERT(a->head != NULL);
if (a->head == NULL) { if (a->head == NULL) {
return NULL; return NULL;
} }
memset(a->head, 0, sizeof(*a->head));
a->head->count = bytes; a->head->count = bytes;
a->head->capacity = size; a->head->capacity = size;
a->tail = a->head; a->tail = a->head;
@@ -66,14 +91,15 @@ void *arena_alloc(Arena *a, size_t bytes)
} }
// If not create a new region // If not create a new region
a->tail->next = (Arena_Region*)malloc(sizeof(*a->tail) + bytes); size_t size = (bytes > region_capacity ? bytes : region_capacity);
a->tail->next = (Arena_Region*)ARENA_REALLOC(NULL, sizeof(*a->tail) + size);
ARENA_ASSERT(a->head != NULL);
if (a->tail->next == NULL) { if (a->tail->next == NULL) {
return NULL; return NULL;
} }
a->tail = a->tail->next; a->tail = a->tail->next;
memset(a->tail, 0, sizeof(*a->tail));
a->tail->count = bytes; a->tail->count = bytes;
a->tail->capacity = bytes; a->tail->capacity = size;
return a->tail->data; return a->tail->data;
} }
@@ -94,7 +120,9 @@ void arena_free(Arena *a)
cur = next; cur = next;
} }
memset(a, 0, sizeof(*a)); a->head = NULL;
a->tail = NULL;
a->region_capacity = 0;
} }
void arena_reset(Arena *a) void arena_reset(Arena *a)

5
test.c
View File

@@ -2,13 +2,12 @@
#include <stdlib.h> #include <stdlib.h>
#ifdef DEBUG #ifdef DEBUG
#define malloc(n) (printf("%s:%d:%s: malloc(%ld)\n",\ #define realloc(p, s) (printf("%s:%d:%s: realloc(%p, %lu)\n",\
__FILE__, __LINE__, __func__, (n)), malloc((n))); __FILE__, __LINE__, __func__, (p), (s)), realloc((p), (s)));
#define free(p) (printf("%s:%d:%s: free(%p)\n",\ #define free(p) (printf("%s:%d:%s: free(%p)\n",\
__FILE__, __LINE__, __func__, (p)), free((p))); __FILE__, __LINE__, __func__, (p)), free((p)));
#endif // DEBUG #endif // DEBUG
#define ARENA_MIN_CAPACITY 400
#define ARENA_IMPLEMENTATION #define ARENA_IMPLEMENTATION
#include "arena.h" #include "arena.h"