Skip to content

Commit b488dda

Browse files
committed
Separate locking from static range
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.
1 parent 392acff commit b488dda

File tree

3 files changed

+88
-29
lines changed

3 files changed

+88
-29
lines changed

src/snmalloc/backend_helpers/globalrange.h

+4-29
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "../ds/ds.h"
44
#include "empty_range.h"
5+
#include "lockrange.h"
6+
#include "staticrange.h"
57

68
namespace snmalloc
79
{
@@ -12,34 +14,7 @@ namespace snmalloc
1214
struct GlobalRange
1315
{
1416
template<typename ParentRange = EmptyRange>
15-
class Type : public StaticParent<ParentRange>
16-
{
17-
using StaticParent<ParentRange>::parent;
18-
19-
/**
20-
* This is infrequently used code, a spin lock simplifies the code
21-
* considerably, and should never be on the fast path.
22-
*/
23-
SNMALLOC_REQUIRE_CONSTINIT static inline FlagWord spin_lock{};
24-
25-
public:
26-
static constexpr bool Aligned = ParentRange::Aligned;
27-
28-
static constexpr bool ConcurrencySafe = true;
29-
30-
constexpr Type() = default;
31-
32-
capptr::Chunk<void> alloc_range(size_t size)
33-
{
34-
FlagLock lock(spin_lock);
35-
return parent.alloc_range(size);
36-
}
37-
38-
void dealloc_range(capptr::Chunk<void> base, size_t size)
39-
{
40-
FlagLock lock(spin_lock);
41-
parent.dealloc_range(base, size);
42-
}
43-
};
17+
class Type : public Pipe<ParentRange, LockRange, StaticRange>
18+
{};
4419
};
4520
} // namespace snmalloc
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include "../ds/ds.h"
4+
#include "empty_range.h"
5+
6+
namespace snmalloc
7+
{
8+
/**
9+
* Protect the ParentRange with a spin lock.
10+
*/
11+
struct LockRange
12+
{
13+
template<typename ParentRange = EmptyRange>
14+
class Type : public ContainsParent<ParentRange>
15+
{
16+
using ContainsParent<ParentRange>::parent;
17+
18+
/**
19+
* This is infrequently used code, a spin lock simplifies the code
20+
* considerably, and should never be on the fast path.
21+
*/
22+
FlagWord spin_lock{};
23+
24+
public:
25+
static constexpr bool Aligned = ParentRange::Aligned;
26+
27+
static constexpr bool ConcurrencySafe = true;
28+
29+
constexpr Type() = default;
30+
31+
capptr::Chunk<void> alloc_range(size_t size)
32+
{
33+
FlagLock lock(spin_lock);
34+
return parent.alloc_range(size);
35+
}
36+
37+
void dealloc_range(capptr::Chunk<void> base, size_t size)
38+
{
39+
FlagLock lock(spin_lock);
40+
parent.dealloc_range(base, size);
41+
}
42+
};
43+
};
44+
} // namespace snmalloc
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
3+
#include "../ds/ds.h"
4+
#include "empty_range.h"
5+
6+
namespace snmalloc
7+
{
8+
/**
9+
* Makes the supplied ParentRange into a global variable.
10+
*/
11+
struct StaticRange
12+
{
13+
template<typename ParentRange = EmptyRange>
14+
class Type : public StaticParent<ParentRange>
15+
{
16+
using StaticParent<ParentRange>::parent;
17+
18+
public:
19+
static constexpr bool Aligned = ParentRange::Aligned;
20+
21+
static_assert(
22+
ParentRange::ConcurrencySafe,
23+
"StaticRange requires a concurrency safe parent.");
24+
25+
static constexpr bool ConcurrencySafe = true;
26+
27+
constexpr Type() = default;
28+
29+
capptr::Chunk<void> alloc_range(size_t size)
30+
{
31+
return parent.alloc_range(size);
32+
}
33+
34+
void dealloc_range(capptr::Chunk<void> base, size_t size)
35+
{
36+
parent.dealloc_range(base, size);
37+
}
38+
};
39+
};
40+
} // namespace snmalloc

0 commit comments

Comments
 (0)