xo-alloc: explicit typeseq arg to alloc
This commit is contained in:
parent
a136241fbb
commit
d5b6861b80
11 changed files with 48 additions and 26 deletions
|
|
@ -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. **/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace xo {
|
|||
**/
|
||||
struct IAllocator_Any : public AAllocator {
|
||||
//using Impl = IAllocator_ImplType<xo::facet::DVariantPlaceholder>;
|
||||
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(); }
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "ArenaConfig.hpp"
|
||||
#include "AllocError.hpp"
|
||||
#include "AllocInfo.hpp"
|
||||
#include <xo/facet/typeseq.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
|
|
@ -43,7 +44,9 @@ namespace xo {
|
|||
/** @brief a contiguous memory range **/
|
||||
using range_type = std::pair<value_type, value_type>;
|
||||
/** @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<T>()) **/
|
||||
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<T>();
|
||||
std::byte * mem = ialloc.alloc(t, sizeof(T));
|
||||
|
||||
if (mem)
|
||||
return new (mem) T(std::forward<Args>(args)...);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <string.h> // 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ namespace utest {
|
|||
xoshiro256ss * p_rgen,
|
||||
obj<AAllocator> 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),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue