Skip to content

Commit 50c5f36

Browse files
committed
Added randomised allocation/deallocation test
1 parent 53c9e8b commit 50c5f36

File tree

1 file changed

+68
-10
lines changed

1 file changed

+68
-10
lines changed

tests/src/resources/test_ResourceSystem.cpp

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <resources/StaticMeshData.h>
1717
#include <resources/Texture2DData.h>
1818
#include <utest.h>
19+
#include <random>
1920

2021
using namespace Siege;
2122

@@ -683,7 +684,9 @@ class Allocator
683684

684685
if (freeListIdx == INVALID_INDEX) return nullptr;
685686

686-
BlockHeader* header = GetHeader(block);
687+
BlockHeader* header = reinterpret_cast<BlockHeader*>(reinterpret_cast<unsigned char*>(block) - sizeof(BlockHeader));
688+
689+
687690

688691
TrySplitBlock(header, block, requiredSize, fl, sl, freeListIdx);
689692

@@ -694,7 +697,7 @@ class Allocator
694697

695698
newHeader->sizeAndFlags = (requiredSize << FLAG_BITS) | flags;
696699

697-
unsigned char* ptr = TO_BYTES(TO_BYTES(header)+sizeof(BlockHeader));
700+
unsigned char* ptr = TO_BYTES(header)+sizeof(BlockHeader);
698701

699702
BlockFooter* footer = TO_FBLOCK((ptr+size));
700703
footer->totalBlockSize = requiredSize;
@@ -732,8 +735,10 @@ class Allocator
732735

733736
size_t GetNextFreeSlotIndex(OUT size_t& fl,OUT size_t& sl)
734737
{
735-
sl = FindLargerSlots(slBitmasks[fl], sl);
736-
if (sl) return fl * MAX_SL_INDEX + __builtin_ctz(sl);
738+
sl = __builtin_ctz(FindLargerSlots(slBitmasks[fl], sl));
739+
740+
if (sl == 32) sl = 0;
741+
if (sl) return fl * MAX_SL_INDEX + sl;
737742

738743
fl = FindLargerSlots64(flBitmask, fl);
739744

@@ -813,18 +818,19 @@ class Allocator
813818
{
814819
size_t blockSize = GetHeaderSize(header);
815820
RemoveFromFreeList(block, fl, sl, index);
816-
if (blockSize <= size) return;
821+
if (blockSize <= size || ((blockSize - size) < (sizeof(BlockHeader) + sizeof(BlockFooter)))) return;
817822

818823
CreateNewBlock(TO_BYTES(header) + size, blockSize - size);
819824
}
820825

821826
void RemoveFromFreeList(FreeBlockNode* block, size_t fl, size_t sl, size_t index)
822827
{
823828
if (!block) return;
824-
if (block->prev) block->prev->next = block->next;
825-
if (block->next) block->next->prev = block->prev;
826829

827-
freeList[index] = block->next;
830+
if (!block->prev) freeList[index] = block->next;
831+
else block->prev->next = block->next;
832+
833+
if (block->next) block->next->prev = block->prev;
828834

829835
slBitmasks[fl] = Mask(slBitmasks[fl],FlipBits(BitMask(sl)));
830836
if (!slBitmasks[fl]) flBitmask = Mask(flBitmask,FlipBits(BitMask(fl)));
@@ -857,15 +863,17 @@ class Allocator
857863
BlockHeader* header = TO_HBLOCK(ptr);
858864
header->sizeAndFlags = (sizeFlag | IS_FREE_FLAG);
859865

860-
FreeBlockNode* block = TO_FREEBLOCK((TO_BYTES(header) + sizeof(BlockHeader)));
866+
FreeBlockNode* block = reinterpret_cast<FreeBlockNode*>(reinterpret_cast<unsigned char*>(header) + sizeof(BlockHeader));
867+
868+
// FreeBlockNode* block = TO_FREEBLOCK((TO_BYTES(header) + sizeof(BlockHeader)));
861869

862870
BlockFooter* firstFooter = TO_FBLOCK((TO_BYTES(header)+(size-sizeof(BlockFooter))));
863871
firstFooter->totalBlockSize = size;
864872

865873
block->next = freeList[index];
866874
block->prev = nullptr;
867875

868-
if (block->next) block->next->prev = block;
876+
if (IsValid(block->next)) block->next->prev = block;
869877

870878
freeList[index] = block;
871879

@@ -892,6 +900,7 @@ class Allocator
892900

893901
bool IsHead(void* ptr) { return TO_BYTES(ptr) == data ;}
894902
bool IsTail(void* ptr) { return TO_BYTES(ptr) + sizeof(BlockHeader) >= (data + capacity); }
903+
bool IsValid(FreeBlockNode* ptr) { return ptr != nullptr; }
895904
size_t& Capacity() { return capacity;}
896905
unsigned char* Data() { return data; };
897906
size_t SlIndex(size_t size, size_t fl) { return (size >> (fl - SL_BITS)) & SL_MASK; }
@@ -1260,3 +1269,52 @@ UTEST(test_ResourceSystem, TestAllocationWhenNoAppropriateFragmentExists)
12601269
void* tooLargeVal = a.Allocate(24);
12611270
ASSERT_FALSE(tooLargeVal);
12621271
}
1272+
1273+
UTEST(test_ResourceSystem, TestRandomAllocationsAndDeallocations)
1274+
{
1275+
Allocator a(1024 * 1024);
1276+
1277+
unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count();
1278+
//std::default_random_engine generator(seed);
1279+
std::default_random_engine generator(12345);
1280+
1281+
std::uniform_int_distribution<int> actionDist(0, 10);
1282+
std::uniform_int_distribution<int> sizeDist(1, 256);
1283+
1284+
std::vector<void*> pointers;
1285+
1286+
for(int i = 0; i < 10000; i++)
1287+
{
1288+
int action = actionDist(generator);
1289+
1290+
if (action < 8)
1291+
{
1292+
size_t randomSize = sizeDist(generator);
1293+
void* ptr = a.Allocate(randomSize);
1294+
if (ptr)
1295+
{
1296+
*((uint32_t*)ptr) = 0xDEADC0DE;
1297+
pointers.push_back(ptr);
1298+
}
1299+
}
1300+
else if (action <= 10 && !pointers.empty())
1301+
{
1302+
std::uniform_int_distribution<int> indices(0, pointers.size()-1);
1303+
size_t index = indices(generator);
1304+
1305+
void* ptrToFree = pointers[index];
1306+
ASSERT_EQ(*(uint32_t*)ptrToFree, 0xDEADC0DE);
1307+
1308+
a.Deallocate(ptrToFree);
1309+
ASSERT_FALSE(ptrToFree);
1310+
pointers.erase(pointers.begin() + index);
1311+
}
1312+
}
1313+
1314+
for (void* ptr : pointers)
1315+
{
1316+
a.Deallocate(ptr);
1317+
}
1318+
1319+
ASSERT_EQ(a.Capacity(), a.BytesRemaining());
1320+
}

0 commit comments

Comments
 (0)