Improve modularity, introduce arena_create()
This commit is contained in:
54
arena.h
54
arena.h
@@ -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
5
test.c
@@ -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"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user