class ArenaAllocatorTest : public ::testing::Test { protected:
size_t NumberOfArenas(ArenaAllocator* allocator) {
size_t result = 0u; for (Arena* a = allocator->arena_head_; a != nullptr; a = a->next_) {
++result;
} return result;
}
};
TEST_F(ArenaAllocatorTest, MakeDefined) { // Regression test to make sure we mark the allocated area defined.
CallocArenaPool pool; static constexpr size_t kSmallArraySize = 10; static constexpr size_t kLargeArraySize = 50;
uint32_t* small_array;
{ // Allocate a small array from an arena and release it.
ArenaAllocator allocator(&pool);
small_array = allocator.AllocArray<uint32_t>(kSmallArraySize);
ASSERT_EQ(0u, small_array[kSmallArraySize - 1u]);
}
{ // Reuse the previous arena and allocate more than previous allocation including red zone.
ArenaAllocator allocator(&pool);
uint32_t* large_array = allocator.AllocArray<uint32_t>(kLargeArraySize);
ASSERT_EQ(0u, large_array[kLargeArraySize - 1u]); // Verify that the allocation was made on the same arena.
ASSERT_EQ(small_array, large_array);
}
}
TEST_F(ArenaAllocatorTest, LargeAllocations) { if (arena_allocator::kArenaAllocatorPreciseTracking) {
printf("WARNING: TEST DISABLED FOR precise arena tracking\n"); return;
}
{
CallocArenaPool pool;
ArenaAllocator allocator(&pool); // Note: Leaving some space for memory tool red zones. void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 5 / 8); void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 2 / 8);
ASSERT_NE(alloc1, alloc2);
ASSERT_EQ(1u, NumberOfArenas(&allocator));
}
{
CallocArenaPool pool;
ArenaAllocator allocator(&pool); void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 13 / 16); void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 11 / 16);
ASSERT_NE(alloc1, alloc2);
ASSERT_EQ(2u, NumberOfArenas(&allocator)); void* alloc3 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 7 / 16);
ASSERT_NE(alloc1, alloc3);
ASSERT_NE(alloc2, alloc3);
ASSERT_EQ(3u, NumberOfArenas(&allocator));
}
{
CallocArenaPool pool;
ArenaAllocator allocator(&pool); void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 13 / 16); void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 9 / 16);
ASSERT_NE(alloc1, alloc2);
ASSERT_EQ(2u, NumberOfArenas(&allocator)); // Note: Leaving some space for memory tool red zones. void* alloc3 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 5 / 16);
ASSERT_NE(alloc1, alloc3);
ASSERT_NE(alloc2, alloc3);
ASSERT_EQ(2u, NumberOfArenas(&allocator));
}
{
CallocArenaPool pool;
ArenaAllocator allocator(&pool); void* alloc1 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 9 / 16); void* alloc2 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 13 / 16);
ASSERT_NE(alloc1, alloc2);
ASSERT_EQ(2u, NumberOfArenas(&allocator)); // Note: Leaving some space for memory tool red zones. void* alloc3 = allocator.Alloc(arena_allocator::kArenaDefaultSize * 5 / 16);
ASSERT_NE(alloc1, alloc3);
ASSERT_NE(alloc2, alloc3);
ASSERT_EQ(2u, NumberOfArenas(&allocator));
}
{
CallocArenaPool pool;
ArenaAllocator allocator(&pool); // Note: Leaving some space for memory tool red zones. for (size_t i = 0; i != 15; ++i) { // Allocate 15 times from the same arena.
allocator.Alloc(arena_allocator::kArenaDefaultSize * 1 / 16);
ASSERT_EQ(i + 1u, NumberOfArenas(&allocator)); // Allocate a separate arena.
allocator.Alloc(arena_allocator::kArenaDefaultSize * 17 / 16);
ASSERT_EQ(i + 2u, NumberOfArenas(&allocator));
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.