From 30615341e2b10e983459269c0b7d9ec01f638d81 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 19 Dec 2025 13:55:19 -0500 Subject: [PATCH] xo-alloc2: work on alloc_range + operator++ for alloc iterators [WIP] --- include/xo/alloc2/alloc/RAllocIterator.hpp | 3 + include/xo/alloc2/alloc/RAllocator.hpp | 3 +- src/alloc2/DArenaIterator.cpp | 2 +- src/alloc2/IAllocIterator_DArenaIterator.cpp | 9 ++ src/alloc2/IAllocator_DArena.cpp | 39 +++++++- utest/AllocIterator.test.cpp | 95 +++++++++++++++----- utest/random_allocs.cpp | 2 +- 7 files changed, 125 insertions(+), 28 deletions(-) diff --git a/include/xo/alloc2/alloc/RAllocIterator.hpp b/include/xo/alloc2/alloc/RAllocIterator.hpp index 6c2dd5e..6a14218 100644 --- a/include/xo/alloc2/alloc/RAllocIterator.hpp +++ b/include/xo/alloc2/alloc/RAllocIterator.hpp @@ -27,6 +27,9 @@ namespace xo { return O::iface()->compare(O::data(), other); } void next() noexcept { O::iface()->next(O::data()); } + /** triggers operator++ in obj> **/ + void _preincrement() noexcept { this->next(); } + static bool _valid; }; diff --git a/include/xo/alloc2/alloc/RAllocator.hpp b/include/xo/alloc2/alloc/RAllocator.hpp index 12d1a78..706b6a8 100644 --- a/include/xo/alloc2/alloc/RAllocator.hpp +++ b/include/xo/alloc2/alloc/RAllocator.hpp @@ -22,6 +22,7 @@ namespace xo { using DataPtr = Object::DataPtr; using size_type = std::size_t; using value_type = std::byte *; + using range_type = AAllocator::range_type; RAllocator() {} RAllocator(Object::DataPtr data) : Object{std::move(data)} {} @@ -36,7 +37,7 @@ namespace xo { bool contains(const void * p) const noexcept { return O::iface()->contains(O::data(), p); } AllocError last_error() const noexcept { return O::iface()->last_error(O::data()); } AllocInfo alloc_info(value_type mem) const noexcept { return O::iface()->alloc_info(O::data(), mem); } - //range_type alloc_range(DArena & mm) + range_type alloc_range(DArena & mm) const noexcept { return O::iface()->alloc_range(O::data(), mm); } value_type alloc(size_type z) noexcept { return O::iface()->alloc(O::data(), z); } value_type super_alloc(size_type z) noexcept { return O::iface()->super_alloc(O::data(), z); } diff --git a/src/alloc2/DArenaIterator.cpp b/src/alloc2/DArenaIterator.cpp index b9873e3..bcad394 100644 --- a/src/alloc2/DArenaIterator.cpp +++ b/src/alloc2/DArenaIterator.cpp @@ -91,7 +91,7 @@ namespace xo { cmpresult DArenaIterator::compare(const DArenaIterator & other_ix) const noexcept { - scope log(XO_DEBUG(false), + scope log(XO_DEBUG(true), xtag("arena", arena_), xtag("pos", pos_), xtag("other.arena", other_ix.arena_), diff --git a/src/alloc2/IAllocIterator_DArenaIterator.cpp b/src/alloc2/IAllocIterator_DArenaIterator.cpp index 4d929de..cfb9a34 100644 --- a/src/alloc2/IAllocIterator_DArenaIterator.cpp +++ b/src/alloc2/IAllocIterator_DArenaIterator.cpp @@ -5,6 +5,7 @@ #include "arena/IAllocIterator_DArenaIterator.hpp" #include "AllocIterator.hpp" +#include #include namespace xo { @@ -21,6 +22,10 @@ namespace xo { IAllocIterator_DArenaIterator::compare(const DArenaIterator & ix, const obj & other_arg) noexcept { + scope log(XO_DEBUG(true), + xtag("&ix", &ix), + xtag("ix.arena", ix.arena_), xtag("ix.pos", ix.pos_)); + /* downcast from variant */ auto other = obj::from(other_arg); @@ -29,6 +34,10 @@ namespace xo { DArenaIterator & other_ix = *other; + log && log(xtag("&other_ix", &other_ix), + xtag("other_ix.arena", other_ix.arena_), + xtag("other_ix.pos", other_ix.pos_)); + return ix.compare(other_ix); } diff --git a/src/alloc2/IAllocator_DArena.cpp b/src/alloc2/IAllocator_DArena.cpp index a9edc22..4580bb3 100644 --- a/src/alloc2/IAllocator_DArena.cpp +++ b/src/alloc2/IAllocator_DArena.cpp @@ -74,13 +74,46 @@ namespace xo { IAllocator_DArena::alloc_range(const DArena & s, DArena & ialloc) noexcept -> range_type { + scope log(XO_DEBUG(true)); + DArenaIterator * begin_ix = construct_with(ialloc, &s, s.begin_header()); DArenaIterator * end_ix = construct_with(ialloc, &s, s.end_header()); - obj begin_obj = with_facet::mkobj(begin_ix); - obj end_obj = with_facet::mkobj( end_ix); + obj begin_obj = with_facet::mkobj(begin_ix); + obj end_obj = with_facet::mkobj( end_ix); - return std::make_pair(begin_obj, end_obj); + log && log(xtag("begin_obj.typeseq", begin_obj._typeseq())); + + obj begin_vt = begin_obj; + obj end_vt = end_obj; + + log && log(xtag("begin_vt.typeseq", begin_vt._typeseq())); + + log && log(xtag("begin_ix", begin_ix), + xtag("begin_ix.arena", begin_ix->arena_), + xtag("begin_ix.pos", begin_ix->pos_)); + + range_type retval = std::make_pair(begin_vt, end_vt); + + log && log(xtag("1.retval.first.typeseq", retval.first._typeseq())); + + retval.first.from_obj(begin_vt); + retval.second.from_obj(end_vt); + + // this gets correct typeseq. so first.from_obj() works + log && log(xtag("2.retval.first.typeseq", retval.first._typeseq())); + + obj begin_vt2; + + begin_vt2 = retval.first; + + log && log(xtag("3.begin_vt2.typeseq", begin_vt2._typeseq())); + + retval = std::make_pair(begin_vt2, begin_vt2); + + log && log(xtag("4.retval.first.typeseq", retval.first._typeseq())); + + return retval; } bool diff --git a/utest/AllocIterator.test.cpp b/utest/AllocIterator.test.cpp index 52391ef..9dc4d74 100644 --- a/utest/AllocIterator.test.cpp +++ b/utest/AllocIterator.test.cpp @@ -8,6 +8,8 @@ #include "arena/IAllocator_DArena.hpp" #include "arena/IAllocIterator_DArenaIterator.hpp" #include "padding.hpp" +#include +#include #include namespace xo { @@ -27,6 +29,10 @@ namespace xo { using xo::mm::padding; using xo::mm::error; + using xo::facet::DVariantPlaceholder; + using xo::facet::obj; + using xo::facet::typeseq; + using std::byte; namespace ut { @@ -146,6 +152,8 @@ namespace xo { TEST_CASE("IAllocIterator-singlearena", "[alloc2]") { + scope log(XO_DEBUG(true)); + ArenaConfig cfg { .name_ = "testarena", .size_ = 64*1024, .store_header_flag_ = true, @@ -166,37 +174,80 @@ namespace xo { REQUIRE(arena.error_count_ == 0); REQUIRE(mem != nullptr); - DArenaIterator ix = arena.begin(); - DArenaIterator end_ix = arena.end(); - - REQUIRE(ix.is_valid()); - REQUIRE(end_ix.is_valid()); - - /* arena is non-empty, so begin!=end */ - REQUIRE (ix != end_ix); - - REQUIRE(arena.error_count_ == 0); - - /* valid iterator can be dereferenced */ { - AllocInfo info = *ix; + DArenaIterator ix = arena.begin(); + DArenaIterator end_ix = arena.end(); + + REQUIRE(ix.is_valid()); + REQUIRE(end_ix.is_valid()); + + /* arena is non-empty, so begin!=end */ + REQUIRE (ix != end_ix); REQUIRE(arena.error_count_ == 0); - REQUIRE(info.is_valid()); - REQUIRE(info.size() == padding::with_padding(req_z)); - auto [payload_lo, payload_hi] = info.payload(); + /* valid iterator can be dereferenced */ + { + AllocInfo info = *ix; - REQUIRE(payload_lo == mem); - REQUIRE(payload_hi == mem + info.size()); + REQUIRE(arena.error_count_ == 0); + REQUIRE(info.is_valid()); + REQUIRE(info.size() == padding::with_padding(req_z)); + + auto [payload_lo, payload_hi] = info.payload(); + + REQUIRE(payload_lo == mem); + REQUIRE(payload_hi == mem + info.size()); + } + + /* valid iterator can be advanced */ + { + ix.next(); + + REQUIRE(arena.error_count_ == 0); + REQUIRE(ix == end_ix); + } } - /* valid iterator can be advanced */ + // repeat, this time with generic iterators { - ix.next(); + log && log(xtag("section", "obj"), + xtag("arena", &arena), + xtag("arena.lo", arena.lo_), + xtag("arena.free", arena.free_)); - REQUIRE(arena.error_count_ == 0); - REQUIRE(ix == end_ix); + DArena scratch_mm + = DArena::map( + ArenaConfig{ + .size_ = 4*1024, + .hugepage_z_ = 4*1024}); + + auto range = a1o.alloc_range(scratch_mm); + + obj ix = range.first; + obj end_ix = range.second; + + REQUIRE(ix.iface()); + REQUIRE(ix.data()); + REQUIRE(end_ix.iface()); + REQUIRE(end_ix.data()); + + REQUIRE(scratch_mm.allocated() >= 2*sizeof(DArenaIterator)); + REQUIRE(scratch_mm.available() > 0); + + log && log(xtag("ix._typeseq", ix._typeseq()), + xtag("ix.data", ix.data())); + + log && log(xtag("typeseq", + typeseq::id())); + log && log(xtag("typeseq", + typeseq::id())); + log && log(xtag("typeseq", + typeseq::id())); + + REQUIRE(ix.compare(ix).is_equal()); + + //REQUIRE(ix.compare(end_ix).is_equal()); } } diff --git a/utest/random_allocs.cpp b/utest/random_allocs.cpp index b3fb514..0d638ec 100644 --- a/utest/random_allocs.cpp +++ b/utest/random_allocs.cpp @@ -170,7 +170,7 @@ namespace utest { DArena scratch_mm = DArena::map(ArenaConfig{.name_ = "scratch", .size_ = 4*1024, .hugepage_z_ = 4*1024 }); - + auto range = mm.alloc_range(scratch_mm); #ifdef NOT_YET // to verify iteration here, need iterator support in AAllocator