Improve modularity, introduce arena_create()
This commit is contained in:
54
arena.h
54
arena.h
@@ -3,27 +3,42 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ARENA_MIN_CAPACITY
|
||||
#define ARENA_MIN_CAPACITY 4096
|
||||
#endif // ARENA_MIN_CAPACITY
|
||||
#ifndef ARENA_REGION_CAPACITY
|
||||
# define ARENA_REGION_CAPACITY (8*1024)
|
||||
#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;
|
||||
|
||||
struct Arena_Region {
|
||||
Arena_Region *next;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
Arena_Region *next;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
Arena_Region *head;
|
||||
Arena_Region *tail;
|
||||
size_t region_capacity;
|
||||
} Arena;
|
||||
|
||||
Arena arena_create(size_t min_capacity);
|
||||
void *arena_alloc(Arena *a, size_t bytes);
|
||||
void arena_free(Arena *a);
|
||||
void arena_reset(Arena *a);
|
||||
@@ -32,20 +47,30 @@ void arena_reset(Arena *a);
|
||||
|
||||
#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)
|
||||
{
|
||||
if (a == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t region_capacity = (a->region_capacity == 0
|
||||
? ARENA_REGION_CAPACITY : a->region_capacity);
|
||||
|
||||
// Empty arena
|
||||
if (a->head == NULL) {
|
||||
size_t size = (bytes > ARENA_MIN_CAPACITY ? bytes : ARENA_MIN_CAPACITY);
|
||||
a->head = (Arena_Region*)malloc(sizeof(*a->head) + size);
|
||||
size_t size = (bytes > region_capacity ? bytes : region_capacity);
|
||||
a->head = (Arena_Region*)ARENA_REALLOC(NULL, sizeof(*a->head) + size);
|
||||
ARENA_ASSERT(a->head != NULL);
|
||||
if (a->head == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(a->head, 0, sizeof(*a->head));
|
||||
a->head->count = bytes;
|
||||
a->head->capacity = size;
|
||||
a->tail = a->head;
|
||||
@@ -66,14 +91,15 @@ void *arena_alloc(Arena *a, size_t bytes)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return NULL;
|
||||
}
|
||||
a->tail = a->tail->next;
|
||||
memset(a->tail, 0, sizeof(*a->tail));
|
||||
a->tail->count = bytes;
|
||||
a->tail->capacity = bytes;
|
||||
a->tail->capacity = size;
|
||||
return a->tail->data;
|
||||
}
|
||||
|
||||
@@ -94,7 +120,9 @@ void arena_free(Arena *a)
|
||||
cur = next;
|
||||
}
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
a->head = NULL;
|
||||
a->tail = NULL;
|
||||
a->region_capacity = 0;
|
||||
}
|
||||
|
||||
void arena_reset(Arena *a)
|
||||
|
||||
5
test.c
5
test.c
@@ -2,13 +2,12 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define malloc(n) (printf("%s:%d:%s: malloc(%ld)\n",\
|
||||
__FILE__, __LINE__, __func__, (n)), malloc((n)));
|
||||
#define realloc(p, s) (printf("%s:%d:%s: realloc(%p, %lu)\n",\
|
||||
__FILE__, __LINE__, __func__, (p), (s)), realloc((p), (s)));
|
||||
#define free(p) (printf("%s:%d:%s: free(%p)\n",\
|
||||
__FILE__, __LINE__, __func__, (p)), free((p)));
|
||||
#endif // DEBUG
|
||||
|
||||
#define ARENA_MIN_CAPACITY 400
|
||||
#define ARENA_IMPLEMENTATION
|
||||
#include "arena.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user