diff --git a/include/xo/alloc2/AAllocator.hpp b/include/xo/alloc2/AAllocator.hpp index ada5184..9e77353 100644 --- a/include/xo/alloc2/AAllocator.hpp +++ b/include/xo/alloc2/AAllocator.hpp @@ -35,90 +35,61 @@ namespace xo { ///@{ /** RTTI: unique id# for actual runtime data representation **/ - virtual int32_t _typeseq() = 0; + virtual int32_t _typeseq() const = 0; /** optional name for allocator @p d * Labeling, for diagnostics. **/ - virtual const std::string & name(Copaque d) = 0; + virtual const std::string & name(Copaque d) const = 0; + /** reserved size in bytes for allocator @p d. + * Includes committed + uncommitted memory. + * Cannot be increased. + **/ + virtual std::size_t reserved(Copaque d) const = 0; /** allocator size in bytes (up to reserved limit) * for allocator @p d. - * Includes allocated and uncomitted memory + * Includes all committed memory. + * Can increase on @ref alloc **/ - virtual std::size_t size(Copaque d) = 0; + virtual std::size_t size(Copaque d) const = 0; /** committed size (physical addresses obtained) * for allocator @p d. **/ - virtual std::size_t committed(Copaque d) = 0; + virtual std::size_t committed(Copaque d) const = 0; /** true iff allocator @p d is responsible for memory at address @p p. **/ - virtual bool contains(Copaque d, const void * p) = 0; + virtual bool contains(Copaque d, const void * p) const = 0; /** allocate @p z bytes of memory from allocator @p d. **/ - virtual std::byte * alloc(Opaque d, std::size_t z) = 0; + virtual std::byte * alloc(Opaque d, std::size_t z) const = 0; /** reset allocator @p d to empty state **/ - virtual void clear(Opaque d) = 0; + virtual void clear(Opaque d) const = 0; /** destruct allocator @p d **/ - virtual void destruct_data(Opaque d) = 0; + virtual void destruct_data(Opaque d) const = 0; ///@} }; /*AAllocator*/ + // implementation IAllocator_DRepr of AAllocator for state DRepr + // should provide a specialization: + // + // template <> + // struct xo::facet::FacetImplementation { + // using ImplType = IAllocator_DRepr; + // }; + // + // then IAllocator_ImplType --> IAllocator_DRepr + // template - struct IAllocator_Impl; + using IAllocator_ImplType = xo::facet::FacetImplType; - template - using IAllocator_ImplType = IAllocator_Impl::ImplType; +// can't we do this with FacetImplementation +// +// template +// struct IAllocator_Impl {}; - struct IAllocator_Any : public AAllocator { - using Impl = Allocator_ImplType; +// template +// using IAllocator_ImplType = IAllocator_Impl::ImplType; - // from AAllocator - int32_t _typeseq() override { return s_typeseq; } - - const std::string & name(Copaque d) override { assert(false); static std::string x; return x; } - std::size_t size(Copaque d) override { assert(false); return 0ul; } - std::size_t committed(Copaque d) override { assert(false); reutrn 0ul; } - bool contains(Copaque d, const void * p) override { assert(false); return false; } - - std::byte * alloc(Opaque d, std::size_t z) override { assert(false); return nullptr; } - void clear(Opaque d) override { assert(false); } - void destruct_data(Opaque d) override { assert(false); } - - static int32_t s_typeseq; - static bool _valid; - } - - /** @class IAllocator_Xfer - **/ - template - struct IAllocator_Xfer : public AAllocator { - // parallel interface to AAllocator, with specific data type - using Impl = IAllocator_ImplType; - - static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } - - // from AAllocator - int32_t _typeseq() override { return s_typeseq; } - const std::string & name(Copaque d) override { return Impl::name(_dcast(d)); } - std::size_t size(Copaque d) override { return Impl::size(*(DRepr*)d); } - std::size_t committed(Copaque d) override { return Impl::committed(*(DRepr*)d); } - bool contains(Copaque d, const void * p) override { return Impl::contains(*(DRepr*)d, p); } - - std::byte * alloc(Opaque d, std::size_t z) override { return Impl::alloc(*(DRepr*)d, z); } - void clear(Opaque d) override { return Impl::clear(*(DRepr*)d); } - void destruct_data(Opaque d) override { return Impl::destruct_data(*(DRepr*)d); } - - static int32_t s_typeseq; - static bool _valid; - }; - - template - int32_t - IAllocator_Xfer::s_typeseq = facet::typeseq::id(); - - template - bool - IAllocator_Xfer::_valid = facet::valid_facet_implementation(); } /*namespace mm*/ } /*namespace xo*/ diff --git a/include/xo/alloc2/IAllocator_Any.hpp b/include/xo/alloc2/IAllocator_Any.hpp new file mode 100644 index 0000000..5a57720 --- /dev/null +++ b/include/xo/alloc2/IAllocator_Any.hpp @@ -0,0 +1,47 @@ +/** @file IAllocator_Any.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include "AAllocator.hpp" +#include + +namespace xo { + namespace mm { + struct IAllocator_Any; + } + + namespace facet { + template <> + struct FacetImplementation { + using ImplType = xo::mm::IAllocator_Any; + }; + } + + namespace mm { + struct IAllocator_Any : public AAllocator { + //using Impl = IAllocator_ImplType; + + // from AAllocator + int32_t _typeseq() const override { return s_typeseq; } + + const std::string & name(Copaque) const override { assert(false); static std::string * x; return *x; } + std::size_t reserved(Copaque) const override { assert(false); return 0ul; } + std::size_t size(Copaque) const override { assert(false); return 0ul; } + std::size_t committed(Copaque) const override { assert(false); return 0ul; } + bool contains(Copaque, const void *) const override { assert(false); return false; } + + std::byte * alloc(Opaque, std::size_t) const override { assert(false); return nullptr; } + void clear(Opaque) const override { assert(false); } + void destruct_data(Opaque) const override { assert(false); } + + static int32_t s_typeseq; + static bool _valid; + }; + } + +} + +/* end IAllocator_Any.hpp */ diff --git a/include/xo/alloc2/IAllocator_DArena.hpp b/include/xo/alloc2/IAllocator_DArena.hpp index 7a3d4c6..40f57bb 100644 --- a/include/xo/alloc2/IAllocator_DArena.hpp +++ b/include/xo/alloc2/IAllocator_DArena.hpp @@ -4,25 +4,38 @@ **/ #include "AAllocator.hpp" +#include "IAllocator_Xfer.hpp" #include "DArena.hpp" namespace xo { namespace mm { + struct IAllocator_DArena; + } - struct IAllocator_DArena { - static const std::string & name(const DArena & s); - static std::size_t size(const DArena & s); - static std::size_t committed(const DArena & s); - static bool contains(const DArena & s, const void * p); - static std::byte * alloc(const DArena & s, std::size_t z); - static void clear(DArena & s); - static void destruct_data(DArena & s); - }; - + namespace facet { template <> - struct IAllocator_Impl { - using ImplType = IAllocator_DArena; + struct FacetImplementation { + using ImplType = xo::mm::IAllocator_Xfer; }; + } + + namespace mm { + struct IAllocator_DArena { + static const std::string & name(const DArena &); + static std::size_t reserved(const DArena &); + static std::size_t size(const DArena &); + static std::size_t committed(const DArena &); + static bool contains(const DArena &, const void * p); + static std::byte * alloc(const DArena &, std::size_t z); + static void clear(DArena &); + static void destruct_data(DArena &); + }; + +// template <> +// struct IAllocator_Impl { +// using ImplType = IAllocator_DArena; +// }; } /*namespace mm*/ } /*namespace xo*/ diff --git a/include/xo/alloc2/IAllocator_Xfer.hpp b/include/xo/alloc2/IAllocator_Xfer.hpp new file mode 100644 index 0000000..a9b8888 --- /dev/null +++ b/include/xo/alloc2/IAllocator_Xfer.hpp @@ -0,0 +1,47 @@ +/** @file IAllocator_Xfer.hpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#pragma once + +#include "AAllocator.hpp" + +namespace xo { + namespace mm { + /** @class IAllocator_Xfer + **/ + template + struct IAllocator_Xfer : public AAllocator { + // parallel interface to AAllocator, with specific data type + using Impl = IAllocator_DRepr; + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + + // from AAllocator + int32_t _typeseq() const override { return s_typeseq; } + const std::string & name(Copaque d) const override { return Impl::name(_dcast(d)); } + std::size_t reserved(Copaque d) const override { return Impl::reserved(*(DRepr*)d); } + std::size_t size(Copaque d) const override { return Impl::size(*(DRepr*)d); } + std::size_t committed(Copaque d) const override { return Impl::committed(*(DRepr*)d); } + bool contains(Copaque d, const void * p) const override { return Impl::contains(*(DRepr*)d, p); } + + std::byte * alloc(Opaque d, std::size_t z) const override { return Impl::alloc(*(DRepr*)d, z); } + void clear(Opaque d) const override { return Impl::clear(*(DRepr*)d); } + void destruct_data(Opaque d) const override { return Impl::destruct_data(*(DRepr*)d); } + + static int32_t s_typeseq; + static bool _valid; + }; + + template + int32_t + IAllocator_Xfer::s_typeseq = facet::typeseq::id(); + + template + bool + IAllocator_Xfer::_valid = facet::valid_facet_implementation(); + } /*namespace mm*/ +} /*namespace xo*/ + +/* end IAllocator_Xfer.hpp */ diff --git a/include/xo/alloc2/RAllocator.hpp b/include/xo/alloc2/RAllocator.hpp index 76785ab..551581d 100644 --- a/include/xo/alloc2/RAllocator.hpp +++ b/include/xo/alloc2/RAllocator.hpp @@ -6,18 +6,29 @@ #pragma once #include "xo/facet/RRouter.hpp" +#include namespace xo { namespace mm { /** @class RAllocator **/ template struct RAllocator : public Object { + private: + using O = Object; + public: using ObjectType = Object; + using size_type = std::size_t; RAllocator() {} RAllocator(Object::DataPtr data) : Object{std::move(data)} {} - int32_t _typeseq() const { return Object::iface()->_typeseq(); } + int32_t _typeseq() const { return O::iface()->_typeseq(); } + const std::string & name() const { return O::iface()->name(O::data()); } + size_type reserved() const { return O::iface()->reserved(O::data()); } + size_type size() const { return O::iface()->size(O::data()); } + size_type committed() const { return O::iface()->committed(O::data()); } + bool contains(const void * p) const { return O::iface()->contains(O::data(), p); } + std::byte * alloc(size_type z) { return O::iface()->alloc(O::data(), z); } static bool _valid; }; diff --git a/src/alloc2/AAllocator.cpp b/src/alloc2/AAllocator.cpp index d896b6d..0061ef0 100644 --- a/src/alloc2/AAllocator.cpp +++ b/src/alloc2/AAllocator.cpp @@ -3,16 +3,7 @@ #include "xo/alloc2/AAllocator.hpp" namespace xo { - using xo::facet::DVariantPlaceholder; - using xo::facet::typeseq; - using xo::facet::valid_facet_implementation; - namespace mm { - int32_t - IAllocator_Any::s_typeseq = typeseq::id; - - bool - IAllocator_Any::_valid = valid_facet_implementation; } } diff --git a/src/alloc2/CMakeLists.txt b/src/alloc2/CMakeLists.txt index f742158..07b7dec 100644 --- a/src/alloc2/CMakeLists.txt +++ b/src/alloc2/CMakeLists.txt @@ -4,6 +4,7 @@ set(SELF_LIB xo_alloc2) set(SELF_SRCS AAllocator.cpp DArena.cpp + IAllocator_Any.cpp IAllocator_DArena.cpp ) diff --git a/src/alloc2/IAllocator_Any.cpp b/src/alloc2/IAllocator_Any.cpp new file mode 100644 index 0000000..24f9042 --- /dev/null +++ b/src/alloc2/IAllocator_Any.cpp @@ -0,0 +1,24 @@ +/** @file IAllocator_Any.cpp + * + * @author Roland Conybeare, Dec 2025 + **/ + +#include "IAllocator_Any.hpp" + +namespace xo { + using xo::facet::DVariantPlaceholder; + using xo::facet::typeseq; + using xo::facet::valid_facet_implementation; + + namespace mm { + + int32_t + IAllocator_Any::s_typeseq = typeseq::id(); + + bool + IAllocator_Any::_valid = valid_facet_implementation(); + + } /*namespace mm*/ +} /*namespace xo*/ + +/* end IAllocator_Any.cpp */ diff --git a/src/alloc2/IAllocator_DArena.cpp b/src/alloc2/IAllocator_DArena.cpp index 5dffefc..06a12d5 100644 --- a/src/alloc2/IAllocator_DArena.cpp +++ b/src/alloc2/IAllocator_DArena.cpp @@ -5,6 +5,7 @@ #include "IAllocator_DArena.hpp" #include +#include namespace xo { namespace mm { @@ -14,6 +15,11 @@ namespace xo { return s.config_.name_; } + std::size_t + IAllocator_DArena::reserved(const DArena & s) { + return s.hi_ - s.lo_; + } + std::size_t IAllocator_DArena::size(const DArena & s) { return s.limit_ - s.lo_; diff --git a/utest/arena.test.cpp b/utest/arena.test.cpp index c9a24f2..42453bc 100644 --- a/utest/arena.test.cpp +++ b/utest/arena.test.cpp @@ -4,7 +4,9 @@ **/ #include "xo/alloc2/AAllocator.hpp" -#include "xo/alloc2/DArena.hpp" +#include "xo/alloc2/IAllocator_Any.hpp" +#include "xo/alloc2/IAllocator_Xfer.hpp" +//#include "xo/alloc2/DArena.hpp" #include "xo/alloc2/IAllocator_DArena.hpp" #include "xo/alloc2/RAllocator.hpp" #include "xo/alloc2/padding.hpp" @@ -13,6 +15,7 @@ namespace xo { using xo::mm::AAllocator; + using xo::mm::IAllocator_DArena; using xo::mm::IAllocator_Xfer; using xo::mm::DArena; using xo::mm::ArenaConfig; @@ -23,9 +26,9 @@ namespace xo { namespace ut { TEST_CASE("IAllocator_Xfer_DArena", "[alloc2]") { - IAllocator_Xfer xfer; + IAllocator_Xfer xfer; - REQUIRE(IAllocator_Xfer::_valid); + REQUIRE(IAllocator_Xfer::_valid); } TEST_CASE("DArena", "[alloc2][DArena]") @@ -73,18 +76,36 @@ namespace xo { TEST_CASE("allocator-any-1", "[alloc2][AAllocator]") { -#ifdef NOPE - ArenaConfig cfg { .name_ = "testarena", - .size_ = 1 }; - DArena arena = DArena::map(cfg); -#endif - /* empty allocator */ obj alloc1; REQUIRE(!alloc1); REQUIRE(alloc1.iface() != nullptr); REQUIRE(alloc1.data() == nullptr); + + ArenaConfig cfg { .name_ = "testarena", + .size_ = 1 }; + DArena arena = DArena::map(cfg); + obj a1o{&arena}; + + REQUIRE(a1o); + REQUIRE(a1o.iface() != nullptr); + REQUIRE(a1o.data() != nullptr); + + REQUIRE(a1o._typeseq() + == xo::facet::FacetImplType::s_typeseq); + REQUIRE(a1o.name() == cfg.name_); + REQUIRE(a1o.reserved() >= cfg.size_); + REQUIRE(a1o.reserved() < cfg.size_ + cfg.hugepage_z_); + REQUIRE(a1o.reserved() % cfg.hugepage_z_ == 0); + REQUIRE(a1o.size() == 0); + REQUIRE(a1o.committed() == 0); + +#ifdef NOPE + byte * m = a1o.alloc(1); + + REQUIRE(m); +#endif } } /*namespace ut*/ } /*namespace xo*/