xo-alloc: UT for allocator interation + misc improvements
This commit is contained in:
parent
77f84cabbb
commit
764e98e12e
6 changed files with 295 additions and 154 deletions
|
|
@ -3,26 +3,124 @@
|
|||
* author: Roland Conybeare, Aug 2025
|
||||
*/
|
||||
|
||||
#include "xo/allocutil/IAlloc.hpp"
|
||||
//#include "xo/allocutil/IAlloc.hpp"
|
||||
#include "xo/alloc/ArenaAlloc.hpp"
|
||||
#include "xo/indentlog/print/tag.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::gc::IAlloc;
|
||||
using xo::gc::ArenaAlloc;
|
||||
|
||||
namespace ut {
|
||||
TEST_CASE("ialloc", "[alloc]")
|
||||
{
|
||||
static_assert((sizeof(std::uintptr_t) == 8) && "possibly fine if this fails, but would want to know");
|
||||
|
||||
REQUIRE(IAlloc::alloc_padding(0) == 0);
|
||||
REQUIRE(IAlloc::alloc_padding(1) == 7);
|
||||
REQUIRE(IAlloc::alloc_padding(2) == 6);
|
||||
REQUIRE(IAlloc::alloc_padding(3) == 5);
|
||||
REQUIRE(IAlloc::alloc_padding(4) == 4);
|
||||
REQUIRE(IAlloc::alloc_padding(5) == 3);
|
||||
REQUIRE(IAlloc::alloc_padding(6) == 2);
|
||||
REQUIRE(IAlloc::alloc_padding(7) == 1);
|
||||
REQUIRE(IAlloc::alloc_padding(8) == 0);
|
||||
REQUIRE(IAlloc::alloc_padding(9) == 7);
|
||||
|
||||
for (std::size_t i = 1; i < sizeof(std::uintptr_t); ++i) {
|
||||
REQUIRE(IAlloc::alloc_padding(i) + i == IAlloc::c_alloc_alignment);
|
||||
}
|
||||
|
||||
REQUIRE(IAlloc::alloc_padding(IAlloc::c_alloc_alignment) == 0);
|
||||
|
||||
for (std::size_t i = 1; i < sizeof(std::uintptr_t); ++i) {
|
||||
REQUIRE(IAlloc::alloc_padding(IAlloc::c_alloc_alignment + i) + i == IAlloc::c_alloc_alignment);
|
||||
}
|
||||
}
|
||||
|
||||
/* although xo::gc::allocator<T> is intended for
|
||||
* IAlloc derivatives (so T is ArenaAlloc | GC),
|
||||
*
|
||||
* it only relies on allocate() and deallocate() methods
|
||||
*/
|
||||
|
||||
namespace {
|
||||
struct TestCase {
|
||||
explicit TestCase(size_t arena_z, size_t n, size_t n2) : arena_z_{arena_z}, n_{n}, n2_{n2} {}
|
||||
|
||||
size_t arena_z_ = 0;
|
||||
size_t n_ = 0;
|
||||
size_t n2_ = 0;
|
||||
};
|
||||
|
||||
std::vector<TestCase> s_testcase_v = { TestCase{1024*1024, 9, 13} };
|
||||
}
|
||||
|
||||
TEST_CASE("gc.allocator", "[alloc]")
|
||||
{
|
||||
using xo::gc::allocator;
|
||||
|
||||
constexpr bool c_debug_flag = false;
|
||||
|
||||
for (size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
||||
INFO(xtag("i_tc", i_tc));
|
||||
|
||||
const TestCase & tc = s_testcase_v[i_tc];
|
||||
|
||||
up<ArenaAlloc> mm1 = ArenaAlloc::make("arena1",
|
||||
tc.arena_z_,
|
||||
c_debug_flag);
|
||||
up<ArenaAlloc> mm2 = ArenaAlloc::make("arena2",
|
||||
tc.arena_z_,
|
||||
c_debug_flag);
|
||||
|
||||
REQUIRE(mm1.get());
|
||||
REQUIRE(mm1->allocated() == 0);
|
||||
|
||||
allocator<int32_t> alloc1(mm1.get());
|
||||
allocator<double> alloc1a(mm1.get());
|
||||
|
||||
REQUIRE(mm2.get());
|
||||
REQUIRE(mm2->allocated() == 0);
|
||||
|
||||
allocator<int32_t> alloc2(mm2.get());
|
||||
|
||||
SECTION("IAlloc identity determines allocator equality") {
|
||||
REQUIRE(alloc1 == alloc1a);
|
||||
REQUIRE(alloc1 != alloc2);
|
||||
}
|
||||
|
||||
int * p1 = nullptr;
|
||||
size_t z1 = 0;
|
||||
|
||||
SECTION("alloc space for ints") {
|
||||
p1 = alloc1.allocate(tc.n_);
|
||||
|
||||
REQUIRE(p1 != nullptr);
|
||||
|
||||
// note: allowing for alignment
|
||||
REQUIRE(mm1->allocated() >= sizeof(int32_t) * tc.n_);
|
||||
REQUIRE(mm1->allocated() < sizeof(int32_t) * tc.n_ + IAlloc::c_alloc_alignment);
|
||||
z1 = mm1->allocated();
|
||||
|
||||
// deallocate exists..
|
||||
alloc1.deallocate(p1, tc.n_);
|
||||
|
||||
// ..but is a no-op
|
||||
REQUIRE(mm1->allocated() == z1);
|
||||
}
|
||||
|
||||
int * p2 = nullptr;
|
||||
|
||||
SECTION("allocator independence") {
|
||||
REQUIRE(mm2->allocated() == 0);
|
||||
|
||||
p2 = alloc2.allocate(tc.n2_);
|
||||
|
||||
REQUIRE(p2 != nullptr);
|
||||
REQUIRE(p1 != p2);
|
||||
|
||||
REQUIRE(mm2->allocated() >= sizeof(int32_t) * tc.n2_);
|
||||
REQUIRE(mm2->allocated() < sizeof(int32_t) * tc.n2_ + IAlloc::c_alloc_alignment);
|
||||
|
||||
// mm1 unaffected by mm2 allocation
|
||||
REQUIRE(mm1->allocated() == z1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /*namespace ut*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue