xo-alloc2: allocation unit tests

This commit is contained in:
Roland Conybeare 2025-12-12 14:04:20 -05:00
commit c63ec1f4d1
4 changed files with 82 additions and 12 deletions

View file

@ -30,6 +30,8 @@ namespace xo {
size_type available() const { return O::iface()->available(O::data()); }
size_type allocated() const { return O::iface()->allocated(O::data()); }
bool contains(const void * p) const { return O::iface()->contains(O::data(), p); }
AllocatorError last_error() const { return O::iface()->last_error(O::data()); }
bool expand(size_type z) { return O::iface()->expand(O::data(), z); }
std::byte * alloc(size_type z) { return O::iface()->alloc(O::data(), z); }

View file

@ -15,6 +15,11 @@ namespace xo {
/** word size for alignment**/
static constexpr std::size_t c_alloc_alignment = sizeof(std::uintptr_t);
static inline std::size_t is_aligned(std::size_t n,
std::size_t align = c_alloc_alignment) {
return n % align == 0;
}
/** how much to add to @p z to get a multiple of
* @ref c_alloc_alignment
**/

View file

@ -148,18 +148,13 @@ namespace xo {
{
scope log(XO_DEBUG(s.config_.debug_flag_));
/* word size for alignment (8 bytes) */
constexpr size_t c_bpw = sizeof(std::uintptr_t);
assert(padding::is_aligned((size_t)s.free_));
std::uintptr_t free_u64 = reinterpret_cast<std::uintptr_t>(s.free_);
assert(free_u64 % c_bpw == 0ul);
/* dz: pad req_z to multiple c_bpw */
/* dz: pad req_z to alignment size (multiple of 8 bytes, probably) */
size_t dz = padding::alloc_padding(req_z);
size_t z1 = req_z + dz;
assert(z1 % c_bpw == 0ul);
assert(padding::is_aligned(z1));
if (expand(s, allocated(s) + z1)) [[likely]] {
byte * mem = s.free_;

View file

@ -18,8 +18,11 @@ namespace xo {
using xo::mm::AAllocator;
using xo::mm::IAllocator_DArena;
using xo::mm::IAllocator_Xfer;
using xo::mm::AllocatorError;
using xo::mm::DArena;
using xo::mm::ArenaConfig;
using xo::mm::padding;
using xo::mm::error;
using xo::facet::obj;
using xo::scope;
using std::byte;
@ -130,11 +133,76 @@ namespace xo {
REQUIRE(a1o.available() == a1o.committed());
REQUIRE(a1o.allocated() == 0);
#ifdef NOPE
byte * m = a1o.alloc(1);
}
REQUIRE(m);
#endif
TEST_CASE("allocator-alloc-1", "[alloc2][AAllocator]")
{
/* typed allocator a1o */
ArenaConfig cfg { .name_ = "testarena",
.size_ = 64*1024,
.debug_flag_ = false };
DArena arena = DArena::map(cfg);
obj<AAllocator, DArena> a1o{&arena};
REQUIRE(a1o.reserved() >= cfg.size_);
REQUIRE(a1o.committed() == 0);
REQUIRE(a1o.available() == 0);
REQUIRE(a1o.allocated() == 0);
size_t z0 = 1;
byte * m0 = a1o.alloc(1);
REQUIRE(m0);
REQUIRE(a1o.last_error().error_ == error::none);
REQUIRE(a1o.last_error().error_seq_ == 0);
REQUIRE(a1o.allocated() >= z0);
REQUIRE(a1o.allocated() < z0 + padding::c_alloc_alignment );
REQUIRE(a1o.allocated() <= a1o.committed());
REQUIRE(a1o.allocated() + a1o.available() == a1o.committed());
REQUIRE(a1o.committed() <= a1o.reserved());
size_t z1 = 16;
byte * m1 = a1o.alloc(z1);
REQUIRE(m1);
REQUIRE(a1o.last_error().error_ == error::none);
REQUIRE(a1o.last_error().error_seq_ == 0);
REQUIRE(a1o.allocated() >= z0 + z1);
REQUIRE(a1o.allocated() < z0 + z1 + 2 * padding::c_alloc_alignment );
REQUIRE(a1o.allocated() <= a1o.committed());
REQUIRE(a1o.allocated() + a1o.available() == a1o.committed());
REQUIRE(a1o.committed() <= a1o.reserved());
}
TEST_CASE("allocator-fail-1", "[alloc2][AAllocator]")
{
/* typed allocator a1o */
ArenaConfig cfg { .name_ = "testarena",
.size_ = 64*1024,
.debug_flag_ = false };
DArena arena = DArena::map(cfg);
obj<AAllocator, DArena> a1o{&arena};
REQUIRE(cfg.size_ <= cfg.hugepage_z_);
REQUIRE(a1o.reserved() >= cfg.size_);
REQUIRE(a1o.committed() == 0);
REQUIRE(a1o.available() == 0);
REQUIRE(a1o.allocated() == 0);
size_t z0 = cfg.hugepage_z_ + 1;
byte * m0 = a1o.alloc(z0);
REQUIRE(!m0);
AllocatorError err = a1o.last_error();
REQUIRE(err.error_ == error::reserve_exhausted);
REQUIRE(err.error_seq_ == 1);
REQUIRE(err.request_z_ >= z0);
REQUIRE(err.request_z_ < z0 + padding::c_alloc_alignment);
REQUIRE(err.committed_z_ == 0);
REQUIRE(err.reserved_z_ == cfg.hugepage_z_);
}
} /*namespace ut*/
} /*namespace xo*/