Add indirect range (#562)
* Add indirect range The ranges currently either completely own the parent range, or it is a static and thus completely shared. The indirect range allows sharing without it being global. Co-authored-by: Nathaniel Filardo <nfilardo@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
fb85216386
commit
591dc4c77f
@@ -5,6 +5,7 @@
|
||||
#include "defaultpagemapentry.h"
|
||||
#include "empty_range.h"
|
||||
#include "globalrange.h"
|
||||
#include "indirectrange.h"
|
||||
#include "largebuddyrange.h"
|
||||
#include "logrange.h"
|
||||
#include "pagemap.h"
|
||||
|
||||
54
src/snmalloc/backend_helpers/indirectrange.h
Normal file
54
src/snmalloc/backend_helpers/indirectrange.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ds/ds.h"
|
||||
#include "empty_range.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* Stores a references to the parent range so that it can be shared
|
||||
* without `static` scope.
|
||||
*
|
||||
* This could be used to allow multiple allocators on a single region of
|
||||
* memory.
|
||||
*/
|
||||
struct IndirectRange
|
||||
{
|
||||
template<typename ParentRange = EmptyRange<>>
|
||||
class Type : public RefParent<ParentRange>
|
||||
{
|
||||
using RefParent<ParentRange>::parent;
|
||||
|
||||
public:
|
||||
static constexpr bool Aligned = ParentRange::Aligned;
|
||||
|
||||
static_assert(
|
||||
ParentRange::ConcurrencySafe,
|
||||
"IndirectRange requires a concurrency safe parent.");
|
||||
|
||||
static constexpr bool ConcurrencySafe = true;
|
||||
|
||||
using ChunkBounds = typename ParentRange::ChunkBounds;
|
||||
|
||||
constexpr Type() = default;
|
||||
|
||||
CapPtr<void, ChunkBounds> alloc_range(size_t size)
|
||||
{
|
||||
return parent->alloc_range(size);
|
||||
}
|
||||
|
||||
void dealloc_range(CapPtr<void, ChunkBounds> base, size_t size)
|
||||
{
|
||||
parent->dealloc_range(base, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Points the parent reference to the given range.
|
||||
*/
|
||||
void set_parent(ParentRange* p)
|
||||
{
|
||||
parent = p;
|
||||
}
|
||||
};
|
||||
};
|
||||
} // namespace snmalloc
|
||||
@@ -130,4 +130,35 @@ namespace snmalloc
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for allowing a range to be navigated to find an
|
||||
* ancestor of a specific type. The parent is a pointer to a range;
|
||||
* this allows the parent to be shared.
|
||||
*/
|
||||
template<typename Parent>
|
||||
class RefParent
|
||||
{
|
||||
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>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace snmalloc
|
||||
|
||||
Reference in New Issue
Block a user