diff options
author | Omniscient <omniscient.oce@gmail.com> | 2024-05-17 13:50:33 +1000 |
---|---|---|
committer | Omniscient <omniscient.oce@gmail.com> | 2024-05-17 13:50:33 +1000 |
commit | 519329e98467d0cdcc39720cef0f69c9936b6d55 (patch) | |
tree | 2837063ce51984dee00c6e2194e6f58ba189e8d8 /src/std | |
parent | 9df999df385b74be5096218d206dd39988784237 (diff) |
pool tests and try get macro working
Diffstat (limited to 'src/std')
-rw-r--r-- | src/std/mem.c | 67 | ||||
-rw-r--r-- | src/std/mem.h | 24 |
2 files changed, 89 insertions, 2 deletions
diff --git a/src/std/mem.c b/src/std/mem.c index 7d768c9..a5321fb 100644 --- a/src/std/mem.c +++ b/src/std/mem.c @@ -1,8 +1,10 @@ -#include "mem.h" +#include <assert.h> #include <stddef.h> #include <stdint.h> #include <string.h> + #include "log.h" +#include "mem.h" #ifndef DEFAULT_ALIGNMENT #define DEFAULT_ALIGNMENT (2 * sizeof(void*)) @@ -58,3 +60,66 @@ void_pool void_pool_create(arena* a, u64 capacity, u64 entry_size) { return pool; } + +void void_pool_free_all(void_pool* pool) { + // set all entries to be free + for (u64 i = 0; i < pool->capacity; i++) { + void* ptr = &pool->backing_buffer[i * pool->entry_size]; + void_pool_header* free_node = + (void_pool_header*)ptr; // we reuse the actual entry itself to hold the header + if (i == (pool->capacity - 1)) { + // if the last one we make its next pointer NULL indicating its full + free_node->next = NULL; + } + free_node->next = pool->free_list_head; + // now the head points to this entry + pool->free_list_head = free_node; + } +} + +void* void_pool_get(void_pool* pool, u32 raw_handle) { + // An handle is an index into the array essentially + void* ptr = pool->backing_buffer + (raw_handle * pool->entry_size); + return ptr; +} + +void* void_pool_alloc(void_pool* pool, u32* out_raw_handle) { + // get the next free node + if (pool->count == pool->capacity) { + WARN("Pool is full!"); + return NULL; + } + if (pool->free_list_head == NULL) { + ERROR("Pool is full (head = null)"); + return NULL; + } + void_pool_header* free_node = pool->free_list_head; + + // What index does this become? + uintptr_t start = (uintptr_t)pool->backing_buffer; + uintptr_t cur = (uintptr_t)free_node; + TRACE("%ld %ld ", start, cur); + /* assert(cur > start); */ + u32 index = (u32)((cur - start) / pool->entry_size); + printf("Index %d\n", index); + if (out_raw_handle != NULL) { + *out_raw_handle = index; + } + + pool->free_list_head = free_node->next; + + memset(free_node, 0, pool->entry_size); + pool->count++; + return (void*)free_node; +} + +void void_pool_dealloc(void_pool* pool, u32 raw_handle) { + // push free node back onto the free list + void* ptr = void_pool_get(pool, raw_handle); + void_pool_header* freed_node = (void_pool_header*)ptr; + + freed_node->next = pool->free_list_head; + pool->free_list_head = freed_node; + + pool->count--; +} diff --git a/src/std/mem.h b/src/std/mem.h index eef97a0..26da778 100644 --- a/src/std/mem.h +++ b/src/std/mem.h @@ -54,6 +54,28 @@ void_pool void_pool_create(arena* a, u64 capacity, u64 entry_size); void void_pool_free_all(void_pool* pool); bool void_pool_is_empty(void_pool* pool); bool void_pool_is_full(void_pool* pool); -void* void_pool_get(u32 raw_handle); +void* void_pool_get(void_pool* pool, u32 raw_handle); +void* void_pool_alloc(void_pool* pool, u32* out_raw_handle); +void void_pool_dealloc(void_pool* pool, u32 raw_handle); // TODO: macro that lets us specialise + +/* typedef struct Name##_handle Name##_handle; \ */ +#define TYPED_POOL(T, Name) \ + typedef struct Name##_pool { \ + void_pool inner; \ + } Name##_pool; \ + \ + static Name##_pool Name##_pool_create(arena* a, u64 cap, u64 entry_size) { \ + void_pool p = void_pool_create(a, cap, entry_size); \ + return (Name##_pool){ .inner = p }; \ + } \ + static inline T* Name##_pool_get(Name##_pool* pool, Name##_handle handle) { \ + return (T*)void_pool_get(&pool->inner, handle.raw); \ + } \ + static inline T* Name##_pool_alloc(Name##_pool* pool, Name##_handle* out_handle) { \ + return (T*)void_pool_alloc(&pool->inner, &out_handle->raw); \ + } \ + static inline void Name##_pool_dealloc(Name##_pool* pool, Name##_handle handle) { \ + void_pool_dealloc(&pool->inner, handle.raw); \ + }\ |