Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fe838e696 | ||
|
|
4ddc450000 | ||
|
|
9df2c60cd0 | ||
|
|
0dcf9bc6d3 | ||
|
|
b6a8c263a3 | ||
|
|
db94f5895a | ||
|
|
66da5acdc9 | ||
|
|
1a6b7e05f0 | ||
|
|
076b152555 | ||
|
|
9ed137abcb | ||
|
|
05c6f067e9 |
+2
-1
@@ -80,7 +80,8 @@ static INLINE void *arena_allocator_func(Allocator *allocator, AllocOperation op
|
|||||||
case Alloc_Op_Aligned:
|
case Alloc_Op_Aligned:
|
||||||
return arena_push(allocator->data, size, align);
|
return arena_push(allocator->data, size, align);
|
||||||
|
|
||||||
case Alloc_Op_Free: // can't free from an marena
|
case Alloc_Op_Free: // can't free from an arena
|
||||||
|
NotImplemented;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case Alloc_Op_Free_All:
|
case Alloc_Op_Free_All:
|
||||||
|
|||||||
@@ -102,9 +102,11 @@ static INLINE void *marena_allocator_func(Allocator *allocator, AllocOperation o
|
|||||||
return marena_push_aligned(allocator->data, size, align);
|
return marena_push_aligned(allocator->data, size, align);
|
||||||
|
|
||||||
case Alloc_Op_Free: // can't free/Free_all from an marena
|
case Alloc_Op_Free: // can't free/Free_all from an marena
|
||||||
|
NotImplemented;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case Alloc_Op_Free_All:
|
case Alloc_Op_Free_All:
|
||||||
|
marena_reset(allocator->data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ static void *platform_allocator_func(Allocator *allocator, AllocOperation operat
|
|||||||
case Alloc_Op_Aligned:
|
case Alloc_Op_Aligned:
|
||||||
return aligned_alloc(size, align);
|
return aligned_alloc(size, align);
|
||||||
|
|
||||||
case Alloc_Op_Free: // can't free/Free_all from an marena
|
case Alloc_Op_Free:
|
||||||
free(memory);
|
free(memory);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
+26
-20
@@ -1,33 +1,35 @@
|
|||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
|
|
||||||
APool *apool_create_ex(Allocator *allocator, U32 n_elements, U32 element_size, U32 element_align)
|
APool *apool_create_ex(Allocator *allocator, const APoolCreateOptions *options)
|
||||||
{
|
{
|
||||||
Assert(IsPow2(element_align));
|
Assert(IsPow2(options->element_align));
|
||||||
U32 align = element_align;
|
U32 element_align = options->element_align;
|
||||||
if (element_align < alignof(APoolElement)) {
|
if (element_align < alignof(APoolElement)) {
|
||||||
element_align = alignof(APoolElement);
|
element_align = alignof(APoolElement);
|
||||||
}
|
}
|
||||||
U32 size = AlignUp(element_size, element_align);
|
U32 element_size = AlignUp(options->element_size, options->element_align);
|
||||||
|
|
||||||
APool *pool = allocator_push_type(allocator, APool);
|
APool *pool = allocator_push_type(allocator, APool);
|
||||||
Assert(pool != NULL);
|
Assert(pool != NULL);
|
||||||
pool->align = align;
|
pool->element_align= element_align;
|
||||||
pool->element_size = size;
|
pool->element_size = element_size;
|
||||||
pool->allocator = allocator;
|
pool->allocator = allocator;
|
||||||
pool->n_elements = n_elements;
|
pool->n_elements = 0;
|
||||||
pool->free_list = NULL;
|
pool->n_free = 0;
|
||||||
pool->start = NULL;
|
pool->free_list = NULL;
|
||||||
|
pool->flags = options->flags;
|
||||||
|
|
||||||
if (size != APOOL_AUTOGROW) {
|
if (options->n_reserved != 0) {
|
||||||
Assert(n_elements <= U32_Max / size );
|
Assert(options->n_reserved <= U32_Max / element_size );
|
||||||
U32 total_size = n_elements * size;
|
U32 total_size = options->n_reserved * element_size;
|
||||||
U8 * start = allocator_push(allocator, total_size, align);
|
U8 *start = allocator_push(allocator, total_size, element_align);
|
||||||
for (U32 i = 0; i < total_size; i += size) {
|
for (U32 i = 0; i < total_size; i += element_size) {
|
||||||
APoolElement *element = (APoolElement *)&start[i];
|
APoolElement *element = (APoolElement *)&start[i];
|
||||||
element->next = pool->free_list;
|
element->next = pool->free_list;
|
||||||
pool->free_list = element;
|
pool->free_list = element;
|
||||||
|
pool->n_elements++;
|
||||||
}
|
}
|
||||||
pool->start = start;
|
pool->n_free = pool->n_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pool;
|
return pool;
|
||||||
@@ -38,8 +40,12 @@ void *apool_alloc(APool *pool)
|
|||||||
APoolElement *element = pool->free_list;
|
APoolElement *element = pool->free_list;
|
||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
pool->free_list = element->next;
|
pool->free_list = element->next;
|
||||||
} else if(pool->n_elements == APOOL_AUTOGROW) {
|
pool->n_free--;
|
||||||
element = allocator_push(pool->allocator, pool->element_size, pool->align);
|
} else if((pool->flags & APoolFlag_AutoGrow) != 0) {
|
||||||
|
element = allocator_push(pool->allocator, pool->element_size, pool->element_align);
|
||||||
|
if (element != NULL) {
|
||||||
|
pool->n_elements++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
@@ -48,10 +54,10 @@ void *apool_alloc(APool *pool)
|
|||||||
void apool_free(APool *pool, void *ptr)
|
void apool_free(APool *pool, void *ptr)
|
||||||
{
|
{
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
Assert((U8 *)ptr >= pool->start);
|
|
||||||
|
|
||||||
APoolElement *element = (APoolElement *)ptr;
|
APoolElement *element = (APoolElement *)ptr;
|
||||||
element->next = pool->free_list;
|
element->next = pool->free_list;
|
||||||
pool->free_list = element;
|
pool->free_list = element;
|
||||||
|
pool->n_free++;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-10
@@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
APoolFlag_AutoGrow = (1 << 0)
|
||||||
|
};
|
||||||
|
typedef U32 APoolFlags;
|
||||||
typedef union APoolElement APoolElement;
|
typedef union APoolElement APoolElement;
|
||||||
union APoolElement {
|
union APoolElement {
|
||||||
APoolElement *next; // offset from start to next free block (when not allocated)
|
APoolElement *next; // offset from start to next free block (when not allocated)
|
||||||
@@ -9,18 +13,23 @@ union APoolElement {
|
|||||||
typedef struct APool APool;
|
typedef struct APool APool;
|
||||||
struct APool {
|
struct APool {
|
||||||
APoolElement *free_list; // free list
|
APoolElement *free_list; // free list
|
||||||
U8 *start; // start of user buffer
|
|
||||||
Allocator *allocator;
|
Allocator *allocator;
|
||||||
U32 element_size; // aligned size of each block
|
APoolFlags flags;
|
||||||
U32 n_elements; // total number of blocks
|
U32 element_size; // aligned size of each element
|
||||||
U32 align; // alignment
|
U32 element_align; // alignment
|
||||||
};
|
U32 n_elements; // total elements in the pool
|
||||||
enum {
|
U32 n_free; // number of free elements
|
||||||
APOOL_AUTOGROW = 0
|
|
||||||
};
|
};
|
||||||
|
typedef struct APoolCreateOptions APoolCreateOptions;
|
||||||
|
struct APoolCreateOptions {
|
||||||
|
U32 element_size; // aligned size of each element
|
||||||
|
U32 element_align; // alignment of elements
|
||||||
|
U32 n_reserved; // number of elements reserved
|
||||||
|
APoolFlags flags;
|
||||||
|
|
||||||
#define apool_create(arena, n_elements, type) \
|
};
|
||||||
apool_create_ex(arena, n_elements, sizeof(type), alignof(type));
|
#define apool_create(arena, n_reserved, type) \
|
||||||
APool *apool_create_ex(Allocator *allocator, U32 n_elements, U32 element_size, uint32_t element_align);
|
apool_create_ex(arena, &(APoolCreateOptions){sizeof(type), alignof(type), n_reserved, 0})
|
||||||
|
APool *apool_create_ex(Allocator *allocator, const APoolCreateOptions *options);
|
||||||
void *apool_alloc(APool *pool);
|
void *apool_alloc(APool *pool);
|
||||||
void apool_free(APool *pool, void *element);
|
void apool_free(APool *pool, void *element);
|
||||||
|
|||||||
+38
-22
@@ -26,7 +26,7 @@ void arena_dump(const Arena *arena)
|
|||||||
}
|
}
|
||||||
static void arena_test_1(void)
|
static void arena_test_1(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
ArenaOptions arena_params = {};
|
ArenaOptions arena_params = {};
|
||||||
U32 arena_size = MB(1) + MemoryBlock_Header_Size;
|
U32 arena_size = MB(1) + MemoryBlock_Header_Size;
|
||||||
U32 commit_size = KB(8);
|
U32 commit_size = KB(8);
|
||||||
@@ -53,7 +53,7 @@ static void arena_test_1(void)
|
|||||||
|
|
||||||
static void arena_test_2(void)
|
static void arena_test_2(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
ArenaOptions arena_params = {};
|
ArenaOptions arena_params = {};
|
||||||
U32 arena_size = MB(3) + MemoryBlock_Header_Size;
|
U32 arena_size = MB(3) + MemoryBlock_Header_Size;
|
||||||
@@ -106,7 +106,7 @@ static void arena_test_2(void)
|
|||||||
|
|
||||||
static void arena_test_3(void)
|
static void arena_test_3(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
ArenaOptions arena_params = {};
|
ArenaOptions arena_params = {};
|
||||||
U32 arena_size = KB(97) + MemoryBlock_Header_Size;
|
U32 arena_size = KB(97) + MemoryBlock_Header_Size;
|
||||||
@@ -134,7 +134,7 @@ static void arena_test_3(void)
|
|||||||
// gap was not accounted for. After the fix this should allocate a larger block.
|
// gap was not accounted for. After the fix this should allocate a larger block.
|
||||||
static void arena_test_4(void)
|
static void arena_test_4(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
U32 page_size = platform_page_size();
|
U32 page_size = platform_page_size();
|
||||||
ArenaOptions arena_params = {};
|
ArenaOptions arena_params = {};
|
||||||
@@ -167,7 +167,7 @@ static void arena_test_4(void)
|
|||||||
|
|
||||||
static void arena_test_allocator_interface(void)
|
static void arena_test_allocator_interface(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
U32 page_size = platform_page_size();
|
U32 page_size = platform_page_size();
|
||||||
ArenaOptions arena_params = {};
|
ArenaOptions arena_params = {};
|
||||||
@@ -203,7 +203,7 @@ static void arena_test_allocator_interface(void)
|
|||||||
|
|
||||||
static void arena_test_decommit(void)
|
static void arena_test_decommit(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
U32 page_size = platform_page_size();
|
U32 page_size = platform_page_size();
|
||||||
ArenaOptions arena_params = {};
|
ArenaOptions arena_params = {};
|
||||||
@@ -230,7 +230,7 @@ static void arena_test_decommit(void)
|
|||||||
|
|
||||||
void miniarena_test1(void)
|
void miniarena_test1(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
#define arena_size 4096
|
#define arena_size 4096
|
||||||
MARENA_DEFINE(arena, arena_size, 8);
|
MARENA_DEFINE(arena, arena_size, 8);
|
||||||
@@ -269,12 +269,18 @@ struct PoolTest{
|
|||||||
|
|
||||||
void apool_test(void)
|
void apool_test(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Arena arena;
|
Arena arena;
|
||||||
arena_init(&arena, &ArenaOptions_Default);
|
arena_init(&arena, &ArenaOptions_Default);
|
||||||
Allocator allocator = arena_allocator(&arena);
|
Allocator allocator = arena_allocator(&arena);
|
||||||
APool *pool = apool_create_ex(&allocator, 16, sizeof(PoolTest), alignof(PoolTest));
|
APoolCreateOptions opts = {
|
||||||
|
.n_reserved= 16,
|
||||||
|
.element_size = sizeof(PoolTest),
|
||||||
|
.element_align = alignof(PoolTest),
|
||||||
|
.flags = 0
|
||||||
|
};
|
||||||
|
APool *pool = apool_create_ex(&allocator, &opts);
|
||||||
PoolTest *list = NULL;
|
PoolTest *list = NULL;
|
||||||
for (U32 i = 0; i < U32_Max; i++) {
|
for (U32 i = 0; i < U32_Max; i++) {
|
||||||
PoolTest *pt = apool_alloc(pool);
|
PoolTest *pt = apool_alloc(pool);
|
||||||
@@ -297,6 +303,7 @@ void apool_test(void)
|
|||||||
printf("Pooltest freeing %u\n",p->n);
|
printf("Pooltest freeing %u\n",p->n);
|
||||||
apool_free(pool, p);
|
apool_free(pool, p);
|
||||||
}
|
}
|
||||||
|
printf("Pooltest total: %u free %u\n", pool->n_elements, pool->n_free);
|
||||||
list = NULL;
|
list = NULL;
|
||||||
for (U32 i = 0; i < U32_Max; i++) {
|
for (U32 i = 0; i < U32_Max; i++) {
|
||||||
PoolTest *pt = apool_alloc(pool);
|
PoolTest *pt = apool_alloc(pool);
|
||||||
@@ -316,13 +323,13 @@ void apool_test(void)
|
|||||||
|
|
||||||
void apool_test_miniarena(void)
|
void apool_test_miniarena(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
MArena arena;
|
MArena arena;
|
||||||
U8 data[4096];
|
U8 data[4096];
|
||||||
marena_init(&arena, data, sizeof data);
|
marena_init(&arena, data, sizeof data);
|
||||||
Allocator allocator = marena_allocator(&arena);
|
Allocator allocator = marena_allocator(&arena);
|
||||||
APool *pool = apool_create_ex(&allocator, 16, sizeof(PoolTest), alignof(PoolTest));
|
APool *pool = apool_create(&allocator, 16, PoolTest);
|
||||||
PoolTest *list = NULL;
|
PoolTest *list = NULL;
|
||||||
for (U32 i = 0; i < U32_Max; i++) {
|
for (U32 i = 0; i < U32_Max; i++) {
|
||||||
PoolTest *pt = apool_alloc(pool);
|
PoolTest *pt = apool_alloc(pool);
|
||||||
@@ -358,19 +365,26 @@ void apool_test_miniarena(void)
|
|||||||
for (PoolTest *p = list; p; p = p->next){
|
for (PoolTest *p = list; p; p = p->next){
|
||||||
printf("Pooltest %u\n",p->n);
|
printf("Pooltest %u\n",p->n);
|
||||||
}
|
}
|
||||||
|
printf("Pooltest total: %u free %u\n", pool->n_elements, pool->n_free);
|
||||||
|
|
||||||
allocator_free_all(&allocator);
|
allocator_free_all(&allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void apool_test_autogrow(void)
|
void apool_test_autogrow(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Arena arena;
|
Arena arena;
|
||||||
arena_init(&arena, &ArenaOptions_Default);
|
arena_init(&arena, &ArenaOptions_Default);
|
||||||
Allocator allocator = arena_allocator(&arena);
|
Allocator allocator = arena_allocator(&arena);
|
||||||
|
APoolCreateOptions opts = {
|
||||||
APool *pool = apool_create(&allocator, APOOL_AUTOGROW, PoolTest);
|
.n_reserved = 0,
|
||||||
|
.element_size = sizeof(PoolTest),
|
||||||
|
.element_align = alignof(PoolTest),
|
||||||
|
.flags = APoolFlag_AutoGrow
|
||||||
|
};
|
||||||
|
APool *pool = apool_create_ex(&allocator, &opts);
|
||||||
PoolTest *list = NULL;
|
PoolTest *list = NULL;
|
||||||
for (U32 i = 0; i < 4; i++) {
|
for (U32 i = 0; i < 4; i++) {
|
||||||
PoolTest *pt = apool_alloc(pool);
|
PoolTest *pt = apool_alloc(pool);
|
||||||
@@ -384,6 +398,7 @@ void apool_test_autogrow(void)
|
|||||||
for (PoolTest *p = list; p; p = p->next){
|
for (PoolTest *p = list; p; p = p->next){
|
||||||
printf("Pooltest %u\n",p->n);
|
printf("Pooltest %u\n",p->n);
|
||||||
}
|
}
|
||||||
|
printf("Pooltest total: %u free %u\n", pool->n_elements, pool->n_free);
|
||||||
|
|
||||||
PoolTest *next;
|
PoolTest *next;
|
||||||
U32 count = 0;
|
U32 count = 0;
|
||||||
@@ -406,6 +421,7 @@ void apool_test_autogrow(void)
|
|||||||
for (PoolTest *p = list; p; p = p->next){
|
for (PoolTest *p = list; p; p = p->next){
|
||||||
printf("Pooltest %u\n",p->n);
|
printf("Pooltest %u\n",p->n);
|
||||||
}
|
}
|
||||||
|
printf("Pooltest total: %u free %u\n", pool->n_elements, pool->n_free);
|
||||||
|
|
||||||
allocator_free_all(&allocator);
|
allocator_free_all(&allocator);
|
||||||
arena_free(&arena);
|
arena_free(&arena);
|
||||||
@@ -414,7 +430,7 @@ void apool_test_autogrow(void)
|
|||||||
|
|
||||||
void string_test_1(void)
|
void string_test_1(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Str str1 = S("Hello");
|
Str str1 = S("Hello");
|
||||||
printf("str1: %.*s len %d\n", str1.len, str1.str, str1.len);
|
printf("str1: %.*s len %d\n", str1.len, str1.str, str1.len);
|
||||||
@@ -431,7 +447,7 @@ void string_test_1(void)
|
|||||||
|
|
||||||
void string_split_test_1(void)
|
void string_split_test_1(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Str str1 = S("|a:bb|ccc|");
|
Str str1 = S("|a:bb|ccc|");
|
||||||
Str sep = S("|:");
|
Str sep = S("|:");
|
||||||
@@ -445,7 +461,7 @@ void string_split_test_1(void)
|
|||||||
}
|
}
|
||||||
void string_test_misc(void)
|
void string_test_misc(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Str str1 = S("Hello World");
|
Str str1 = S("Hello World");
|
||||||
bool prefix1 = str_starts_with(str1, S("He"));
|
bool prefix1 = str_starts_with(str1, S("He"));
|
||||||
@@ -484,7 +500,7 @@ void string_test_misc(void)
|
|||||||
}
|
}
|
||||||
void string_test_join(void)
|
void string_test_join(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
Arena arena;
|
Arena arena;
|
||||||
arena_init(&arena, &ArenaOptions_Default);
|
arena_init(&arena, &ArenaOptions_Default);
|
||||||
Allocator allocator = arena_allocator(&arena);
|
Allocator allocator = arena_allocator(&arena);
|
||||||
@@ -515,7 +531,7 @@ void print_runes(Str str)
|
|||||||
|
|
||||||
void string_test_utf8(void)
|
void string_test_utf8(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Str str1 = S("Test 1ø2 ☺");
|
Str str1 = S("Test 1ø2 ☺");
|
||||||
|
|
||||||
@@ -539,7 +555,7 @@ void string_test_utf8(void)
|
|||||||
|
|
||||||
void string_test_hex(void)
|
void string_test_hex(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
MArena arena;
|
MArena arena;
|
||||||
U8 data[4096];
|
U8 data[4096];
|
||||||
@@ -577,7 +593,7 @@ struct StrSList {
|
|||||||
|
|
||||||
void string_test_slist(void)
|
void string_test_slist(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Str str1 = S("one");
|
Str str1 = S("one");
|
||||||
Str str2 = S("two");
|
Str str2 = S("two");
|
||||||
@@ -625,7 +641,7 @@ struct StrDList {
|
|||||||
|
|
||||||
void string_test_dlist(void)
|
void string_test_dlist(void)
|
||||||
{
|
{
|
||||||
TRACEF("\n");
|
TRACEF("\n\n");
|
||||||
|
|
||||||
Str str1 = S("one");
|
Str str1 = S("one");
|
||||||
Str str2 = S("two");
|
Str str2 = S("two");
|
||||||
|
|||||||
Reference in New Issue
Block a user