mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[project] Lose the battle between tabs & spaces
I'm a tabs guy. I like tabs, it's an elegant way to represent indentation instead of brute-forcing it. But I have to admit that the world seems to be going towards spaces, and tooling tends not to play nice with tabs. So here we go, changing the whole repo to spaces since I'm getting tired of all the inconsistent formatting.
This commit is contained in:
committed by
Justin C. Miller
parent
d36b2d8057
commit
8f529046a9
@@ -26,169 +26,169 @@ extern bool ASSERT_EXPECTED;
|
||||
extern bool ASSERT_HAPPENED;
|
||||
|
||||
std::vector<size_t> sizes = {
|
||||
16000, 8000, 4000, 4000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 150,
|
||||
150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 48, 48, 48, 13 };
|
||||
16000, 8000, 4000, 4000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 150,
|
||||
150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 48, 48, 48, 13 };
|
||||
|
||||
void segfault_handler(int signum, siginfo_t *info, void *ctxp)
|
||||
{
|
||||
uintptr_t start = reinterpret_cast<uintptr_t>(mem_base);
|
||||
uintptr_t end = start + mem_size;
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(info->si_addr);
|
||||
uintptr_t start = reinterpret_cast<uintptr_t>(mem_base);
|
||||
uintptr_t end = start + mem_size;
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(info->si_addr);
|
||||
|
||||
if (addr < start || addr >= end) {
|
||||
CAPTURE( start );
|
||||
CAPTURE( end );
|
||||
CAPTURE( addr );
|
||||
FAIL("Segfaulted outside memory area");
|
||||
}
|
||||
if (addr < start || addr >= end) {
|
||||
CAPTURE( start );
|
||||
CAPTURE( end );
|
||||
CAPTURE( addr );
|
||||
FAIL("Segfaulted outside memory area");
|
||||
}
|
||||
|
||||
signalled_at = info->si_addr;
|
||||
signalled += 1;
|
||||
if (mprotect(signalled_at, max_block, PROT_READ|PROT_WRITE)) {
|
||||
perror("mprotect");
|
||||
exit(100);
|
||||
}
|
||||
signalled_at = info->si_addr;
|
||||
signalled += 1;
|
||||
if (mprotect(signalled_at, max_block, PROT_READ|PROT_WRITE)) {
|
||||
perror("mprotect");
|
||||
exit(100);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "Buddy blocks tests", "[memory buddy]" )
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
unsigned seed = clock::now().time_since_epoch().count();
|
||||
std::default_random_engine rng(seed);
|
||||
using clock = std::chrono::system_clock;
|
||||
unsigned seed = clock::now().time_since_epoch().count();
|
||||
std::default_random_engine rng(seed);
|
||||
|
||||
mem_base = aligned_alloc(max_block, mem_size);
|
||||
mem_base = aligned_alloc(max_block, mem_size);
|
||||
|
||||
// Catch segfaults so we can track memory access
|
||||
struct sigaction sigact;
|
||||
memset(&sigact, 0, sizeof(sigact));
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_NODEFER|SA_SIGINFO;
|
||||
sigact.sa_sigaction = segfault_handler;
|
||||
sigaction(SIGSEGV, &sigact, nullptr);
|
||||
// Catch segfaults so we can track memory access
|
||||
struct sigaction sigact;
|
||||
memset(&sigact, 0, sizeof(sigact));
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_NODEFER|SA_SIGINFO;
|
||||
sigact.sa_sigaction = segfault_handler;
|
||||
sigaction(SIGSEGV, &sigact, nullptr);
|
||||
|
||||
// Protect our memory arena so we trigger out fault handler
|
||||
REQUIRE( mprotect(mem_base, max_block*4, PROT_NONE) == 0 );
|
||||
// Protect our memory arena so we trigger out fault handler
|
||||
REQUIRE( mprotect(mem_base, max_block*4, PROT_NONE) == 0 );
|
||||
|
||||
heap_allocator mm(
|
||||
reinterpret_cast<uintptr_t>(mem_base),
|
||||
max_block * 4);
|
||||
heap_allocator mm(
|
||||
reinterpret_cast<uintptr_t>(mem_base),
|
||||
max_block * 4);
|
||||
|
||||
// Initial creation should not have allocated
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
// Initial creation should not have allocated
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
// Allocating too much should assert
|
||||
ASSERT_EXPECTED = true;
|
||||
void *p = mm.allocate(max_block - hs + 1);
|
||||
REQUIRE( ASSERT_HAPPENED );
|
||||
ASSERT_HAPPENED = false;
|
||||
// Allocating too much should assert
|
||||
ASSERT_EXPECTED = true;
|
||||
void *p = mm.allocate(max_block - hs + 1);
|
||||
REQUIRE( ASSERT_HAPPENED );
|
||||
ASSERT_HAPPENED = false;
|
||||
|
||||
// Allocating should signal just at the first page.
|
||||
p = mm.allocate(max_block - hs);
|
||||
CHECK( p == offset_pointer(mem_base, hs) );
|
||||
CHECK( signalled == 1 );
|
||||
CHECK( signalled_at == mem_base );
|
||||
signalled = 0;
|
||||
// Allocating should signal just at the first page.
|
||||
p = mm.allocate(max_block - hs);
|
||||
CHECK( p == offset_pointer(mem_base, hs) );
|
||||
CHECK( signalled == 1 );
|
||||
CHECK( signalled_at == mem_base );
|
||||
signalled = 0;
|
||||
|
||||
// Freeing and allocating should not allocate
|
||||
mm.free(p);
|
||||
p = mm.allocate(max_block - hs);
|
||||
CHECK( p == offset_pointer(mem_base, hs) );
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
// Freeing and allocating should not allocate
|
||||
mm.free(p);
|
||||
p = mm.allocate(max_block - hs);
|
||||
CHECK( p == offset_pointer(mem_base, hs) );
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
mm.free(p);
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
mm.free(p);
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
// Blocks should be:
|
||||
// 22: 0-4M
|
||||
// Blocks should be:
|
||||
// 22: 0-4M
|
||||
|
||||
std::vector<void *> allocs(6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
allocs[i] = mm.allocate(150); // size 8
|
||||
std::vector<void *> allocs(6);
|
||||
for (int i = 0; i < 6; ++i)
|
||||
allocs[i] = mm.allocate(150); // size 8
|
||||
|
||||
// Should not have grown
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
// Should not have grown
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
// Blocks should be:
|
||||
// 22: [0-4M]
|
||||
// 21: [0-2M], 2-4M
|
||||
// 20: [0-1M], 1-2M
|
||||
// 19: [0-512K], 512K-1M
|
||||
// 18: [0-256K], 256-512K
|
||||
// 17: [0-128K], 128-256K
|
||||
// 16: [0-64K], 64-128K
|
||||
// 15: [0-32K], 32K-64K
|
||||
// 14: [0-16K], 16K-32K
|
||||
// 13: [0-8K], 8K-16K
|
||||
// 12: [0-4K], 4K-8K
|
||||
// 11: [0-2K], 2K-4K
|
||||
// 10: [0-1K, 1-2K]
|
||||
// 9: [0, 512, 1024], 1536
|
||||
// 8: [0, 256, 512, 768, 1024, 1280]
|
||||
// Blocks should be:
|
||||
// 22: [0-4M]
|
||||
// 21: [0-2M], 2-4M
|
||||
// 20: [0-1M], 1-2M
|
||||
// 19: [0-512K], 512K-1M
|
||||
// 18: [0-256K], 256-512K
|
||||
// 17: [0-128K], 128-256K
|
||||
// 16: [0-64K], 64-128K
|
||||
// 15: [0-32K], 32K-64K
|
||||
// 14: [0-16K], 16K-32K
|
||||
// 13: [0-8K], 8K-16K
|
||||
// 12: [0-4K], 4K-8K
|
||||
// 11: [0-2K], 2K-4K
|
||||
// 10: [0-1K, 1-2K]
|
||||
// 9: [0, 512, 1024], 1536
|
||||
// 8: [0, 256, 512, 768, 1024, 1280]
|
||||
|
||||
// We have free memory at 1526 and 2K, but we should get 4K
|
||||
void *big = mm.allocate(4000); // size 12
|
||||
// We have free memory at 1526 and 2K, but we should get 4K
|
||||
void *big = mm.allocate(4000); // size 12
|
||||
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
REQUIRE( big == offset_pointer(mem_base, 4096 + hs) );
|
||||
mm.free(big);
|
||||
REQUIRE( big == offset_pointer(mem_base, 4096 + hs) );
|
||||
mm.free(big);
|
||||
|
||||
// free up 512
|
||||
mm.free(allocs[3]);
|
||||
mm.free(allocs[4]);
|
||||
// free up 512
|
||||
mm.free(allocs[3]);
|
||||
mm.free(allocs[4]);
|
||||
|
||||
// Blocks should be:
|
||||
// ...
|
||||
// 9: [0, 512, 1024], 1536
|
||||
// 8: [0, 256, 512], 768, 1024, [1280]
|
||||
// Blocks should be:
|
||||
// ...
|
||||
// 9: [0, 512, 1024], 1536
|
||||
// 8: [0, 256, 512], 768, 1024, [1280]
|
||||
|
||||
// A request for a 512-block should not cross the buddy divide
|
||||
big = mm.allocate(500); // size 9
|
||||
REQUIRE( big >= offset_pointer(mem_base, 1536 + hs) );
|
||||
mm.free(big);
|
||||
// A request for a 512-block should not cross the buddy divide
|
||||
big = mm.allocate(500); // size 9
|
||||
REQUIRE( big >= offset_pointer(mem_base, 1536 + hs) );
|
||||
mm.free(big);
|
||||
|
||||
mm.free(allocs[0]);
|
||||
mm.free(allocs[1]);
|
||||
mm.free(allocs[2]);
|
||||
mm.free(allocs[5]);
|
||||
allocs.clear();
|
||||
mm.free(allocs[0]);
|
||||
mm.free(allocs[1]);
|
||||
mm.free(allocs[2]);
|
||||
mm.free(allocs[5]);
|
||||
allocs.clear();
|
||||
|
||||
std::shuffle(sizes.begin(), sizes.end(), rng);
|
||||
std::shuffle(sizes.begin(), sizes.end(), rng);
|
||||
|
||||
allocs.reserve(sizes.size());
|
||||
for (size_t size : sizes)
|
||||
allocs.push_back(mm.allocate(size));
|
||||
allocs.reserve(sizes.size());
|
||||
for (size_t size : sizes)
|
||||
allocs.push_back(mm.allocate(size));
|
||||
|
||||
std::shuffle(allocs.begin(), allocs.end(), rng);
|
||||
for (void *p: allocs)
|
||||
mm.free(p);
|
||||
allocs.clear();
|
||||
std::shuffle(allocs.begin(), allocs.end(), rng);
|
||||
for (void *p: allocs)
|
||||
mm.free(p);
|
||||
allocs.clear();
|
||||
|
||||
big = mm.allocate(max_block / 2 + 1);
|
||||
big = mm.allocate(max_block / 2 + 1);
|
||||
|
||||
// If everything was freed / joined correctly, that should not have allocated
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
// If everything was freed / joined correctly, that should not have allocated
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
// And we should have gotten back the start of memory
|
||||
CHECK( big == offset_pointer(mem_base, hs) );
|
||||
// And we should have gotten back the start of memory
|
||||
CHECK( big == offset_pointer(mem_base, hs) );
|
||||
|
||||
// Allocating again should signal at the next page.
|
||||
void *p2 = mm.allocate(max_block - hs);
|
||||
CHECK( p2 == offset_pointer(mem_base, max_block + hs) );
|
||||
CHECK( signalled == 1 );
|
||||
CHECK( signalled_at == offset_pointer(mem_base, max_block) );
|
||||
signalled = 0;
|
||||
// Allocating again should signal at the next page.
|
||||
void *p2 = mm.allocate(max_block - hs);
|
||||
CHECK( p2 == offset_pointer(mem_base, max_block + hs) );
|
||||
CHECK( signalled == 1 );
|
||||
CHECK( signalled_at == offset_pointer(mem_base, max_block) );
|
||||
signalled = 0;
|
||||
|
||||
mm.free(p2);
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
mm.free(p2);
|
||||
CHECK( signalled == 0 );
|
||||
signalled = 0;
|
||||
|
||||
free(mem_base);
|
||||
free(mem_base);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user