ultimatepp/autotest/Mem/Mem.cpp

211 lines
4.8 KiB
C++

#include <Core/Core.h>
using namespace Upp;
// TODO: Large array checks
const int MAX = 1024*1024*16;
template <class T, class FN>
void CheckEq(FN eq)
{
LOG("CheckEq " << sizeof(T));
T a[2000], b[2000];
auto Rnd = [] { return (T)(Random(26) + 'A'); };
for(int i = 0; i < 100000; i++) {
if(i % 10000 == 0)
LOG(i);
for(int j = 0; j < 2000; j++)
a[j] = b[j] = Rnd();
for(int j = 0; j < 1000; j++) {
int pos = Random(1000);
int len = Random(1000);
if(eq(a + pos, b + pos, len) != !memcmp(a + pos, b + pos, sizeof(T) * len)) {
RDUMP(i);
RDUMP(pos);
RDUMP(len);
RDUMP(memcmp(a + pos, b + pos, sizeof(T) * len));
RDUMP(eq(a + pos, b + pos, len));
auto Read = [&](const T *p) {
String s;
for(int i = 0; i < len; i++)
s.Cat((byte)p[i]);
return s;
};
RDUMP(Read(a + pos));
RDUMP(Read(b + pos));
Panic("Failed");
}
b[Random(2000)] = Rnd();
}
}
}
template <class T, class FN>
void CheckCopy(FN copy)
{
LOG("CheckCopy " << sizeof(T));
Buffer<T> b0(MAX), b1(MAX), b2(MAX);
memset(~b0, 0, MAX * sizeof(T));
memset(~b1, 0, MAX * sizeof(T));
memset(~b2, 0, MAX * sizeof(T));
for(int pass = 0; pass < 5; pass++) {
LOG(pass);
for(int i = 0; i < (pass == 4 ? 100 : 500000); i++) {
int pos = Random(200);
int len = Random(decode(pass, 0, 20, 1, 200, 2, 2000, 3, 9999, 200)) + (pass == 4) * 7*1024*1024;
memset(~b0 + pos, i, len * sizeof(T));
pos = Random(200);
len = Random(200);
copy(~b1 + pos, ~b0 + pos, len);
memcpy(~b2 + pos, ~b0 + pos, len * sizeof(T));
if(memcmp(b1, b2, 20000)) {
RDUMP(i);
RDUMP(pos);
RDUMP(len);
Panic("Failed");
}
}
}
}
template <class T, class FN>
void CheckFill(FN fill)
{
LOG("CheckFill " << sizeof(T));
Buffer<T> b1(20000, 0), b2(20000, 0);
for(int pass = 0; pass < 4; pass++) {
LOG(pass);
for(int i = 0; i < 500000; i++) {
int pos = Random(200);
int len = Random(decode(pass, 0, 20, 1, 200, 2, 2000, 9999));
fill(~b1 + pos, (T)i, len);
for(int j = 0; j < len; j++)
b2[pos + j] = i;
if(memcmp(b1, b2, sizeof(T) * 20000)) {
RDUMP(i);
RDUMP(pos);
RDUMP(len);
LOGHEXDUMP(b1 + pos - 4, sizeof(T) * len + 8);
LOGHEXDUMP(b2 + pos - 4, sizeof(T) * len + 8);
Panic("Failed");
}
}
}
LOG("HUGE");
b1.Alloc(1024*1024*16, 0);
b2.Alloc(1024*1024*16, 0);
for(int i = 0; i < 100; i++) {
int pos = Random(200);
int len = 1024*1024*7 + Random(200);
fill(~b1 + pos, (T)i, len);
for(int j = 0; j < len; j++)
b2[pos + j] = i;
if(memcmp(b1, b2, sizeof(T) * 1024*1024*16)) {
RDUMP(i);
RDUMP(pos);
RDUMP(len);
LOGHEXDUMP(b1 + pos - 8, 32 * sizeof(T));
LOGHEXDUMP(b1 + pos + len - 8, 16 * sizeof(T));
DLOG("===============");
LOGHEXDUMP(b2 + pos - 8, 32 * sizeof(T));
LOGHEXDUMP(b2 + pos + len - 8, 16 * sizeof(T));
Panic("Failed");
}
}
}
void CheckMemHash()
{
Buffer<byte> b(2000);
for(int i = 0; i < 2000; i++)
b[i] = (byte)Random(256);
int worst = 0;
for(int pos = 10; pos < 40; pos++) {
for(int len = 0; len < 200; len++) {
auto Hash = [&] { return memhash(~b + pos, len); };
hash_t h = Hash();
for(int i = 0; i < 8; i++) {
b[pos - i - 1]++;
if(h != Hash()) {
RDUMP(pos);
RDUMP(len);
RDUMP(pos - i - 1);
Panic("Failed");
}
b[pos - i - 1]++;
b[pos + len]++;
if(h != Hash()) {
RDUMP(pos);
RDUMP(len);
RDUMP(pos + len);
Panic("Failed");
}
b[pos + len]--;
}
for(int i = 0; i < len; i++) {
int ii = pos + i;
byte bak = b[ii];
bool ok = false;
for(int v = 0; v < 256; v++) {
b[ii] = v;
if(h != Hash()) {
ok = true;
worst = max(worst, v);
break;
}
}
if(!ok) {
RDUMP(pos);
RDUMP(len);
RDUMP(ii);
RDUMP(worst);
RDUMP(ii - pos);
LOGHEXDUMP(~b + pos, len);
b[ii] = bak;
LOGHEXDUMP(~b + pos, len);
Panic("Failed");
}
b[ii] = bak;
}
}
}
LOG("CheckMemHash worst: " << worst);
}
struct m128n : m128 {
m128n(int i) { i64[0] = i, i64[1] = 0; }
m128n() {}
operator byte() const { return (byte)i64[0]; }
};
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
SeedRandom(0);
CheckMemHash();
CheckEq<byte>(memeq8);
CheckEq<word>(memeq16);
CheckEq<dword>(memeq32);
CheckEq<uint64>(memeq64);
CheckEq<m128n>(memeq128);
CheckFill<byte>(memset8);
CheckFill<word>(memset16);
CheckFill<dword>(memset32);
CheckFill<uint64>(memset64);
CheckFill<m128n>(memset128);
CheckCopy<byte>(memcpy8);
CheckCopy<word>(memcpy16);
CheckCopy<dword>(memcpy32);
CheckCopy<qword>(memcpy64);
CheckCopy<m128n>(memcpy128);
LOG("============= OK");
}