Write tests for testing realloc stack

This commit is contained in:
Doyle Thai 2018-02-03 23:11:14 +11:00
parent 9be5194b17
commit 019aad46ca
2 changed files with 143 additions and 2 deletions

4
dqn.h
View File

@ -3144,7 +3144,7 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP
{ {
isize const oldMemSize = *(metadata->PtrToAllocAmount(ptr)); isize const oldMemSize = *(metadata->PtrToAllocAmount(ptr));
u8 const *ptrEnd = ptr + oldMemSize + metadata->GetAllocTailSize(); u8 const *ptrEnd = ptr + oldMemSize + metadata->GetAllocTailSize();
result = (ptrEnd == block->head); result = (ptrEnd == (block->head - 1));
} }
else if (type == PtrType::Tail) else if (type == PtrType::Tail)
{ {
@ -3209,7 +3209,7 @@ FILE_SCOPE u8 *DqnMemAPIInternal_StackAllocatorCallback(DqnMemAPI *api, DqnMemAP
if (enoughSpace) if (enoughSpace)
{ {
stack->PopOnTail(ptr, false); stack->PopOnTail(ptr, false);
result = (u8 *)stack->Push(request->newSize, alignment); result = (u8 *)stack->PushOnTail(request->newSize, alignment);
DqnMem_Copy(result, ptr, oldMemSize); DqnMem_Copy(result, ptr, oldMemSize);
result[oldMemSize] = 0; result[oldMemSize] = 0;

View File

@ -2750,6 +2750,147 @@ FILE_SCOPE void DqnMemStack_Test()
Log(Status::Ok, "Non-Expanding and expanding stack with tail push."); 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) int main(void)