/** @file AAllocator.hpp * * @author Roland Conybeare, Dec 2025 **/ #pragma once #include "AllocatorError.hpp" #include "xo/facet/facet_implementation.hpp" #include "xo/facet/typeseq.hpp" #include namespace xo { namespace mm { using Copaque = const void *; using Opaque = void *; /** @class AAllocator * @brief Abstract facet for allocation * **/ struct AAllocator { /** @defgroup mm-allocator-type-traits allocator type traits **/ ///@{ /** @brief type used for allocation amounts **/ using size_type = std::size_t; /** @brief type used for allocation responses **/ using value_type = std::byte *; /** object header, if configured **/ using header_type = std::uint64_t; ///@} /* * <----------------------------size--------------------------> * <------------committed-----------><-------uncommitted------> * <--allocated--> * * XXXXXXXXXXXXXXX___________________.......................... * * allocated: in use * committed: physical memory obtained * uncommitted: mapped in virtual memory, not backed by memory */ /** @defgroup mm-allocator-methods Allocator methods **/ ///@{ /** RTTI: unique id# for actual runtime data representation **/ virtual int32_t _typeseq() const noexcept = 0; /** optional name for allocator @p d * Labeling, for diagnostics. **/ virtual std::string_view name(Copaque d) const noexcept = 0; /** reserved size in bytes for allocator @p d. * Includes committed + uncommitted memory. * Cannot be increased. **/ virtual size_type reserved(Copaque d) const noexcept = 0; /** Synonym for @ref committed. * Can increase on @ref alloc **/ virtual size_type size(Copaque d) const noexcept = 0; /** committed size (physical addresses obtained) * for allocator @p d. * @ref alloc may auto-increase this **/ virtual size_type committed(Copaque d) const noexcept = 0; /** unallocated (but committed) size in bytes for allocator @p d **/ virtual size_type available(Copaque d) const noexcept = 0; /** allocated (i.e. in-use) amount in bytes for allocator @p d **/ virtual size_type allocated(Copaque d) const noexcept = 0; /** true iff allocator @p d is responsible for memory at address @p p. **/ virtual bool contains(Copaque d, const void * p) const noexcept = 0; /** report last error **/ virtual AllocatorError last_error(Copaque d) const noexcept = 0; /** expand committed space in arena @p d * to size at least @p z * In practice will round up to a multiple of hugepage size (2MB) **/ virtual bool expand(Opaque d, std::size_t z) const noexcept = 0; /** allocate @p z bytes of memory from allocator @p d. **/ virtual value_type alloc(Opaque d, 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; /** 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 **/ virtual value_type sub_alloc(Opaque d, size_type z, bool complete_flag) const = 0; /** reset allocator @p d to empty state **/ virtual void clear(Opaque d) const = 0; /** destruct allocator @p d **/ 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 using IAllocator_ImplType = xo::facet::FacetImplType; // can't we do this with FacetImplementation // // template // struct IAllocator_Impl {}; // template // using IAllocator_ImplType = IAllocator_Impl::ImplType; } /*namespace mm*/ } /*namespace xo*/ /* end AAllocator.hpp */