Skip to content

Commit

Permalink
RFC, NFC: refactor ranges to be nested templates
Browse files Browse the repository at this point in the history
This way, we don't have to specify a Parent when we're just interested in
Pipe-ing things together.

We could have called these inner classes Apply and left the Pipe implementation
alone, but it's probably better to call them Type and adjust the Pipe code.
  • Loading branch information
nwf-msr committed May 31, 2022
1 parent 53d9fd2 commit 89fc430
Show file tree
Hide file tree
Showing 11 changed files with 403 additions and 428 deletions.
16 changes: 8 additions & 8 deletions src/snmalloc/backend/meta_protected_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace snmalloc
Pagemap,
MinSizeBits>,
LogRange<2>,
GlobalRange<>>;
GlobalRange>;

static constexpr size_t page_size_bits =
bits::next_pow2_bits_const(PAL::page_size);
Expand All @@ -53,9 +53,9 @@ namespace snmalloc
GlobalR,
LargeBuddyRange<GlobalCacheSizeBits, bits::BITS - 1, Pagemap>,
LogRange<3>,
GlobalRange<>,
GlobalRange,
CommitRange<PAL>,
StatsRange<>>;
StatsRange>;

// Controls the padding around the meta-data range.
// The larger the padding range the more randomisation that
Expand All @@ -81,8 +81,8 @@ namespace snmalloc
Pagemap,
page_size_bits>,
LogRange<4>,
GlobalRange<>,
StatsRange<>>;
GlobalRange,
StatsRange>;

// Local caching of object range
using ObjectRange = Pipe<
Expand All @@ -101,7 +101,7 @@ namespace snmalloc
LocalCacheSizeBits - SubRangeRatioBits,
bits::BITS - 1,
Pagemap>,
SmallBuddyRange<>>;
SmallBuddyRange>;

public:
using Stats = StatsCombiner<CentralObjectRange, CentralMetaRange>;
Expand All @@ -119,6 +119,6 @@ namespace snmalloc
// Don't want to add the SmallBuddyRange to the CentralMetaRange as that
// would require committing memory inside the main global lock.
using GlobalMetaRange =
Pipe<CentralMetaRange, SmallBuddyRange<>, GlobalRange<>>;
Pipe<CentralMetaRange, SmallBuddyRange, GlobalRange>;
};
} // namespace snmalloc
} // namespace snmalloc
10 changes: 5 additions & 5 deletions src/snmalloc/backend/standard_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ namespace snmalloc
Pagemap,
MinSizeBits>,
LogRange<2>,
GlobalRange<>>;
GlobalRange>;

// Track stats of the committed memory
using Stats = Pipe<GlobalR, CommitRange<PAL>, StatsRange<>>;
using Stats = Pipe<GlobalR, CommitRange<PAL>, StatsRange>;

private:
static constexpr size_t page_size_bits =
Expand All @@ -53,11 +53,11 @@ namespace snmalloc
LocalCacheSizeBits,
Pagemap,
page_size_bits>,
SmallBuddyRange<>>;
SmallBuddyRange>;

public:
// Expose a global range for the initial allocation of meta-data.
using GlobalMetaRange = Pipe<ObjectRange, GlobalRange<>>;
using GlobalMetaRange = Pipe<ObjectRange, GlobalRange>;

// Where we get user allocations from.
ObjectRange object_range;
Expand All @@ -69,4 +69,4 @@ namespace snmalloc
return object_range;
}
};
} // namespace snmalloc
} // namespace snmalloc
68 changes: 33 additions & 35 deletions src/snmalloc/backend_helpers/commitrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,44 @@

namespace snmalloc
{
template<typename PAL, typename ParentRange = EmptyRange>
class CommitRange : public ContainsParent<ParentRange>
template<typename PAL>
struct CommitRange
{
using ContainsParent<ParentRange>::parent;

public:
/**
* We use a nested Apply type to enable a Pipe operation.
*/
template<typename ParentRange2>
using Apply = CommitRange<PAL, ParentRange2>;
template<typename ParentRange>
class Type : public ContainsParent<ParentRange>
{
using ContainsParent<ParentRange>::parent;

static constexpr bool Aligned = ParentRange::Aligned;
public:
static constexpr bool Aligned = ParentRange::Aligned;

static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe;
static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe;

constexpr CommitRange() = default;
constexpr Type() = default;

capptr::Chunk<void> alloc_range(size_t size)
{
SNMALLOC_ASSERT_MSG(
(size % PAL::page_size) == 0,
"size ({}) must be a multiple of page size ({})",
size,
PAL::page_size);
auto range = parent.alloc_range(size);
if (range != nullptr)
PAL::template notify_using<NoZero>(range.unsafe_ptr(), size);
return range;
}
capptr::Chunk<void> alloc_range(size_t size)
{
SNMALLOC_ASSERT_MSG(
(size % PAL::page_size) == 0,
"size ({}) must be a multiple of page size ({})",
size,
PAL::page_size);
auto range = parent.alloc_range(size);
if (range != nullptr)
PAL::template notify_using<NoZero>(range.unsafe_ptr(), size);
return range;
}

void dealloc_range(capptr::Chunk<void> base, size_t size)
{
SNMALLOC_ASSERT_MSG(
(size % PAL::page_size) == 0,
"size ({}) must be a multiple of page size ({})",
size,
PAL::page_size);
PAL::notify_not_using(base.unsafe_ptr(), size);
parent.dealloc_range(base, size);
}
void dealloc_range(capptr::Chunk<void> base, size_t size)
{
SNMALLOC_ASSERT_MSG(
(size % PAL::page_size) == 0,
"size ({}) must be a multiple of page size ({})",
size,
PAL::page_size);
PAL::notify_not_using(base.unsafe_ptr(), size);
parent.dealloc_range(base, size);
}
};
};
} // namespace snmalloc
53 changes: 25 additions & 28 deletions src/snmalloc/backend_helpers/globalrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,37 @@ namespace snmalloc
* Makes the supplied ParentRange into a global variable,
* and protects access with a lock.
*/
template<typename ParentRange = EmptyRange>
class GlobalRange : public StaticParent<ParentRange>
struct GlobalRange
{
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{};
template<typename ParentRange = EmptyRange>
class Type : public StaticParent<ParentRange>
{
using StaticParent<ParentRange>::parent;

public:
/**
* We use a nested Apply type to enable a Pipe operation.
*/
template<typename ParentRange2>
using Apply = GlobalRange<ParentRange2>;
/**
* 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{};

static constexpr bool Aligned = ParentRange::Aligned;
public:
static constexpr bool Aligned = ParentRange::Aligned;

static constexpr bool ConcurrencySafe = true;
static constexpr bool ConcurrencySafe = true;

constexpr GlobalRange() = default;
constexpr Type() = default;

capptr::Chunk<void> alloc_range(size_t size)
{
FlagLock lock(spin_lock);
return parent.alloc_range(size);
}
capptr::Chunk<void> alloc_range(size_t size)
{
FlagLock lock(spin_lock);
return parent.alloc_range(size);
}

void dealloc_range(capptr::Chunk<void> base, size_t size)
{
FlagLock lock(spin_lock);
parent.dealloc_range(base, size);
}
void dealloc_range(capptr::Chunk<void> base, size_t size)
{
FlagLock lock(spin_lock);
parent.dealloc_range(base, size);
}
};
};
} // namespace snmalloc
Loading

0 comments on commit 89fc430

Please sign in to comment.