/* @file GC.test.cpp * * author: Roland Conybeare, Jul 2025 */ #include "xo/alloc/GC.hpp" #include 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, std::size_t n_gct, std::size_t t_gct) : nursery_z_{nz}, tenured_z_{tz}, incr_gc_threshold_{n_gct}, full_gc_threshold_{t_gct} {} std::size_t nursery_z_; std::size_t tenured_z_; std::size_t incr_gc_threshold_; std::size_t full_gc_threshold_; }; std::vector s_testcase_v = { // n_gct: nursery gc threshold // t_gct: tenured gc threshold // // nz tz n_gct t_gct testcase_gc(1024, 4096, 1024, 1024) }; } TEST_CASE("gc", "[alloc][gc]") { for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) { try { const testcase_gc & tc = s_testcase_v[i_tc]; up gc = GC::make( {.initial_nursery_z_ = tc.nursery_z_, .initial_tenured_z_ = tc.tenured_z_, .incr_gc_threshold_ = tc.incr_gc_threshold_, .full_gc_threshold_ = tc.full_gc_threshold_, }); REQUIRE(gc.get()); REQUIRE(gc->name() == "GC"); REQUIRE(gc->nursery_to_allocated() == 0); REQUIRE(gc->nursery_to_committed() >= tc.nursery_z_); REQUIRE(gc->nursery_to_reserved() >= tc.nursery_z_); REQUIRE(gc->nursery_to_reserved() < tc.nursery_z_ + gc->hugepage_z()); REQUIRE(gc->size() >= tc.nursery_z_ + tc.tenured_z_); REQUIRE(gc->size() < tc.nursery_z_ + gc->hugepage_z() + tc.tenured_z_ + gc->hugepage_z()); REQUIRE(gc->allocated() == 0); REQUIRE(gc->available() == gc->nursery_to_reserved()); 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->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 0); REQUIRE(gc->native_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->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1); REQUIRE(gc->native_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->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1); REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 1); } catch (std::exception &ex) { std::cerr << "caught exception: " << ex.what() << std::endl; REQUIRE(false); } } } } /*namespace ut*/ } /*namespace xo*/ /* GC.test.cpp */