2022-03-18 12:17:28 +00:00
|
|
|
#include "Testing/MemoryTesting.h"
|
|
|
|
|
|
|
|
#include "Memory/Memory.h"
|
|
|
|
#include "Memory/Alignment.h"
|
2022-03-19 08:05:47 +00:00
|
|
|
#include "Memory/MemoryOperator.h"
|
2022-03-18 12:17:28 +00:00
|
|
|
#include "Miscellaneous/AssertionMacros.h"
|
|
|
|
|
|
|
|
NAMESPACE_REDCRAFT_BEGIN
|
|
|
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
|
|
|
NAMESPACE_MODULE_BEGIN(Utility)
|
|
|
|
|
2022-03-19 05:35:27 +00:00
|
|
|
NAMESPACE_BEGIN(Testing)
|
|
|
|
|
2022-03-18 12:17:28 +00:00
|
|
|
void TestMemory()
|
|
|
|
{
|
|
|
|
TestAlignment();
|
|
|
|
TestMemoryBuffer();
|
|
|
|
TestMemoryMalloc();
|
2022-03-19 08:05:47 +00:00
|
|
|
TestMemoryOperator();
|
2022-03-18 12:17:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TestAlignment()
|
|
|
|
{
|
|
|
|
int32 Unaligned = 0xAAAA;
|
|
|
|
|
|
|
|
int32 Aligned8 = Memory::Align(Unaligned, 8);
|
|
|
|
int32 Aligned16 = Memory::Align(Unaligned, 16);
|
|
|
|
int32 Aligned32 = Memory::Align(Unaligned, 32);
|
|
|
|
int32 Aligned64 = Memory::Align(Unaligned, 64);
|
|
|
|
|
|
|
|
int32 AlignedDown8 = Memory::AlignDown(Unaligned, 8);
|
|
|
|
int32 AlignedDown16 = Memory::AlignDown(Unaligned, 16);
|
|
|
|
int32 AlignedDown32 = Memory::AlignDown(Unaligned, 32);
|
|
|
|
int32 AlignedDown64 = Memory::AlignDown(Unaligned, 64);
|
|
|
|
|
|
|
|
int32 AlignedArbitrary8 = Memory::AlignArbitrary(Unaligned, 8);
|
|
|
|
int32 AlignedArbitrary16 = Memory::AlignArbitrary(Unaligned, 16);
|
|
|
|
int32 AlignedArbitrary32 = Memory::AlignArbitrary(Unaligned, 32);
|
|
|
|
int32 AlignedArbitrary64 = Memory::AlignArbitrary(Unaligned, 64);
|
|
|
|
|
|
|
|
always_check((Memory::IsAligned(Aligned8, 8) && Aligned8 > Unaligned));
|
|
|
|
always_check((Memory::IsAligned(Aligned16, 16) && Aligned16 > Unaligned));
|
|
|
|
always_check((Memory::IsAligned(Aligned32, 32) && Aligned32 > Unaligned));
|
|
|
|
always_check((Memory::IsAligned(Aligned64, 64) && Aligned64 > Unaligned));
|
|
|
|
|
|
|
|
always_check((Memory::IsAligned(Aligned8, 8) && AlignedDown8 < Unaligned));
|
|
|
|
always_check((Memory::IsAligned(Aligned16, 16) && AlignedDown16 < Unaligned));
|
|
|
|
always_check((Memory::IsAligned(Aligned32, 32) && AlignedDown32 < Unaligned));
|
|
|
|
always_check((Memory::IsAligned(Aligned64, 64) && AlignedDown64 < Unaligned));
|
|
|
|
|
|
|
|
always_check((Memory::IsAligned(AlignedArbitrary8, 8)));
|
|
|
|
always_check((Memory::IsAligned(AlignedArbitrary16, 16)));
|
|
|
|
always_check((Memory::IsAligned(AlignedArbitrary32, 32)));
|
|
|
|
always_check((Memory::IsAligned(AlignedArbitrary64, 64)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestMemoryBuffer()
|
|
|
|
{
|
|
|
|
int64 TempA;
|
|
|
|
int64 TempB;
|
|
|
|
int64 TempC;
|
|
|
|
int64 TempD;
|
|
|
|
uint8* PtrA = reinterpret_cast<uint8*>(&TempA);
|
|
|
|
uint8* PtrB = reinterpret_cast<uint8*>(&TempB);
|
|
|
|
uint8* PtrC = reinterpret_cast<uint8*>(&TempC);
|
|
|
|
uint8* PtrD = reinterpret_cast<uint8*>(&TempD);
|
|
|
|
|
|
|
|
TempA = 0x0123456789ABCDEF;
|
|
|
|
TempB = 0x0123456789AB0000;
|
|
|
|
Memory::Memmove(PtrA, PtrA + 2, 6);
|
|
|
|
always_check((TempA << 16) == TempB);
|
|
|
|
|
2022-12-15 15:37:41 +00:00
|
|
|
TempA = 0x0123456789ABCDEF;
|
|
|
|
Memory::Memmove(TempB, TempA);
|
|
|
|
always_check(TempB == TempA);
|
|
|
|
|
2022-03-18 12:17:28 +00:00
|
|
|
TempA = 1004;
|
|
|
|
TempB = 1005;
|
|
|
|
TempC = 1005;
|
|
|
|
TempD = 1006;
|
|
|
|
int32 ResultA = Memory::Memcmp(PtrA, PtrB, sizeof(int64));
|
|
|
|
int32 ResultB = Memory::Memcmp(PtrB, PtrC, sizeof(int64));
|
|
|
|
int32 ResultC = Memory::Memcmp(PtrC, PtrD, sizeof(int64));
|
2022-12-15 15:37:41 +00:00
|
|
|
always_check((ResultA < 0) == (ResultC < 0));
|
2022-03-18 12:17:28 +00:00
|
|
|
always_check(ResultB == 0);
|
2022-12-15 15:37:41 +00:00
|
|
|
int32 ResultD = Memory::Memcmp(TempA, TempB);
|
|
|
|
int32 ResultE = Memory::Memcmp(TempB, TempC);
|
|
|
|
int32 ResultF = Memory::Memcmp(TempC, TempD);
|
|
|
|
always_check((ResultD < 0) == (ResultF < 0));
|
|
|
|
always_check(ResultE == 0);
|
2022-03-18 12:17:28 +00:00
|
|
|
|
|
|
|
Memory::Memset(PtrA, 0x3F, sizeof(int64));
|
|
|
|
always_check(TempA == 0x3F3F3F3F3F3F3F3F);
|
|
|
|
Memory::Memset(TempB, 0x3F);
|
|
|
|
always_check(TempB == 0x3F3F3F3F3F3F3F3F);
|
|
|
|
|
|
|
|
Memory::Memzero(PtrA, sizeof(int64));
|
|
|
|
always_check(TempA == 0);
|
|
|
|
Memory::Memzero(TempB);
|
|
|
|
always_check(TempB == 0);
|
|
|
|
|
|
|
|
TempA = 0x0123456789ABCDEF;
|
|
|
|
Memory::Memcpy(PtrC, PtrA, sizeof(int64));
|
|
|
|
always_check(TempA == TempC);
|
|
|
|
TempB = 0xDEDCBA9876543210;
|
|
|
|
Memory::Memcpy(TempD, TempB);
|
|
|
|
always_check(TempB == TempD);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestMemoryMalloc()
|
|
|
|
{
|
|
|
|
int32* PtrA;
|
|
|
|
int64* PtrB;
|
|
|
|
|
|
|
|
PtrA = reinterpret_cast<int32*>(Memory::SystemMalloc(sizeof(int32)));
|
|
|
|
*PtrA = 0x01234567;
|
|
|
|
always_check(*PtrA == 0x01234567);
|
|
|
|
PtrB = reinterpret_cast<int64*>(Memory::SystemRealloc(PtrA, sizeof(int64)));
|
|
|
|
*PtrB = 0x0123456789ABCDEF;
|
|
|
|
always_check(*PtrB == 0x0123456789ABCDEF);
|
|
|
|
Memory::SystemFree(PtrB);
|
|
|
|
|
|
|
|
PtrA = reinterpret_cast<int32*>(Memory::Malloc(sizeof(int32), 1024));
|
|
|
|
always_check(Memory::IsAligned(PtrA, 1024));
|
|
|
|
*PtrA = 0x01234567;
|
|
|
|
always_check(*PtrA == 0x01234567);
|
|
|
|
PtrB = reinterpret_cast<int64*>(Memory::Realloc(PtrA, sizeof(int64), 1024));
|
|
|
|
always_check(Memory::IsAligned(PtrB, 1024));
|
|
|
|
*PtrB = 0x0123456789ABCDEF;
|
|
|
|
always_check(*PtrB == 0x0123456789ABCDEF);
|
|
|
|
Memory::Free(PtrB);
|
|
|
|
|
|
|
|
PtrA = new int32;
|
|
|
|
PtrB = new int64;
|
|
|
|
*PtrA = 0x01234567;
|
|
|
|
always_check(*PtrA == 0x01234567);
|
|
|
|
*PtrB = 0x0123456789ABCDEF;
|
|
|
|
always_check(*PtrB == 0x0123456789ABCDEF);
|
|
|
|
delete PtrA;
|
|
|
|
delete PtrB;
|
|
|
|
|
|
|
|
struct alignas(1024) FTest { int32 A; };
|
|
|
|
FTest* PtrC = new FTest[4];
|
|
|
|
always_check(Memory::IsAligned(PtrC, 1024));
|
|
|
|
PtrC->A = 0x01234567;
|
|
|
|
always_check(PtrC->A == 0x01234567);
|
2023-01-06 10:28:31 +00:00
|
|
|
delete [] PtrC;
|
2022-03-18 12:17:28 +00:00
|
|
|
|
2023-01-11 11:24:02 +00:00
|
|
|
Memory::Free(Memory::Realloc(Memory::Malloc(0), 0));
|
2022-03-18 12:17:28 +00:00
|
|
|
}
|
|
|
|
|
2022-03-19 08:05:47 +00:00
|
|
|
NAMESPACE_UNNAMED_BEGIN
|
|
|
|
|
|
|
|
struct FTracker
|
|
|
|
{
|
|
|
|
static int32 Status;
|
2022-04-30 13:33:18 +00:00
|
|
|
FTracker() { always_check(Status == 0); Status = -1; }
|
|
|
|
FTracker(const FTracker&) { always_check(Status == 1); Status = -1; }
|
|
|
|
FTracker(FTracker&&) { always_check(Status == 2); Status = -1; }
|
|
|
|
~FTracker() { always_check(Status == 3); Status = -1; }
|
2022-03-19 08:05:47 +00:00
|
|
|
FTracker& operator=(const FTracker&) { always_check(Status == 4); Status = -1; return *this; }
|
|
|
|
FTracker& operator=(FTracker&&) { always_check(Status == 5); Status = -1; return *this; }
|
|
|
|
};
|
|
|
|
|
|
|
|
int32 FTracker::Status = -1;
|
|
|
|
|
|
|
|
NAMESPACE_UNNAMED_END
|
|
|
|
|
|
|
|
void TestMemoryOperator()
|
|
|
|
{
|
|
|
|
|
|
|
|
FTracker* PtrA = reinterpret_cast<FTracker*>(Memory::Malloc(sizeof(FTracker)));
|
|
|
|
FTracker* PtrB = reinterpret_cast<FTracker*>(Memory::Malloc(sizeof(FTracker)));
|
|
|
|
|
|
|
|
FTracker::Status = 0;
|
2022-06-05 14:52:55 +00:00
|
|
|
Memory::DefaultConstruct<FTracker>(PtrA);
|
2022-03-19 08:05:47 +00:00
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
|
|
|
FTracker::Status = 1;
|
2022-06-05 14:52:55 +00:00
|
|
|
Memory::Construct<FTracker>(PtrA, PtrB);
|
2022-03-19 08:05:47 +00:00
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
2022-04-30 13:33:18 +00:00
|
|
|
FTracker::Status = 1;
|
|
|
|
Memory::CopyConstruct(PtrA, PtrB);
|
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
2022-03-19 08:05:47 +00:00
|
|
|
FTracker::Status = 2;
|
|
|
|
Memory::MoveConstruct(PtrA, PtrB);
|
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
|
|
|
FTracker::Status = 3;
|
|
|
|
Memory::Destruct(PtrA);
|
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
|
|
|
FTracker::Status = 4;
|
|
|
|
Memory::CopyAssign(PtrA, PtrB);
|
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
|
|
|
FTracker::Status = 5;
|
|
|
|
Memory::MoveAssign(PtrA, PtrB);
|
|
|
|
always_check(FTracker::Status == -1);
|
|
|
|
|
|
|
|
Memory::Free(PtrA);
|
|
|
|
Memory::Free(PtrB);
|
|
|
|
}
|
|
|
|
|
2022-03-19 05:35:27 +00:00
|
|
|
NAMESPACE_END(Testing)
|
|
|
|
|
2022-03-18 12:17:28 +00:00
|
|
|
NAMESPACE_MODULE_END(Utility)
|
|
|
|
NAMESPACE_MODULE_END(Redcraft)
|
|
|
|
NAMESPACE_REDCRAFT_END
|