diff --git a/include/xo/alloc2/alloc/AAllocator.hpp b/include/xo/alloc2/alloc/AAllocator.hpp index 6c191c5..26056fb 100644 --- a/include/xo/alloc2/alloc/AAllocator.hpp +++ b/include/xo/alloc2/alloc/AAllocator.hpp @@ -117,20 +117,22 @@ namespace xo { **/ virtual bool expand(Opaque d, std::size_t z) const noexcept = 0; /** attempt to allocate @p z bytes of memory from allocator @p d. + * for object with type @p t. + * (DX1collector cares about @p t, DArena does not) * If allocation fails returns nullptr. In this case error details may be retrieved * using last error **/ - virtual value_type alloc(Opaque d, size_type z) const = 0; + virtual value_type alloc(Opaque d, typeseq t, size_type z) const = 0; /** like @ref alloc, but follow with one or more consecutive * @ref sub_alloc() calls. This sequence of allocs will share * the initial allocation header. **/ - virtual value_type super_alloc(Opaque d, size_type z) const = 0; + virtual value_type super_alloc(Opaque d, typeseq t, size_type z) const = 0; /** follow a preceding @ref super_alloc call with additional * subsidiary allocs that share the same object header. * Must finish sequence with exactly one sub_alloc call * with @p complete_flag set. This sub_alloc call may have - * zero @p z + * zero @p z. **/ virtual value_type sub_alloc(Opaque d, size_type z, bool complete_flag) const = 0; /** reset allocator @p d to empty state. **/ diff --git a/include/xo/alloc2/alloc/IAllocator_Any.hpp b/include/xo/alloc2/alloc/IAllocator_Any.hpp index 60b174e..df3d18e 100644 --- a/include/xo/alloc2/alloc/IAllocator_Any.hpp +++ b/include/xo/alloc2/alloc/IAllocator_Any.hpp @@ -26,6 +26,7 @@ namespace xo { **/ struct IAllocator_Any : public AAllocator { //using Impl = IAllocator_ImplType; + using typeseq = xo::facet::typeseq; using size_type = std::size_t; const AAllocator * iface() const { return std::launder(this); } @@ -49,8 +50,8 @@ namespace xo { // non-const methods [[noreturn]] bool expand(Opaque, std::size_t) const noexcept override { _fatal(); } - [[noreturn]] value_type alloc(Opaque, std::size_t) const override { _fatal(); } - [[noreturn]] value_type super_alloc(Opaque, std::size_t) const override { _fatal(); } + [[noreturn]] value_type alloc(Opaque, typeseq, std::size_t) const override { _fatal(); } + [[noreturn]] value_type super_alloc(Opaque, typeseq, std::size_t) const override { _fatal(); } [[noreturn]] value_type sub_alloc(Opaque, std::size_t, bool) const override { _fatal(); } [[noreturn]] void clear(Opaque) const override { _fatal(); } [[noreturn]] void destruct_data(Opaque) const override { _fatal(); } diff --git a/include/xo/alloc2/alloc/IAllocator_Xfer.hpp b/include/xo/alloc2/alloc/IAllocator_Xfer.hpp index 796549b..7d23f2d 100644 --- a/include/xo/alloc2/alloc/IAllocator_Xfer.hpp +++ b/include/xo/alloc2/alloc/IAllocator_Xfer.hpp @@ -60,9 +60,11 @@ namespace xo { bool expand(Opaque d, std::size_t z) const noexcept override { return I::expand(_dcast(d), z); } value_type alloc(Opaque d, - std::size_t z) const override { return I::alloc(_dcast(d), z); } + typeseq t, + std::size_t z) const override { return I::alloc(_dcast(d), t, z); } value_type super_alloc(Opaque d, - std::size_t z) const override { return I::super_alloc(_dcast(d), z); } + typeseq t, + std::size_t z) const override { return I::super_alloc(_dcast(d), t, z); } value_type sub_alloc(Opaque d, std::size_t z, bool complete_flag) const override { diff --git a/include/xo/alloc2/alloc/RAllocator.hpp b/include/xo/alloc2/alloc/RAllocator.hpp index 005dc44..e39afe8 100644 --- a/include/xo/alloc2/alloc/RAllocator.hpp +++ b/include/xo/alloc2/alloc/RAllocator.hpp @@ -40,8 +40,8 @@ namespace xo { AllocInfo alloc_info(value_type mem) const noexcept { return O::iface()->alloc_info(O::data(), mem); } 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); } + value_type alloc(typeseq t, size_type z) noexcept { return O::iface()->alloc(O::data(), t, z); } + value_type super_alloc(typeseq t, size_type z) noexcept { return O::iface()->super_alloc(O::data(), t, z); } value_type sub_alloc(size_type z, bool complete_flag) noexcept { return O::iface()->sub_alloc(O::data(), z, complete_flag); } diff --git a/include/xo/alloc2/arena/DArena.hpp b/include/xo/alloc2/arena/DArena.hpp index 696dbae..efaf768 100644 --- a/include/xo/alloc2/arena/DArena.hpp +++ b/include/xo/alloc2/arena/DArena.hpp @@ -8,6 +8,7 @@ #include "ArenaConfig.hpp" #include "AllocError.hpp" #include "AllocInfo.hpp" +#include namespace xo { namespace mm { @@ -43,7 +44,9 @@ namespace xo { /** @brief a contiguous memory range **/ using range_type = std::pair; /** @brief type for allocation header (if enabled) **/ - using header_type = AllocHeader; //std::uint64_t; + using header_type = AllocHeader; + /** integer identifying a type (see xo::facet::typeid()) **/ + using typeseq = xo::facet::typeseq; /** @brief mode argument for @ref _alloc **/ enum class alloc_mode : uint8_t { @@ -169,14 +172,14 @@ namespace xo { * May expand committed memory, as long as resulting committed size * is no larger than reserved size **/ - value_type alloc(size_type z); + value_type alloc(typeseq t, size_type z); /** when store_header_flag enabled: * like alloc(), but combine memory consumed by this alloc * plus following consecutive sub_alloc()'s into a single header. * otherwise equivalent to alloc() **/ - value_type super_alloc(size_type z); + value_type super_alloc(typeseq t, size_type z); /** when store_header_flag enabled: * follow preceding super_alloc() by one or more sub_allocs(). @@ -271,7 +274,10 @@ namespace xo { static T * construct_with(DArena & ialloc, Args&&... args) { - std::byte * mem = ialloc.alloc(sizeof(T)); + using xo::facet::typeseq; + + typeseq t = typeseq::id(); + std::byte * mem = ialloc.alloc(t, sizeof(T)); if (mem) return new (mem) T(std::forward(args)...); diff --git a/include/xo/alloc2/arena/IAllocator_DArena.hpp b/include/xo/alloc2/arena/IAllocator_DArena.hpp index 85ef412..d7d5c58 100644 --- a/include/xo/alloc2/arena/IAllocator_DArena.hpp +++ b/include/xo/alloc2/arena/IAllocator_DArena.hpp @@ -29,6 +29,7 @@ namespace xo { * IAllocator_Xfer IAllocator_Xfer.hpp * RAllocator RAllocator.hpp */ + using typeseq = xo::facet::typeseq; using size_type = std::size_t; using value_type = std::byte *; using range_type = AAllocator::range_type; @@ -54,13 +55,13 @@ namespace xo { **/ static bool expand(DArena & d, size_type z) noexcept; - static value_type alloc(DArena &, size_type z); + static value_type alloc(DArena &, typeseq t, size_type z); /** when store_header_flag enabled: * like alloc(), but combine memory consumed by this alloc * plus following consecutive sub_alloc()'s into a single header. * otherwise equivalent to alloc() **/ - static value_type super_alloc(DArena &, size_type z); + static value_type super_alloc(DArena &, typeseq t, size_type z); /** when store_header_flag enabled: * follow preceding super_alloc() by one or more sub_allocs(). * accumulate total allocated size (including padding) into diff --git a/src/alloc2/DArena.cpp b/src/alloc2/DArena.cpp index af4892a..62dce15 100644 --- a/src/alloc2/DArena.cpp +++ b/src/alloc2/DArena.cpp @@ -15,6 +15,7 @@ #include // for ::memset() namespace xo { + using xo::facet::typeseq; using std::byte; using std::size_t; @@ -313,18 +314,20 @@ namespace xo { } std::byte * - DArena::alloc(std::size_t req_z) + DArena::alloc(typeseq t, std::size_t req_z) { /* - primary allocation path: * exactly 1 header per alloc() call. * - store_header_flag follows configuration */ + (void)t; + return _alloc(req_z, alloc_mode::standard); } std::byte * - DArena::super_alloc(std::size_t req_z) + DArena::super_alloc(typeseq t, std::size_t req_z) { /* - (uncommon) pattern for parent alloc immediately followed by * zero-or-more susidiary allocs, all sharing a single header. @@ -332,6 +335,8 @@ namespace xo { * ArenaConfig.store_header_flag_ disabled */ + (void)t; + return _alloc(req_z, alloc_mode::super); } diff --git a/src/alloc2/IAllocator_DArena.cpp b/src/alloc2/IAllocator_DArena.cpp index b536227..12a4a40 100644 --- a/src/alloc2/IAllocator_DArena.cpp +++ b/src/alloc2/IAllocator_DArena.cpp @@ -111,16 +111,18 @@ namespace xo { std::byte * IAllocator_DArena::alloc(DArena & s, + typeseq t, std::size_t req_z) { - return s.alloc(req_z); + return s.alloc(t, req_z); } std::byte * IAllocator_DArena::super_alloc(DArena & s, + typeseq t, std::size_t req_z) { - return s.super_alloc(req_z); + return s.super_alloc(t, req_z); } std::byte * diff --git a/utest/DArenaIterator.test.cpp b/utest/DArenaIterator.test.cpp index ce52675..8eb1614 100644 --- a/utest/DArenaIterator.test.cpp +++ b/utest/DArenaIterator.test.cpp @@ -169,7 +169,7 @@ namespace xo { /* arbitrary alloc size */ size_t req_z = 13; - byte * mem = a1o.alloc(req_z); + byte * mem = a1o.alloc(typeseq::anon(), req_z); REQUIRE(arena.error_count_ == 0); REQUIRE(mem != nullptr); diff --git a/utest/arena.test.cpp b/utest/arena.test.cpp index 09e5e4b..6c3278b 100644 --- a/utest/arena.test.cpp +++ b/utest/arena.test.cpp @@ -26,6 +26,7 @@ namespace xo { using xo::mm::padding; using xo::mm::error; using xo::facet::obj; + using xo::facet::typeseq; using xo::scope; using std::byte; using std::size_t; @@ -199,7 +200,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = 1; - byte * m0 = a1o.alloc(1); + byte * m0 = a1o.alloc(typeseq::anon(), 1); REQUIRE(m0); REQUIRE(a1o.last_error().error_ == error::ok); @@ -211,7 +212,7 @@ namespace xo { REQUIRE(a1o.committed() <= a1o.reserved()); size_t z1 = 16; - byte * m1 = a1o.alloc(z1); + byte * m1 = a1o.alloc(typeseq::anon(), z1); REQUIRE(m1); REQUIRE(a1o.last_error().error_ == error::ok); @@ -248,7 +249,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = 1; - byte * m0 = a1o.alloc(1); + byte * m0 = a1o.alloc(typeseq::anon(), 1); REQUIRE(m0); @@ -291,7 +292,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = 1; - byte * m0 = a1o.alloc(1); + byte * m0 = a1o.alloc(typeseq::anon(), 1); REQUIRE(m0); @@ -343,7 +344,7 @@ namespace xo { REQUIRE(a1o.allocated() == 0); size_t z0 = cfg.hugepage_z_ + 1; - byte * m0 = a1o.alloc(z0); + byte * m0 = a1o.alloc(typeseq::anon(), z0); REQUIRE(!m0); diff --git a/utest/random_allocs.cpp b/utest/random_allocs.cpp index 4031534..654c6c9 100644 --- a/utest/random_allocs.cpp +++ b/utest/random_allocs.cpp @@ -43,6 +43,8 @@ namespace utest { xoshiro256ss * p_rgen, obj mm) { + using xo::facet::typeseq; + scope log(XO_DEBUG(catch_flag), xtag("n-alloc", n_alloc)); /* track allocs. verify: @@ -65,7 +67,7 @@ namespace utest { bool ok_flag = true; - std::byte * mem = mm.alloc(z); + std::byte * mem = mm.alloc(typeseq::anon(), z); log && log(xtag("i_alloc", i_alloc), xtag("si", si),