Enable accessing parent ranges. (#529)
This exposes a feature on Ranges to access ranges higher up the stack of ranges. This could be useful for applying operations in the middle of a pipeline like object_range.ancestor<SpecialRange>().init(...); This allows some initialisation to be added to the middle of pipeline without breaking the current coding pattern. It also allows for bypassing some ranges object_range.ancestor<LargeObjectsRange>().alloc_chunk(...); Neither are done in this commit, but both will occur in future commits. Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
c445de8eb4
commit
7ff10c30f1
@@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
#include "../pal/pal.h"
|
||||
#include "empty_range.h"
|
||||
#include "range_helpers.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
template<typename PAL, typename ParentRange = EmptyRange>
|
||||
class CommitRange
|
||||
class CommitRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange parent{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace snmalloc
|
||||
* and protects access with a lock.
|
||||
*/
|
||||
template<typename ParentRange = EmptyRange>
|
||||
class GlobalRange
|
||||
class GlobalRange : public StaticParent<ParentRange>
|
||||
{
|
||||
SNMALLOC_REQUIRE_CONSTINIT static inline ParentRange parent{};
|
||||
using StaticParent<ParentRange>::parent;
|
||||
|
||||
/**
|
||||
* This is infrequently used code, a spin lock simplifies the code
|
||||
|
||||
@@ -189,9 +189,9 @@ namespace snmalloc
|
||||
SNMALLOC_CONCEPT(ConceptBuddyRangeMeta) Pagemap,
|
||||
size_t MIN_REFILL_SIZE_BITS = 0,
|
||||
typename ParentRange = EmptyRange>
|
||||
class LargeBuddyRange
|
||||
class LargeBuddyRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange parent{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
/**
|
||||
* Maximum size of a refill
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "empty_range.h"
|
||||
#include "range_helpers.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
@@ -11,9 +12,9 @@ namespace snmalloc
|
||||
* ParentRange is what the range is logging calls to.
|
||||
*/
|
||||
template<size_t RangeName, typename ParentRange = EmptyRange>
|
||||
class LogRange
|
||||
class LogRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange parent{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "../pal/pal.h"
|
||||
#include "empty_range.h"
|
||||
#include "range_helpers.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
@@ -9,9 +10,9 @@ namespace snmalloc
|
||||
SNMALLOC_CONCEPT(ConceptBackendMetaRange) Pagemap,
|
||||
bool CanConsolidate = true,
|
||||
typename ParentRange = EmptyRange>
|
||||
class PagemapRegisterRange
|
||||
class PagemapRegisterRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange state{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ namespace snmalloc
|
||||
|
||||
capptr::Chunk<void> alloc_range(size_t size)
|
||||
{
|
||||
auto base = state.alloc_range(size);
|
||||
auto base = parent.alloc_range(size);
|
||||
|
||||
if (base != nullptr)
|
||||
Pagemap::register_range(address_cast(base), size);
|
||||
|
||||
@@ -69,4 +69,65 @@ namespace snmalloc
|
||||
*/
|
||||
template<typename... Args>
|
||||
using Pipe = typename PipeImpl<Args...>::result;
|
||||
|
||||
/**
|
||||
* Helper class for allowing a range to be navigated to find an
|
||||
* ancestor of a specific type. The parent is an instance field.
|
||||
*/
|
||||
template<typename Parent>
|
||||
class ContainsParent
|
||||
{
|
||||
protected:
|
||||
Parent parent{};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the outermost Ancestor with the correct type.
|
||||
*
|
||||
* Fails to compile if no such ancestor exists.
|
||||
*/
|
||||
template<typename Anc>
|
||||
Anc* ancestor()
|
||||
{
|
||||
if constexpr (std::is_same_v<Anc, Parent>)
|
||||
{
|
||||
return &parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent.template ancestor<Anc>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for allowing a range to be navigated to find an
|
||||
* ancestor of a specific type. The parent is a static field.
|
||||
*/
|
||||
template<typename Parent>
|
||||
class StaticParent
|
||||
{
|
||||
protected:
|
||||
SNMALLOC_REQUIRE_CONSTINIT inline static Parent parent{};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the outermost Ancestor with the correct type.
|
||||
*
|
||||
* Fails to compile if no such ancestor exists.
|
||||
*/
|
||||
template<typename Anc>
|
||||
Anc* ancestor()
|
||||
{
|
||||
if constexpr (std::is_same_v<Anc, Parent>)
|
||||
{
|
||||
return &parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent.template ancestor<Anc>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace snmalloc
|
||||
|
||||
@@ -144,9 +144,9 @@ namespace snmalloc
|
||||
};
|
||||
|
||||
template<typename ParentRange = EmptyRange>
|
||||
class SmallBuddyRange
|
||||
class SmallBuddyRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange parent{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
static constexpr size_t MIN_BITS =
|
||||
bits::next_pow2_bits_const(sizeof(FreeChunk));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "empty_range.h"
|
||||
#include "range_helpers.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
@@ -10,9 +11,9 @@ namespace snmalloc
|
||||
* Used to measure memory usage.
|
||||
*/
|
||||
template<typename ParentRange = EmptyRange>
|
||||
class StatsRange
|
||||
class StatsRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange parent{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
static inline std::atomic<size_t> current_usage{};
|
||||
static inline std::atomic<size_t> peak_usage{};
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace snmalloc
|
||||
* the end of the large allocation.
|
||||
*/
|
||||
template<typename PAL, size_t RATIO_BITS, typename ParentRange = EmptyRange>
|
||||
class SubRange
|
||||
class SubRange : public ContainsParent<ParentRange>
|
||||
{
|
||||
ParentRange parent{};
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user