diff --git a/xo-alloc2/include/xo/alloc2/AAllocator.hpp b/xo-alloc2/include/xo/alloc2/AAllocator.hpp index bcb75fa8..4cb2d4e3 100644 --- a/xo-alloc2/include/xo/alloc2/AAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/AAllocator.hpp @@ -19,6 +19,12 @@ namespace xo { * **/ struct AAllocator { + /** @defgroup mm-allocator-type-traits allocator type traits **/ + ///@{ + /** @brief type used for allocation amounts **/ + using size_type = std::size_t; + ///@} + /* * <----------------------------size--------------------------> * <------------committed-----------><-------uncommitted------> @@ -44,19 +50,20 @@ namespace xo { * 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 all committed memory. + virtual size_type reserved(Copaque d) const = 0; + /** Synonym for @ref committed. * Can increase on @ref alloc **/ - virtual std::size_t size(Copaque d) const = 0; + virtual size_type size(Copaque d) const = 0; /** committed size (physical addresses obtained) * for allocator @p d. + * @ref alloc may auto-increase this **/ - virtual std::size_t committed(Copaque d) const = 0; + virtual size_type committed(Copaque d) const = 0; /** unallocated (but committed) size in bytes for allocator @p d **/ - virtual std::size_t available(Copaque d) const = 0; + virtual size_type available(Copaque d) const = 0; + /** allocated (i.e. in-use) amount in bytes for allocator @p d **/ + virtual size_type allocated(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) const = 0; diff --git a/xo-alloc2/include/xo/alloc2/IAllocator_Any.hpp b/xo-alloc2/include/xo/alloc2/IAllocator_Any.hpp index e344403a..18f06f87 100644 --- a/xo-alloc2/include/xo/alloc2/IAllocator_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/IAllocator_Any.hpp @@ -36,6 +36,7 @@ namespace xo { [[noreturn]] size_type size(Copaque) const override { _fatal(); } [[noreturn]] size_type committed(Copaque) const override { _fatal(); } [[noreturn]] size_type available(Copaque) const override { _fatal(); } + [[noreturn]] size_type allocated(Copaque) const override { _fatal(); } [[noreturn]] bool contains(Copaque, const void *) const override { _fatal(); } [[noreturn]] bool expand(Opaque, std::size_t) const override { _fatal(); } diff --git a/xo-alloc2/include/xo/alloc2/IAllocator_DArena.hpp b/xo-alloc2/include/xo/alloc2/IAllocator_DArena.hpp index 2a0a7036..bd5551ab 100644 --- a/xo-alloc2/include/xo/alloc2/IAllocator_DArena.hpp +++ b/xo-alloc2/include/xo/alloc2/IAllocator_DArena.hpp @@ -35,6 +35,7 @@ namespace xo { static size_type size(const DArena &); static size_type committed(const DArena &); static size_type available(const DArena &); + static size_type allocated(const DArena &); static bool contains(const DArena &, const void * p); /** expand committed space in arena @p d diff --git a/xo-alloc2/include/xo/alloc2/IAllocator_Xfer.hpp b/xo-alloc2/include/xo/alloc2/IAllocator_Xfer.hpp index 838cc0db..cedc37a2 100644 --- a/xo-alloc2/include/xo/alloc2/IAllocator_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/IAllocator_Xfer.hpp @@ -40,6 +40,9 @@ namespace xo { size_type available(Copaque d) const override { return I::available(_dcast(d)); } + size_type allocated(Copaque d) const override { + return I::allocated(_dcast(d)); + } bool contains(Copaque d, const void * p) const override { return Impl::contains(_dcast(d), p); diff --git a/xo-alloc2/include/xo/alloc2/RAllocator.hpp b/xo-alloc2/include/xo/alloc2/RAllocator.hpp index a47f4828..3701d997 100644 --- a/xo-alloc2/include/xo/alloc2/RAllocator.hpp +++ b/xo-alloc2/include/xo/alloc2/RAllocator.hpp @@ -28,6 +28,7 @@ namespace xo { size_type size() const { return O::iface()->size(O::data()); } size_type committed() const { return O::iface()->committed(O::data()); } 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); } 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); } diff --git a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp index 73bce9d3..77b3718e 100644 --- a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp +++ b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp @@ -40,6 +40,11 @@ namespace xo { return s.limit_ - s.free_; } + size_t + IAllocator_DArena::allocated(const DArena & s) { + return s.free_ - s.lo_; + } + bool IAllocator_DArena::contains(const DArena & s, const void * p) diff --git a/xo-alloc2/utest/arena.test.cpp b/xo-alloc2/utest/arena.test.cpp index 02912fe8..5006c7bc 100644 --- a/xo-alloc2/utest/arena.test.cpp +++ b/xo-alloc2/utest/arena.test.cpp @@ -103,6 +103,7 @@ namespace xo { REQUIRE(a1o.reserved() % cfg.hugepage_z_ == 0); REQUIRE(a1o.size() == 0); REQUIRE(a1o.committed() == 0); + REQUIRE(a1o.allocated() == 0); } TEST_CASE("allocator-expand-1", "[alloc2][AAllocator]") @@ -115,6 +116,7 @@ namespace xo { obj a1o{&arena}; REQUIRE(a1o.available() == 0); + REQUIRE(a1o.allocated() == 0); size_t z2 = 512; REQUIRE(a1o.expand(z2)); @@ -126,6 +128,7 @@ namespace xo { REQUIRE(a1o.size() == a1o.committed()); REQUIRE(a1o.available() >= z2); REQUIRE(a1o.available() == a1o.committed()); + REQUIRE(a1o.allocated() == 0); #ifdef NOPE byte * m = a1o.alloc(1);