+ xo-alloc + xo-object + xo-alloc docs + GC utests
This commit is contained in:
parent
8970f51dbd
commit
5f46b51f12
32 changed files with 2903 additions and 82 deletions
87
utest/ArenaAlloc.test.cpp
Normal file
87
utest/ArenaAlloc.test.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* @file ArenaAlloc.test.cpp
|
||||
*
|
||||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#include "xo/alloc/ArenaAlloc.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::gc::ArenaAlloc;
|
||||
|
||||
namespace ut {
|
||||
|
||||
namespace {
|
||||
struct testcase_alloc {
|
||||
testcase_alloc(std::size_t rz, std::size_t z)
|
||||
: redline_z_{rz}, arena_z_{z} {}
|
||||
|
||||
std::size_t redline_z_;
|
||||
std::size_t arena_z_;
|
||||
|
||||
};
|
||||
|
||||
std::vector<testcase_alloc>
|
||||
s_testcase_v = {
|
||||
testcase_alloc(0, 4096)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("linearalloc", "[alloc]")
|
||||
{
|
||||
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
||||
const testcase_alloc & tc = s_testcase_v[i_tc];
|
||||
|
||||
constexpr bool c_debug_flag = false;
|
||||
|
||||
auto alloc = ArenaAlloc::make("linearalloc", tc.redline_z_, tc.arena_z_, c_debug_flag);
|
||||
|
||||
REQUIRE(alloc.get());
|
||||
REQUIRE(alloc->name() == "linearalloc");
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == tc.arena_z_);
|
||||
REQUIRE(alloc->allocated() == 0);
|
||||
REQUIRE(alloc->is_before_checkpoint(alloc->free_ptr()) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == 0);
|
||||
|
||||
auto free0 = alloc->free_ptr();
|
||||
|
||||
auto mem = alloc->alloc(tc.arena_z_);
|
||||
|
||||
REQUIRE(mem != nullptr);
|
||||
|
||||
REQUIRE(mem == free0);
|
||||
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == 0);
|
||||
REQUIRE(alloc->allocated() == tc.arena_z_);
|
||||
REQUIRE(alloc->is_before_checkpoint(mem) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == tc.arena_z_);
|
||||
|
||||
alloc->clear();
|
||||
|
||||
REQUIRE(alloc->free_ptr() == free0);
|
||||
REQUIRE(alloc->available() == tc.arena_z_);
|
||||
REQUIRE(alloc->allocated() == 0);
|
||||
REQUIRE(alloc->is_before_checkpoint(free0) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == 0);
|
||||
|
||||
mem = alloc->alloc(1);
|
||||
|
||||
auto used = sizeof(void*);
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == tc.arena_z_ - used);
|
||||
REQUIRE(alloc->allocated() == used);
|
||||
REQUIRE(alloc->is_before_checkpoint(free0) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == used);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} /*namespace ut */
|
||||
} /*namespace xo*/
|
||||
|
|
@ -3,7 +3,8 @@
|
|||
set(SELF_EXE utest.alloc)
|
||||
set(SELF_SRCS
|
||||
alloc_utest_main.cpp
|
||||
LinearAlloc.test.cpp)
|
||||
ArenaAlloc.test.cpp
|
||||
GC.test.cpp)
|
||||
|
||||
xo_add_utest_executable(${SELF_EXE} ${SELF_SRCS})
|
||||
xo_self_dependency(${SELF_EXE} xo_alloc)
|
||||
|
|
|
|||
69
utest/GC.test.cpp
Normal file
69
utest/GC.test.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* @file GC.test.cpp
|
||||
*
|
||||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#include "xo/alloc/GC.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::gc::GC;
|
||||
using xo::gc::generation;
|
||||
using xo::gc::Config;
|
||||
|
||||
namespace ut {
|
||||
|
||||
namespace {
|
||||
struct testcase_gc {
|
||||
testcase_gc(std::size_t nz, std::size_t tz) : nursery_z_{nz}, tenured_z_{tz} {}
|
||||
|
||||
std::size_t nursery_z_;
|
||||
std::size_t tenured_z_;
|
||||
};
|
||||
|
||||
std::vector<testcase_gc>
|
||||
s_testcase_v = {
|
||||
testcase_gc(1024, 4096)
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("gc", "[alloc][gc]")
|
||||
{
|
||||
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
||||
const testcase_gc & tc = s_testcase_v[i_tc];
|
||||
|
||||
up<GC> gc = GC::make(
|
||||
{.initial_nursery_z_ = tc.nursery_z_,
|
||||
.initial_tenured_z_ = tc.tenured_z_});
|
||||
|
||||
REQUIRE(gc.get());
|
||||
REQUIRE(gc->size() == tc.nursery_z_ + tc.tenured_z_);
|
||||
REQUIRE(gc->allocated() == 0);
|
||||
REQUIRE(gc->available() == tc.nursery_z_);
|
||||
REQUIRE(gc->before_checkpoint() == 0);
|
||||
// ListAlloc model is that nothing is before checkpoint
|
||||
// until it's first established
|
||||
REQUIRE(gc->after_checkpoint() == 0);
|
||||
|
||||
REQUIRE(gc->gc_in_progress() == false);
|
||||
REQUIRE(gc->is_gc_enabled() == true);
|
||||
REQUIRE(gc->gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 0);
|
||||
REQUIRE(gc->gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
|
||||
|
||||
/* gc with empty state */
|
||||
gc->request_gc(generation::nursery);
|
||||
|
||||
REQUIRE(gc->gc_in_progress() == false);
|
||||
REQUIRE(gc->gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
|
||||
REQUIRE(gc->gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
|
||||
|
||||
/* still empty state */
|
||||
gc->request_gc(generation::tenured);
|
||||
|
||||
REQUIRE(gc->gc_in_progress() == false);
|
||||
REQUIRE(gc->gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
|
||||
REQUIRE(gc->gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 1);
|
||||
}
|
||||
}
|
||||
} /*namespace ut*/
|
||||
} /*namespace xo*/
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#include "xo/alloc/LinearAlloc.hpp"
|
||||
#include "xo/alloc/ArenaAlloc.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -33,15 +33,53 @@ namespace xo {
|
|||
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
||||
const testcase_alloc & tc = s_testcase_v[i_tc];
|
||||
|
||||
auto alloc = LinearAlloc::make(tc.redline_z_, tc.arena_z_);
|
||||
constexpr bool c_debug_flag = false;
|
||||
|
||||
auto alloc = LinearAlloc::make("linearalloc", tc.redline_z_, tc.arena_z_, c_debug_flag);
|
||||
|
||||
REQUIRE(alloc.get());
|
||||
REQUIRE(alloc->name() == "linearalloc");
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == tc.arena_z_);
|
||||
REQUIRE(alloc->allocated() == 0);
|
||||
REQUIRE(alloc->is_before_checkpoint(alloc->free_ptr()) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == 0);
|
||||
|
||||
auto free0 = alloc->free_ptr();
|
||||
|
||||
auto mem = alloc->alloc(tc.arena_z_);
|
||||
|
||||
REQUIRE(mem != nullptr);
|
||||
|
||||
REQUIRE(mem == free0);
|
||||
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == 0);
|
||||
REQUIRE(alloc->allocated() == tc.arena_z_);
|
||||
REQUIRE(alloc->is_before_checkpoint(mem) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == tc.arena_z_);
|
||||
|
||||
alloc->clear();
|
||||
|
||||
REQUIRE(alloc->free_ptr() == free0);
|
||||
REQUIRE(alloc->available() == tc.arena_z_);
|
||||
REQUIRE(alloc->allocated() == 0);
|
||||
REQUIRE(alloc->is_before_checkpoint(free0) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == 0);
|
||||
|
||||
mem = alloc->alloc(1);
|
||||
|
||||
auto used = sizeof(void*);
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == tc.arena_z_ - used);
|
||||
REQUIRE(alloc->allocated() == used);
|
||||
REQUIRE(alloc->is_before_checkpoint(free0) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == used);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue