Add MemBuffer with allocation from stack memory
This commit is contained in:
parent
fbb9c8bf9d
commit
fef763aaff
134
dqn.h
134
dqn.h
@ -567,39 +567,52 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max);
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// PushBuffer Header
|
// PushBuffer Header
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
typedef struct DqnPushBufferBlock
|
typedef struct DqnMemBufferBlock
|
||||||
{
|
{
|
||||||
u8 *memory;
|
u8 *memory;
|
||||||
size_t used;
|
size_t used;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
DqnPushBufferBlock *prevBlock;
|
DqnMemBufferBlock *prevBlock;
|
||||||
} DqnPushBufferBlock;
|
} DqnMemBufferBlock;
|
||||||
|
|
||||||
typedef struct DqnPushBuffer
|
enum DqnMemBufferFlag
|
||||||
{
|
{
|
||||||
DqnPushBufferBlock *block;
|
DqnMemBufferFlag_IsExpandable = (1 << 0),
|
||||||
|
DqnMemBufferFlag_IsFixedMemoryFromUser = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct DqnMemBuffer
|
||||||
|
{
|
||||||
|
DqnMemBufferBlock *block;
|
||||||
|
|
||||||
|
u32 flags;
|
||||||
i32 tempBufferCount;
|
i32 tempBufferCount;
|
||||||
size_t alignment;
|
size_t alignment;
|
||||||
} DqnPushBuffer;
|
} DqnMemBuffer;
|
||||||
|
|
||||||
typedef struct DqnTempBuffer
|
typedef struct DqnTempBuffer
|
||||||
{
|
{
|
||||||
DqnPushBuffer *buffer;
|
DqnMemBuffer *buffer;
|
||||||
DqnPushBufferBlock *startingBlock;
|
DqnMemBufferBlock *startingBlock;
|
||||||
size_t used;
|
size_t used;
|
||||||
|
|
||||||
} DqnTempBuffer;
|
} DqnTempBuffer;
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnPushBuffer_Init (DqnPushBuffer *const buffer, size_t size, const size_t alignment);
|
// NOTE: InitWithFixedMem() is for giving the MemBuffer a pre-allocated block AND the buffer WILL NOT allocate new blocks.
|
||||||
DQN_FILE_SCOPE void *DqnPushBuffer_Allocate (DqnPushBuffer *const buffer, size_t size);
|
// Memory from user given memory is required for MemBufferBlock metadata which is equal to sizeof(DqnMemBufferBlock)
|
||||||
DQN_FILE_SCOPE void DqnPushBuffer_FreeLastBuffer(DqnPushBuffer *const buffer);
|
// InitWithFixedSize() will incur one allocation from the platform and WILL NOT allocate any more blocks after that
|
||||||
DQN_FILE_SCOPE void DqnPushBuffer_Free (DqnPushBuffer *const buffer);
|
DQN_FILE_SCOPE bool DqnMemBuffer_InitWithFixedMem (DqnMemBuffer *const buffer, u8* mem, size_t memSize, const size_t alignment = 4);
|
||||||
DQN_FILE_SCOPE void DqnPushBuffer_ClearCurrBlock(DqnPushBuffer *const buffer, const bool clearToZero);
|
DQN_FILE_SCOPE bool DqnMemBuffer_InitWithFixedSize(DqnMemBuffer *const buffer, size_t size, const size_t alignment = 4);
|
||||||
|
DQN_FILE_SCOPE bool DqnMemBuffer_Init (DqnMemBuffer *const buffer, size_t size, const size_t alignment = 4);
|
||||||
|
|
||||||
DQN_FILE_SCOPE DqnTempBuffer DqnPushBuffer_BeginTempRegion(DqnPushBuffer *const buffer);
|
DQN_FILE_SCOPE void *DqnMemBuffer_Allocate (DqnMemBuffer *const buffer, size_t size);
|
||||||
DQN_FILE_SCOPE void DqnPushBuffer_EndTempRegion(DqnTempBuffer tempBuffer);
|
DQN_FILE_SCOPE void DqnMemBuffer_FreeLastBuffer(DqnMemBuffer *const buffer);
|
||||||
|
DQN_FILE_SCOPE void DqnMemBuffer_Free (DqnMemBuffer *const buffer);
|
||||||
|
DQN_FILE_SCOPE void DqnMemBuffer_ClearCurrBlock(DqnMemBuffer *const buffer, const bool clearToZero);
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE DqnTempBuffer DqnMemBuffer_BeginTempRegion(DqnMemBuffer *const buffer);
|
||||||
|
DQN_FILE_SCOPE void DqnMemBuffer_EndTempRegion (DqnTempBuffer tempBuffer);
|
||||||
|
|
||||||
#endif /* DQN_H */
|
#endif /* DQN_H */
|
||||||
|
|
||||||
@ -2770,7 +2783,7 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DqnPushBuffer Header
|
// DqnMemBuffer Header
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
FILE_SCOPE size_t Dqn_SizeAlignmentInternal(size_t alignment, size_t size)
|
FILE_SCOPE size_t Dqn_SizeAlignmentInternal(size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
@ -2778,13 +2791,13 @@ FILE_SCOPE size_t Dqn_SizeAlignmentInternal(size_t alignment, size_t size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_SCOPE DqnPushBufferBlock *
|
FILE_SCOPE DqnMemBufferBlock *
|
||||||
DqnPushBuffer_AllocBlockInternal(size_t alignment, size_t size)
|
DqnMemBuffer_AllocBlockInternal(size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
size_t alignedSize = Dqn_SizeAlignmentInternal(alignment, size);
|
size_t alignedSize = Dqn_SizeAlignmentInternal(alignment, size);
|
||||||
size_t totalSize = alignedSize + sizeof(DqnPushBufferBlock);
|
size_t totalSize = alignedSize + sizeof(DqnMemBufferBlock);
|
||||||
|
|
||||||
DqnPushBufferBlock *result = (DqnPushBufferBlock *)Dqn_MemAllocInternal(totalSize, true);
|
DqnMemBufferBlock *result = (DqnMemBufferBlock *)Dqn_MemAllocInternal(totalSize, true);
|
||||||
if (!result) return NULL;
|
if (!result) return NULL;
|
||||||
|
|
||||||
result->memory = (u8 *)result + sizeof(*result);
|
result->memory = (u8 *)result + sizeof(*result);
|
||||||
@ -2793,36 +2806,84 @@ DqnPushBuffer_AllocBlockInternal(size_t alignment, size_t size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnPushBuffer_Init(DqnPushBuffer *const buffer,
|
DQN_FILE_SCOPE bool DqnMemBuffer_Init(DqnMemBuffer *const buffer, size_t size,
|
||||||
size_t size, const size_t alignment)
|
const size_t alignment)
|
||||||
{
|
{
|
||||||
if (!buffer || size <= 0) return false;
|
if (!buffer || size <= 0) return false;
|
||||||
DQN_ASSERT(!buffer->block);
|
DQN_ASSERT(!buffer->block);
|
||||||
|
|
||||||
buffer->block = DqnPushBuffer_AllocBlockInternal(alignment, size);
|
buffer->block = DqnMemBuffer_AllocBlockInternal(alignment, size);
|
||||||
if (!buffer->block) return false;
|
if (!buffer->block) return false;
|
||||||
|
|
||||||
buffer->tempBufferCount = 0;
|
buffer->tempBufferCount = 0;
|
||||||
buffer->alignment = alignment;
|
buffer->alignment = alignment;
|
||||||
|
buffer->flags = DqnMemBufferFlag_IsExpandable;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE void *DqnPushBuffer_Allocate(DqnPushBuffer *const buffer, size_t size)
|
DQN_FILE_SCOPE bool DqnMemBuffer_InitWithFixedSize(DqnMemBuffer *const buffer,
|
||||||
|
size_t size,
|
||||||
|
const size_t alignment)
|
||||||
|
{
|
||||||
|
bool result = DqnMemBuffer_Init(buffer, size, alignment);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
buffer->flags = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool DqnMemBuffer_InitWithFixedMem(DqnMemBuffer *const buffer,
|
||||||
|
u8 *mem, size_t memSize,
|
||||||
|
const size_t alignment)
|
||||||
|
{
|
||||||
|
if (!buffer || !mem) return false;
|
||||||
|
DQN_ASSERT(!buffer->block);
|
||||||
|
|
||||||
|
// TODO(doyle): Better logging
|
||||||
|
if (memSize < sizeof(DqnMemBufferBlock))
|
||||||
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
|
|
||||||
|
buffer->block = (DqnMemBufferBlock *)mem;
|
||||||
|
buffer->block->memory = mem + sizeof(DqnMemBufferBlock);
|
||||||
|
buffer->block->used = 0;
|
||||||
|
buffer->block->size = memSize - sizeof(DqnMemBufferBlock);
|
||||||
|
buffer->flags = DqnMemBufferFlag_IsFixedMemoryFromUser;
|
||||||
|
|
||||||
|
const u32 DEFAULT_ALIGNMENT = 4;
|
||||||
|
buffer->tempBufferCount = 0;
|
||||||
|
buffer->alignment = (alignment == 0) ? DEFAULT_ALIGNMENT : alignment;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE void *DqnMemBuffer_Allocate(DqnMemBuffer *const buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (!buffer || size == 0) return NULL;
|
if (!buffer || size == 0) return NULL;
|
||||||
|
|
||||||
size_t alignedSize = Dqn_SizeAlignmentInternal(buffer->alignment, size);
|
size_t alignedSize = Dqn_SizeAlignmentInternal(buffer->alignment, size);
|
||||||
if (!buffer->block ||
|
if (!buffer->block ||
|
||||||
(buffer->block->used + alignedSize) > buffer->block->size)
|
(buffer->block->used + alignedSize) > buffer->block->size)
|
||||||
|
{
|
||||||
|
if (buffer->flags & DqnMemBufferFlag_IsFixedMemoryFromUser) return NULL;
|
||||||
|
|
||||||
|
// TODO: Better notifying to user, out of space in buffer
|
||||||
|
if (buffer->flags & DqnMemBufferFlag_IsExpandable)
|
||||||
{
|
{
|
||||||
size_t newBlockSize = DQN_MAX(alignedSize, buffer->block->size);
|
size_t newBlockSize = DQN_MAX(alignedSize, buffer->block->size);
|
||||||
DqnPushBufferBlock *newBlock = DqnPushBuffer_AllocBlockInternal(
|
DqnMemBufferBlock *newBlock = DqnMemBuffer_AllocBlockInternal(
|
||||||
buffer->alignment, newBlockSize);
|
buffer->alignment, newBlockSize);
|
||||||
if (!newBlock) return NULL;
|
if (!newBlock) return NULL;
|
||||||
|
|
||||||
newBlock->prevBlock = buffer->block;
|
newBlock->prevBlock = buffer->block;
|
||||||
buffer->block = newBlock;
|
buffer->block = newBlock;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u8 *currPointer = buffer->block->memory + buffer->block->used;
|
u8 *currPointer = buffer->block->memory + buffer->block->used;
|
||||||
u8 *alignedResult = (u8 *)Dqn_SizeAlignmentInternal(buffer->alignment, (size_t)currPointer);
|
u8 *alignedResult = (u8 *)Dqn_SizeAlignmentInternal(buffer->alignment, (size_t)currPointer);
|
||||||
@ -2835,9 +2896,11 @@ DQN_FILE_SCOPE void *DqnPushBuffer_Allocate(DqnPushBuffer *const buffer, size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE void
|
DQN_FILE_SCOPE void
|
||||||
DqnPushBuffer_FreeLastBuffer(DqnPushBuffer *const buffer)
|
DqnMemBuffer_FreeLastBuffer(DqnMemBuffer *const buffer)
|
||||||
{
|
{
|
||||||
DqnPushBufferBlock *prevBlock = buffer->block->prevBlock;
|
if (buffer->flags & DqnMemBufferFlag_IsFixedMemoryFromUser) return;
|
||||||
|
|
||||||
|
DqnMemBufferBlock *prevBlock = buffer->block->prevBlock;
|
||||||
Dqn_MemFreeInternal(buffer->block);
|
Dqn_MemFreeInternal(buffer->block);
|
||||||
buffer->block = prevBlock;
|
buffer->block = prevBlock;
|
||||||
|
|
||||||
@ -2845,17 +2908,18 @@ DqnPushBuffer_FreeLastBuffer(DqnPushBuffer *const buffer)
|
|||||||
if (!buffer->block) DQN_ASSERT(buffer->tempBufferCount == 0);
|
if (!buffer->block) DQN_ASSERT(buffer->tempBufferCount == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE void DqnPushBuffer_Free(DqnPushBuffer *buffer)
|
DQN_FILE_SCOPE void DqnMemBuffer_Free(DqnMemBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (!buffer) return;
|
if (!buffer) return;
|
||||||
|
if (buffer->flags & DqnMemBufferFlag_IsFixedMemoryFromUser) return;
|
||||||
|
|
||||||
while (buffer->block)
|
while (buffer->block)
|
||||||
{
|
{
|
||||||
DqnPushBuffer_FreeLastBuffer(buffer);
|
DqnMemBuffer_FreeLastBuffer(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE void
|
DQN_FILE_SCOPE void DqnMemBuffer_ClearCurrBlock(DqnMemBuffer *const buffer,
|
||||||
DqnPushBuffer_ClearCurrBlock(DqnPushBuffer *const buffer,
|
|
||||||
const bool clearToZero)
|
const bool clearToZero)
|
||||||
{
|
{
|
||||||
if (!buffer) return;
|
if (!buffer) return;
|
||||||
@ -2871,7 +2935,7 @@ DqnPushBuffer_ClearCurrBlock(DqnPushBuffer *const buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE DqnTempBuffer
|
DQN_FILE_SCOPE DqnTempBuffer
|
||||||
DqnPushBuffer_BeginTempRegion(DqnPushBuffer *const buffer)
|
DqnMemBuffer_BeginTempRegion(DqnMemBuffer *const buffer)
|
||||||
{
|
{
|
||||||
DqnTempBuffer result = {};
|
DqnTempBuffer result = {};
|
||||||
result.buffer = buffer;
|
result.buffer = buffer;
|
||||||
@ -2882,11 +2946,11 @@ DqnPushBuffer_BeginTempRegion(DqnPushBuffer *const buffer)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE void DqnPushBuffer_EndTempRegion(DqnTempBuffer tempBuffer)
|
DQN_FILE_SCOPE void DqnMemBuffer_EndTempRegion(DqnTempBuffer tempBuffer)
|
||||||
{
|
{
|
||||||
DqnPushBuffer *buffer = tempBuffer.buffer;
|
DqnMemBuffer *buffer = tempBuffer.buffer;
|
||||||
while (buffer->block != tempBuffer.startingBlock)
|
while (buffer->block != tempBuffer.startingBlock)
|
||||||
DqnPushBuffer_FreeLastBuffer(buffer);
|
DqnMemBuffer_FreeLastBuffer(buffer);
|
||||||
|
|
||||||
if (buffer->block)
|
if (buffer->block)
|
||||||
{
|
{
|
||||||
|
@ -893,12 +893,14 @@ void FileTest()
|
|||||||
printf("FileTest(): Completed successfully\n");
|
printf("FileTest(): Completed successfully\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushBufferTest()
|
void MemBufferTest()
|
||||||
|
{
|
||||||
|
// Expandable memory buffer
|
||||||
{
|
{
|
||||||
size_t allocSize = DQN_KILOBYTE(1);
|
size_t allocSize = DQN_KILOBYTE(1);
|
||||||
DqnPushBuffer buffer = {};
|
DqnMemBuffer buffer = {};
|
||||||
const u32 ALIGNMENT = 4;
|
const u32 ALIGNMENT = 4;
|
||||||
DqnPushBuffer_Init(&buffer, allocSize, ALIGNMENT);
|
DqnMemBuffer_Init(&buffer, allocSize, ALIGNMENT);
|
||||||
DQN_ASSERT(buffer.block && buffer.block->memory);
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
DQN_ASSERT(buffer.block->size == allocSize);
|
DQN_ASSERT(buffer.block->size == allocSize);
|
||||||
DQN_ASSERT(buffer.block->used == 0);
|
DQN_ASSERT(buffer.block->used == 0);
|
||||||
@ -906,7 +908,7 @@ void PushBufferTest()
|
|||||||
|
|
||||||
// Alocate A
|
// Alocate A
|
||||||
size_t sizeA = (size_t)(allocSize * 0.5f);
|
size_t sizeA = (size_t)(allocSize * 0.5f);
|
||||||
void *resultA = DqnPushBuffer_Allocate(&buffer, sizeA);
|
void *resultA = DqnMemBuffer_Allocate(&buffer, sizeA);
|
||||||
u64 resultAddrA = *((u64 *)resultA);
|
u64 resultAddrA = *((u64 *)resultA);
|
||||||
DQN_ASSERT(resultAddrA % ALIGNMENT == 0);
|
DQN_ASSERT(resultAddrA % ALIGNMENT == 0);
|
||||||
DQN_ASSERT(buffer.block && buffer.block->memory);
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
@ -919,17 +921,19 @@ void PushBufferTest()
|
|||||||
for (u32 i = 0; i < sizeA; i++)
|
for (u32 i = 0; i < sizeA; i++)
|
||||||
ptrA[i] = 1;
|
ptrA[i] = 1;
|
||||||
|
|
||||||
DqnPushBufferBlock *blockA = buffer.block;
|
DqnMemBufferBlock *blockA = buffer.block;
|
||||||
// Alocate B
|
// Alocate B
|
||||||
size_t sizeB = (size_t)(allocSize * 2.0f);
|
size_t sizeB = (size_t)(allocSize * 2.0f);
|
||||||
void *resultB = DqnPushBuffer_Allocate(&buffer, sizeB);
|
void *resultB = DqnMemBuffer_Allocate(&buffer, sizeB);
|
||||||
u64 resultAddrB = *((u64 *)resultB);
|
u64 resultAddrB = *((u64 *)resultB);
|
||||||
DQN_ASSERT(resultAddrB % ALIGNMENT == 0);
|
DQN_ASSERT(resultAddrB % ALIGNMENT == 0);
|
||||||
DQN_ASSERT(buffer.block && buffer.block->memory);
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
DQN_ASSERT(buffer.block->size == DQN_KILOBYTE(2));
|
DQN_ASSERT(buffer.block->size == DQN_KILOBYTE(2));
|
||||||
|
|
||||||
// Since we alignment the pointers we return they can be within 0-3 bytes of
|
// Since we alignment the pointers we return they can be within 0-3
|
||||||
// what we expect and since this is in a new block as well used will reflect
|
// bytes of
|
||||||
|
// what we expect and since this is in a new block as well used will
|
||||||
|
// reflect
|
||||||
// just this allocation.
|
// just this allocation.
|
||||||
DQN_ASSERT(buffer.block->used >= sizeB + 0 &&
|
DQN_ASSERT(buffer.block->used >= sizeB + 0 &&
|
||||||
buffer.block->used <= sizeB + 3);
|
buffer.block->used <= sizeB + 3);
|
||||||
@ -943,12 +947,12 @@ void PushBufferTest()
|
|||||||
DQN_ASSERT(buffer.block != blockA);
|
DQN_ASSERT(buffer.block != blockA);
|
||||||
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
DQN_ASSERT(blockA->used == sizeA);
|
DQN_ASSERT(blockA->used == sizeA);
|
||||||
DqnPushBufferBlock *blockB = buffer.block;
|
DqnMemBufferBlock *blockB = buffer.block;
|
||||||
|
|
||||||
// Check temp regions work
|
// Check temp regions work
|
||||||
DqnTempBuffer tempBuffer = DqnPushBuffer_BeginTempRegion(&buffer);
|
DqnTempBuffer tempBuffer = DqnMemBuffer_BeginTempRegion(&buffer);
|
||||||
size_t sizeC = 1024 + 1;
|
size_t sizeC = 1024 + 1;
|
||||||
void *resultC = DqnPushBuffer_Allocate(tempBuffer.buffer, sizeC);
|
void *resultC = DqnMemBuffer_Allocate(tempBuffer.buffer, sizeC);
|
||||||
u64 resultAddrC = *((u64 *)resultC);
|
u64 resultAddrC = *((u64 *)resultC);
|
||||||
DQN_ASSERT(resultAddrC % ALIGNMENT == 0);
|
DQN_ASSERT(resultAddrC % ALIGNMENT == 0);
|
||||||
DQN_ASSERT(buffer.block != blockB && buffer.block != blockA);
|
DQN_ASSERT(buffer.block != blockB && buffer.block != blockA);
|
||||||
@ -976,7 +980,7 @@ void PushBufferTest()
|
|||||||
DQN_ASSERT(ptrC[i] == 3);
|
DQN_ASSERT(ptrC[i] == 3);
|
||||||
|
|
||||||
// End temp region which should revert back to 2 linked buffers, A and B
|
// End temp region which should revert back to 2 linked buffers, A and B
|
||||||
DqnPushBuffer_EndTempRegion(tempBuffer);
|
DqnMemBuffer_EndTempRegion(tempBuffer);
|
||||||
DQN_ASSERT(buffer.block && buffer.block->memory);
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
DQN_ASSERT(buffer.block->size == sizeB);
|
DQN_ASSERT(buffer.block->size == sizeB);
|
||||||
DQN_ASSERT(buffer.block->used >= sizeB + 0 &&
|
DQN_ASSERT(buffer.block->used >= sizeB + 0 &&
|
||||||
@ -990,7 +994,7 @@ void PushBufferTest()
|
|||||||
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
|
|
||||||
// Release the last linked buffer from the push buffer
|
// Release the last linked buffer from the push buffer
|
||||||
DqnPushBuffer_FreeLastBuffer(&buffer);
|
DqnMemBuffer_FreeLastBuffer(&buffer);
|
||||||
|
|
||||||
// Which should return back to the 1st allocation
|
// Which should return back to the 1st allocation
|
||||||
DQN_ASSERT(buffer.block == blockA);
|
DQN_ASSERT(buffer.block == blockA);
|
||||||
@ -1000,12 +1004,62 @@ void PushBufferTest()
|
|||||||
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
|
|
||||||
// Free once more to release buffer A memory
|
// Free once more to release buffer A memory
|
||||||
DqnPushBuffer_FreeLastBuffer(&buffer);
|
DqnMemBuffer_FreeLastBuffer(&buffer);
|
||||||
DQN_ASSERT(!buffer.block);
|
DQN_ASSERT(!buffer.block);
|
||||||
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
DQN_ASSERT(buffer.tempBufferCount == 0);
|
DQN_ASSERT(buffer.tempBufferCount == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test buffer with fixed memory does not allocate more
|
||||||
|
{
|
||||||
|
u8 memory[DQN_KILOBYTE(1)] = {};
|
||||||
|
DqnMemBuffer buffer = {};
|
||||||
|
const u32 ALIGNMENT = 4;
|
||||||
|
DqnMemBuffer_InitWithFixedMem(&buffer, memory, DQN_ARRAY_COUNT(memory),
|
||||||
|
ALIGNMENT);
|
||||||
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
|
DQN_ASSERT(buffer.block->size ==
|
||||||
|
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemBufferBlock));
|
||||||
|
DQN_ASSERT(buffer.block->used == 0);
|
||||||
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
|
|
||||||
|
// Allocation larger than stack mem size should fail
|
||||||
|
DQN_ASSERT(!DqnMemBuffer_Allocate(&buffer, DQN_ARRAY_COUNT(memory) * 2));
|
||||||
|
|
||||||
|
// Check free does nothing
|
||||||
|
DqnMemBuffer_Free(&buffer);
|
||||||
|
DqnMemBuffer_FreeLastBuffer(&buffer);
|
||||||
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
|
DQN_ASSERT(buffer.block->size ==
|
||||||
|
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemBufferBlock));
|
||||||
|
DQN_ASSERT(buffer.block->used == 0);
|
||||||
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test buffer with fixed size, allocates once from platform but does not
|
||||||
|
// grow further
|
||||||
|
{
|
||||||
|
size_t allocSize = DQN_KILOBYTE(1);
|
||||||
|
DqnMemBuffer buffer = {};
|
||||||
|
const u32 ALIGNMENT = 4;
|
||||||
|
DqnMemBuffer_InitWithFixedSize(&buffer, allocSize, ALIGNMENT);
|
||||||
|
DQN_ASSERT(buffer.block && buffer.block->memory);
|
||||||
|
DQN_ASSERT(buffer.block->size == allocSize);
|
||||||
|
DQN_ASSERT(buffer.block->used == 0);
|
||||||
|
DQN_ASSERT(buffer.alignment == ALIGNMENT);
|
||||||
|
|
||||||
|
void *result = DqnMemBuffer_Allocate(&buffer, (size_t)(0.5f * allocSize));
|
||||||
|
DQN_ASSERT(result);
|
||||||
|
|
||||||
|
// Allocating more should fail
|
||||||
|
DQN_ASSERT(!DqnMemBuffer_Allocate(&buffer, allocSize));
|
||||||
|
|
||||||
|
// Freeing should work
|
||||||
|
DqnMemBuffer_Free(&buffer);
|
||||||
|
DQN_ASSERT(!buffer.block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
StringsTest();
|
StringsTest();
|
||||||
@ -1015,7 +1069,7 @@ int main(void)
|
|||||||
OtherTest();
|
OtherTest();
|
||||||
ArrayTest();
|
ArrayTest();
|
||||||
FileTest();
|
FileTest();
|
||||||
PushBufferTest();
|
MemBufferTest();
|
||||||
|
|
||||||
printf("\nPress 'Enter' Key to Exit\n");
|
printf("\nPress 'Enter' Key to Exit\n");
|
||||||
getchar();
|
getchar();
|
||||||
|
Loading…
Reference in New Issue
Block a user