Separate locking from static range (#540)
Pull a part the locking from the static range. This enables locking to be added to a range directly, and does not require it to be made static. This is useful in cases where the source of memory is shared between threads, but not static. I.e. there are multiple instances of the same type.
This commit is contained in:
committed by
GitHub
parent
8f8dbd83b5
commit
a118c9b7d8
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "../ds/ds.h"
|
||||
#include "empty_range.h"
|
||||
#include "lockrange.h"
|
||||
#include "staticrange.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
@@ -12,36 +14,7 @@ namespace snmalloc
|
||||
struct GlobalRange
|
||||
{
|
||||
template<typename ParentRange = EmptyRange<>>
|
||||
class Type : public StaticParent<ParentRange>
|
||||
{
|
||||
using StaticParent<ParentRange>::parent;
|
||||
|
||||
/**
|
||||
* This is infrequently used code, a spin lock simplifies the code
|
||||
* considerably, and should never be on the fast path.
|
||||
*/
|
||||
SNMALLOC_REQUIRE_CONSTINIT static inline FlagWord spin_lock{};
|
||||
|
||||
public:
|
||||
static constexpr bool Aligned = ParentRange::Aligned;
|
||||
|
||||
static constexpr bool ConcurrencySafe = true;
|
||||
|
||||
using ChunkBounds = typename ParentRange::ChunkBounds;
|
||||
|
||||
constexpr Type() = default;
|
||||
|
||||
CapPtr<void, ChunkBounds> alloc_range(size_t size)
|
||||
{
|
||||
FlagLock lock(spin_lock);
|
||||
return parent.alloc_range(size);
|
||||
}
|
||||
|
||||
void dealloc_range(CapPtr<void, ChunkBounds> base, size_t size)
|
||||
{
|
||||
FlagLock lock(spin_lock);
|
||||
parent.dealloc_range(base, size);
|
||||
}
|
||||
};
|
||||
class Type : public Pipe<ParentRange, LockRange, StaticRange>
|
||||
{};
|
||||
};
|
||||
} // namespace snmalloc
|
||||
|
||||
46
src/snmalloc/backend_helpers/lockrange.h
Normal file
46
src/snmalloc/backend_helpers/lockrange.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ds/ds.h"
|
||||
#include "empty_range.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* Protect the ParentRange with a spin lock.
|
||||
*/
|
||||
struct LockRange
|
||||
{
|
||||
template<typename ParentRange = EmptyRange<>>
|
||||
class Type : public ContainsParent<ParentRange>
|
||||
{
|
||||
using ContainsParent<ParentRange>::parent;
|
||||
|
||||
/**
|
||||
* This is infrequently used code, a spin lock simplifies the code
|
||||
* considerably, and should never be on the fast path.
|
||||
*/
|
||||
FlagWord spin_lock{};
|
||||
|
||||
public:
|
||||
static constexpr bool Aligned = ParentRange::Aligned;
|
||||
|
||||
using ChunkBounds = typename ParentRange::ChunkBounds;
|
||||
|
||||
static constexpr bool ConcurrencySafe = true;
|
||||
|
||||
constexpr Type() = default;
|
||||
|
||||
CapPtr<void, ChunkBounds> alloc_range(size_t size)
|
||||
{
|
||||
FlagLock lock(spin_lock);
|
||||
return parent.alloc_range(size);
|
||||
}
|
||||
|
||||
void dealloc_range(CapPtr<void, ChunkBounds> base, size_t size)
|
||||
{
|
||||
FlagLock lock(spin_lock);
|
||||
parent.dealloc_range(base, size);
|
||||
}
|
||||
};
|
||||
};
|
||||
} // namespace snmalloc
|
||||
42
src/snmalloc/backend_helpers/staticrange.h
Normal file
42
src/snmalloc/backend_helpers/staticrange.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ds/ds.h"
|
||||
#include "empty_range.h"
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* Makes the supplied ParentRange into a global variable.
|
||||
*/
|
||||
struct StaticRange
|
||||
{
|
||||
template<typename ParentRange = EmptyRange<>>
|
||||
class Type : public StaticParent<ParentRange>
|
||||
{
|
||||
using StaticParent<ParentRange>::parent;
|
||||
|
||||
public:
|
||||
static constexpr bool Aligned = ParentRange::Aligned;
|
||||
|
||||
static_assert(
|
||||
ParentRange::ConcurrencySafe,
|
||||
"StaticRange 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);
|
||||
}
|
||||
};
|
||||
};
|
||||
} // namespace snmalloc
|
||||
Reference in New Issue
Block a user