diff --git a/VERSION b/VERSION index 3e3c2f1..ccbccc3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.1 +2.2.0 diff --git a/src/base/array/array.c b/src/base/array/array.c index bfb3ae8..5d5304c 100644 --- a/src/base/array/array.c +++ b/src/base/array/array.c @@ -7,14 +7,14 @@ #include "../../common/aliases/aliases.h" #include -#define _array_header(ARRAY) (WpArrayHeader *)(wpMiscUtilsOffsetPointer(ARRAY, (i64)sizeof(WpArrayHeader) * -1)) +#define _arrayHeader(ARRAY) (WpArrayHeader *)(wpMiscUtilsOffsetPointer(ARRAY, (i64)sizeof(WpArrayHeader) * -1)) -wp_persist inline void _array_validate(const WpArray array, u64 item_size); +wp_persist inline void _arrayValidate(const WpArray array, u64 item_size); u64 _arrayCount(WpArray array) { wpDebugAssert(array != NULL, "`array` should not be NULL"); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); wpRuntimeAssert(WP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array"); return header->count; @@ -23,7 +23,7 @@ u64 _arrayCount(WpArray array) { u64 _arrayCapacity(WpArray array) { wpDebugAssert(array != NULL, "`array` should not be NULL"); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); wpRuntimeAssert(WP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array"); return header->capacity; @@ -32,7 +32,7 @@ u64 _arrayCapacity(WpArray array) { u64 _arrayItemSize(WpArray array) { wpDebugAssert(array != NULL, "`array` should not be NULL"); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); wpRuntimeAssert(WP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array"); return header->item_size; @@ -41,7 +41,7 @@ u64 _arrayItemSize(WpArray array) { void _arraySetCount(WpArray array, u64 count) { wpDebugAssert(array != NULL, "`array` should not be NULL"); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); wpRuntimeAssert(WP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array"); header->count = count; @@ -49,9 +49,9 @@ void _arraySetCount(WpArray array, u64 count) { void *_arrayGet(WpArray array, u64 index, u64 item_size) { wpRuntimeAssert(array != NULL, "`array` should not be NULL"); - _array_validate(array, item_size); + _arrayValidate(array, item_size); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); wpRuntimeAssert(index < header->count, "`index` is out of bounds"); return wpMiscUtilsOffsetPointer(array, header->item_size * index); @@ -60,15 +60,15 @@ void *_arrayGet(WpArray array, u64 index, u64 item_size) { void _arraySet(WpArray array, u64 index, void *value, u64 item_size) { void *item = _arrayGet(array, index, item_size); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); memcpy(item, value, header->item_size); } void _arrayAppendCapped(WpArray array, void *value, u64 item_size) { wpRuntimeAssert(array != NULL, "`array` should not be NULL"); - _array_validate(array, item_size); + _arrayValidate(array, item_size); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); if (header->count >= header->capacity) { return; } u64 index = (header->count)++; @@ -77,11 +77,11 @@ void _arrayAppendCapped(WpArray array, void *value, u64 item_size) { void _arrayExtendCappend(WpArray dst, const WpArray src, u64 item_size) { wpRuntimeAssert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); - _array_validate(dst, item_size); - _array_validate(src, item_size); + _arrayValidate(dst, item_size); + _arrayValidate(src, item_size); - WpArrayHeader *src_header = _array_header(src); - WpArrayHeader *dst_header = _array_header(dst); + WpArrayHeader *src_header = _arrayHeader(src); + WpArrayHeader *dst_header = _arrayHeader(dst); u64 remaining_capacity = dst_header->capacity - dst_header->count; u64 copy_count = src_header->count < remaining_capacity ? src_header->count : remaining_capacity; @@ -92,13 +92,13 @@ void _arrayExtendCappend(WpArray dst, const WpArray src, u64 item_size) { void _arrayCopyCapped(WpArray dst, const WpArray src, u64 item_size) { wpRuntimeAssert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); - _array_validate(dst, item_size); - _array_validate(src, item_size); + _arrayValidate(dst, item_size); + _arrayValidate(src, item_size); _arrayClear(dst, item_size); - WpArrayHeader *src_header = _array_header(src); - WpArrayHeader *dst_header = _array_header(dst); + WpArrayHeader *src_header = _arrayHeader(src); + WpArrayHeader *dst_header = _arrayHeader(dst); u64 copy_count = src_header->count < dst_header->capacity ? src_header->count : dst_header->capacity; memcpy((void *)dst, (void *)src, copy_count * src_header->item_size); dst_header->count = copy_count; @@ -107,11 +107,11 @@ void _arrayCopyCapped(WpArray dst, const WpArray src, u64 item_size) { WpArray _arrayAppendAlloc(const WpAllocator *allocator, WpArray array, void *value, WpArrayInitFlags flags, u64 item_size) { wpRuntimeAssert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL"); - _array_validate(array, item_size); + _arrayValidate(array, item_size); WpArray output = array; - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); if (header->count >= header->capacity) { u64 new_capacity = wpMiscUtilsU64RoundUpPow2(header->capacity * 2); output = (WpArray )_arrayAllocCapacity(allocator, new_capacity, flags, @@ -136,13 +136,13 @@ RETURN_ARRAY_APPEND_ALLOC: WpArray _arrayExtendAlloc(const WpAllocator *allocator, WpArray dst, const WpArray src, WpArrayInitFlags flags, u64 item_size) { wpRuntimeAssert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL"); - _array_validate(dst, item_size); - _array_validate(src, item_size); + _arrayValidate(dst, item_size); + _arrayValidate(src, item_size); WpArray output = dst; - WpArrayHeader *src_header = _array_header(src); - WpArrayHeader *dst_header = _array_header(dst); + WpArrayHeader *src_header = _arrayHeader(src); + WpArrayHeader *dst_header = _arrayHeader(dst); u64 remaining_capacity = dst_header->capacity - dst_header->count; if (src_header->count >= remaining_capacity) { u64 new_capacity = wpMiscUtilsU64RoundUpPow2(dst_header->capacity * 2); @@ -168,13 +168,13 @@ RETURN_ARRAY_EXTEND_ALLOC: WpArray _arrayCopyAlloc(const WpAllocator *allocator, WpArray dst, const WpArray src, WpArrayInitFlags flags, u64 item_size) { wpRuntimeAssert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL"); - _array_validate(dst, item_size); - _array_validate(src, item_size); + _arrayValidate(dst, item_size); + _arrayValidate(src, item_size); WpArray output = dst; - WpArrayHeader *src_header = _array_header(src); - WpArrayHeader *dst_header = _array_header(dst); + WpArrayHeader *src_header = _arrayHeader(src); + WpArrayHeader *dst_header = _arrayHeader(dst); if (src_header->count >= dst_header->capacity) { u64 new_capacity = wpMiscUtilsU64RoundUpPow2(dst_header->capacity * 2); output = (WpArray )_arrayAllocCapacity(allocator, new_capacity, @@ -197,9 +197,9 @@ RETURN_ARRAY_COPY_ALLOC: void *_arrayPop(WpArray array, u64 item_size) { wpRuntimeAssert(array != NULL, "`array` should not be NULL"); - _array_validate(array, item_size); + _arrayValidate(array, item_size); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); if (header->count == 0) { return NULL; } u64 index = header->count - 1; @@ -210,9 +210,9 @@ void *_arrayPop(WpArray array, u64 item_size) { void _arrayClear(WpArray array, u64 item_size) { wpRuntimeAssert(array != NULL, "`array` should not be NULL"); - _array_validate(array, item_size); + _arrayValidate(array, item_size); - WpArrayHeader *header = _array_header(array); + WpArrayHeader *header = _arrayHeader(array); header->count = 0; } @@ -259,8 +259,18 @@ WpArray _arrayFromPreallocatedBuffer(void *buffer, u64 buffer_size, WpArrayInitF return output; } -wp_persist inline void _array_validate(const WpArray array, u64 item_size) { - WpArrayHeader *header = _array_header(array); +void _arrayDealloc(const WpAllocator *allocator, WpArray *array, u64 item_size) { + wpRuntimeAssert(allocator != NULL, "`allocator` should not be NULL"); + + u64 capacity = wpArrayCapacity(*array); + u64 allocation_size = _arrayCalcAllocSize(capacity, item_size); + void *header = (void *)_arrayHeader(*array); + wpMemAllocatorFree(allocator, &header, allocation_size); + *array = NULL; +} + +wp_persist inline void _arrayValidate(const WpArray array, u64 item_size) { + WpArrayHeader *header = _arrayHeader(array); wpRuntimeAssert(WP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array"); wpRuntimeAssert(item_size == header->item_size, "Invalid item type provided"); } diff --git a/src/base/array/array.h b/src/base/array/array.h index 746a95d..27760d2 100644 --- a/src/base/array/array.h +++ b/src/base/array/array.h @@ -176,6 +176,10 @@ typedef enum { ((TYPE *)_arrayAllocCapacity(ALLOCATOR_PTR, CAPACITY, FLAGS, sizeof(TYPE))) #define wpArrayFromPreallcatedBuffer(TYPE, BUFFER, BUFFER_SIZE) \ ((TYPE *)_array_from_preallcated_buffer(BUFFER, BUFFER_SIZE, sizeof(TYPE))) +// Only needed for allocators like malloc where each allocation has to be freed on its own. +// No need to use it for allocators like Arena. +#define wpArrayDealloc(TYPE, ALLOCATOR_PTR, ARRAY_DPTR) \ + (_arrayDealloc(ALLOCATOR_PTR, (WpArray *)ARRAY_DPTR, sizeof(TYPE))) typedef struct WpArrayHeader WpArrayHeader; @@ -208,6 +212,7 @@ WpArray _arrayAllocCapacity(const WpAllocator *allocator, u64 capacity, WpArrayI u64 item_size); WpArray _arrayFromPreallocatedBuffer(void *buffer, u64 buffer_size, WpArrayInitFlags flags, u64 item_size); +void _arrayDealloc(const WpAllocator *allocator, WpArray *array, u64 item_size); #ifdef WP_PLATFORM_CPP END_C_LINKAGE diff --git a/src/base/mem/allocator/mem_allocator.c b/src/base/mem/allocator/mem_allocator.c index 56b8f2b..b62c692 100644 --- a/src/base/mem/allocator/mem_allocator.c +++ b/src/base/mem/allocator/mem_allocator.c @@ -6,7 +6,7 @@ #include void *wpMemAllocatorAlloc(const WpAllocator *allocator, u64 size) { - wpDebugAssert(allocator != NULL && (allocator->alloc) != NULL, "`allocator` and `allocator->alloc` should not be NULL"); + wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_ALLOC)) { return NULL; @@ -16,7 +16,7 @@ void *wpMemAllocatorAlloc(const WpAllocator *allocator, u64 size) { } void *wpMemAllocatorAllocAligned(const WpAllocator *allocator, u64 size, u64 alignment) { - wpDebugAssert(allocator != NULL && (allocator->alloc_aligned) != NULL, "`allocator` and `allocator->alloc_aligned` should not be NULL"); + wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_ALLOC_ALIGNED)) { return NULL; @@ -26,7 +26,7 @@ void *wpMemAllocatorAllocAligned(const WpAllocator *allocator, u64 size, u64 ali } void *wpMemAllocatorRealloc(const WpAllocator *allocator, void *ptr, u64 old_size, u64 new_size) { - wpDebugAssert(allocator != NULL && (allocator->realloc) != NULL, "`allocator` and `allocator->realloc` should not be NULL"); + wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_REALLOC)) { return NULL; @@ -37,7 +37,7 @@ void *wpMemAllocatorRealloc(const WpAllocator *allocator, void *ptr, u64 old_siz void *wpMemAllocatorReallocAligned(const WpAllocator *allocator, void *ptr, u64 old_size, u64 new_size, u64 alignment) { - wpDebugAssert(allocator != NULL && (allocator->realloc_aligned) != NULL, "`allocator` and `allocator->realloc_aligned` should not be NULL"); + wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_REALLOC_ALIGNED)) { return NULL; @@ -47,7 +47,7 @@ void *wpMemAllocatorReallocAligned(const WpAllocator *allocator, void *ptr, u64 } void wpMemAllocatorFree(const WpAllocator *allocator, void **ptr, u64 size) { - wpDebugAssert(allocator != NULL && (allocator->free) != NULL, "`allocator` and `allocator->free` should not be NULL"); + wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_FREE)) { return; diff --git a/src/base/queue/queue.h b/src/base/queue/queue.h index f04cf29..b35282e 100644 --- a/src/base/queue/queue.h +++ b/src/base/queue/queue.h @@ -42,7 +42,7 @@ typedef WpQueue WpStr8Queue; #ifdef WP_PLATFORM_CPP #define wpQueue(TYPE, CAPACITY) ([&]() { \ - wp_persist WpArray arr = wpArrayWithCapacity(TYPE, CAPACITY, WP_ARRAY_INIT_FILLED); \ + wp_persist WpArray arr = wpArrayWithCapacity(TYPE, CAPACITY, WP_ARRAY_INIT_FILLED); \ wp_persist WpQueue queue = { \ arr, \ 0, \ @@ -54,7 +54,7 @@ typedef WpQueue WpStr8Queue; }()) #define wpQueueAlloc(TYPE, ALLOCATOR_PTR, CAPACITY) ([&]() { \ wp_persist WpQueue queue = { \ - wpArrayAllocCapacity(TYPE, ALLOCATOR_PTR, CAPACITY, WP_ARRAY_INIT_FILLED), \ + wpArrayAllocCapacity(TYPE, ALLOCATOR_PTR, CAPACITY, WP_ARRAY_INIT_FILLED), \ 0, \ 0, \ 0, \ @@ -64,13 +64,13 @@ typedef WpQueue WpStr8Queue; }()) #else #define wpQueue(TYPE, CAPACITY) ((WpQueue){ \ - .items = wpArrayWithCapacity(TYPE, CAPACITY, WP_ARRAY_INIT_FILLED), \ + .items = wpArrayWithCapacity(TYPE, CAPACITY, WP_ARRAY_INIT_FILLED), \ .front = 0, \ .back = 0, \ .count = 0, \ }) #define wpQueueAlloc(TYPE, ALLOCATOR_PTR, CAPACITY) ((WpQueue){ \ - .items = wpArrayAllocCapacity(TYPE, ALLOCATOR_PTR, CAPACITY, WP_ARRAY_INIT_FILLED), \ + .items = wpArrayAllocCapacity(TYPE, ALLOCATOR_PTR, CAPACITY, WP_ARRAY_INIT_FILLED), \ .front = 0, \ .back = 0, \ .count = 0, \ @@ -88,6 +88,11 @@ typedef WpQueue WpStr8Queue; #define wpQueuePop(TYPE, QUEUE_PTR) ( \ (TYPE *)_queuePop(QUEUE_PTR, sizeof(TYPE)) \ ) +#define wpQueueDealloc(TYPE, ALLOCATOR_PTR, QUEUE_PTR) \ + (wpArrayDealloc(TYPE, ALLOCATOR_PTR, &((QUEUE_PTR)->items)), \ + (QUEUE_PTR)->front = 0, \ + (QUEUE_PTR)->back = 0, \ + (QUEUE_PTR)->count = 0) void _queuePush(WpQueue *queue, void *item, u64 item_size); WpQueue *_queuePushAlloc(const WpAllocator *allocator, WpQueue *queue, void *item, u64 item_size);