From 019aad46ca778440736f06e72aff5362ae06b37e Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Sat, 3 Feb 2018 23:11:14 +1100 Subject: [PATCH] Write tests for testing realloc stack --- dqn.h | 4 +- dqn_unit_test.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 2 deletions(-) diff --git a/dqn.h b/dqn.h index dba7e00..7ec71e9 100644 --- a/dqn.h +++ b/dqn.h @@ -3144,7 +3144,7 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP { isize const oldMemSize = *(metadata->PtrToAllocAmount(ptr)); u8 const *ptrEnd = ptr + oldMemSize + metadata->GetAllocTailSize(); - result = (ptrEnd == block->head); + result = (ptrEnd == (block->head - 1)); } else if (type == PtrType::Tail) { @@ -3209,7 +3209,7 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP if (enoughSpace) { stack->PopOnTail(ptr, false); - result = (u8 *)stack->Push(request->newSize, alignment); + result = (u8 *)stack->PushOnTail(request->newSize, alignment); DqnMem_Copy(result, ptr, oldMemSize); result[oldMemSize] = 0; diff --git a/dqn_unit_test.cpp b/dqn_unit_test.cpp index 4eb9960..960f4e8 100644 --- a/dqn_unit_test.cpp +++ b/dqn_unit_test.cpp @@ -2750,6 +2750,147 @@ FILE_SCOPE void DqnMemStack_Test() Log(Status::Ok, "Non-Expanding and expanding stack with tail push."); } } + + // Check stack allocator mem api callbacks + if (1) + { + // Realloc in same block and allow it to grow in place. + if (1) + { + // Using push on head + if (1) + { + DqnMemStack stack = {}; + DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); + auto *api = &stack.myAPI; + + auto *blockBefore = stack.block; + auto *headBefore = stack.block->head; + + isize bufSize = 16; + char *buf = (char *)stack.Push(bufSize); + DqnMem_Set(buf, 'X', bufSize); + for (auto i = 0; i < bufSize; i++) DQN_ASSERT(buf[i] == 'X'); + + isize oldBufSize = bufSize; + bufSize = 32; + buf = (char *)api->Realloc(buf, oldBufSize, bufSize); + for (auto i = 0; i < oldBufSize; i++) DQN_ASSERT(buf[i] == 'X'); + DqnMem_Set(buf, '@', bufSize); + + DQN_ASSERT(blockBefore == stack.block); + DQN_ASSERT(headBefore < stack.block->head); + stack.Pop(buf); + + DQN_ASSERT(blockBefore == stack.block); + DQN_ASSERT(headBefore == stack.block->head); + DQN_ASSERT(headBefore == stack.block->memory); + stack.Free(); + } + + // Using push on tail + if (1) + { + DqnMemStack stack = {}; + DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); + auto *api = &stack.myAPI; + + auto *blockBefore = stack.block; + auto *tailBefore = stack.block->tail; + + isize bufSize = 16; + char *buf = (char *)stack.PushOnTail(bufSize); + DqnMem_Set(buf, 'X', bufSize); + for (auto i = 0; i < bufSize; i++) DQN_ASSERT(buf[i] == 'X'); + + isize oldBufSize = bufSize; + bufSize = 32; + buf = (char *)api->Realloc(buf, oldBufSize, bufSize); + for (auto i = 0; i < oldBufSize; i++) DQN_ASSERT(buf[i] == 'X'); + DqnMem_Set(buf, '@', bufSize); + + DQN_ASSERT(blockBefore == stack.block); + DQN_ASSERT(tailBefore > stack.block->tail); + stack.PopOnTail(buf, bufSize); + + DQN_ASSERT(blockBefore == stack.block); + DQN_ASSERT(tailBefore == stack.block->tail); + DQN_ASSERT(stack.block->head == stack.block->memory); + stack.Free(); + } + Log(Status::Ok, "Allocator MemAPI callback, realloc grow in place"); + } + + // Realloc in same block and insufficient size and expand + if (1) + { + // Using push on head + if (1) + { + DqnMemStack stack = {}; + DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); + auto *api = &stack.myAPI; + + auto *blockBefore = stack.block; + auto *headBefore = stack.block->head; + + isize bufSize = 16; + char *buf = (char *)stack.Push(bufSize); + DqnMem_Set(buf, 'X', bufSize); + for (auto i = 0; i < bufSize; i++) DQN_ASSERT(buf[i] == 'X'); + + isize oldBufSize = bufSize; + bufSize = DQN_MEGABYTE(2); + buf = (char *)api->Realloc(buf, oldBufSize, bufSize); + for (auto i = 0; i < oldBufSize; i++) DQN_ASSERT(buf[i] == 'X'); + DqnMem_Set(buf, '@', bufSize); + + DQN_ASSERT(blockBefore == stack.block->prevBlock); + stack.Pop(buf, bufSize); + + DQN_ASSERT(blockBefore == stack.block); + DQN_ASSERT(headBefore == stack.block->head); + DQN_ASSERT(headBefore == stack.block->memory); + stack.Free(); + } + + // Using push on tail + if (1) + { + DqnMemStack stack = {}; + DQN_ASSERT(stack.Init(DQN_MEGABYTE(1), true, DqnMemStack::Flag::BoundsGuard)); + auto *api = &stack.myAPI; + + auto *blockBefore = stack.block; + auto *tailBefore = stack.block->tail; + + isize bufSize = 16; + char *buf = (char *)stack.PushOnTail(bufSize); + DqnMem_Set(buf, 'X', bufSize); + for (auto i = 0; i < bufSize; i++) DQN_ASSERT(buf[i] == 'X'); + + isize oldBufSize = bufSize; + bufSize = DQN_MEGABYTE(2); + buf = (char *)api->Realloc(buf, oldBufSize, bufSize); + for (auto i = 0; i < oldBufSize; i++) + DQN_ASSERT(buf[i] == 'X'); + DqnMem_Set(buf, '@', bufSize); + + DQN_ASSERT(blockBefore != stack.block); + DQN_ASSERT(blockBefore == stack.block->prevBlock); + stack.PopOnTail(buf); + + DQN_ASSERT(blockBefore == stack.block); + DQN_ASSERT(tailBefore == stack.block->tail); + + DQN_ASSERT(stack.block->head == stack.block->memory); + stack.Free(); + } + Log(Status::Ok, "Allocator MemAPI callback, realloc insufficient size so expand"); + } + + // TODO(doyle): Realloc to smaller size logic + } } int main(void)