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 30, 2022
1 parent 1b8aa6b commit f7e100a
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 426 deletions.
21 changes: 10 additions & 11 deletions src/snmalloc/backend/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,52 +122,51 @@ namespace snmalloc
Base,
LargeBuddyRange<24, bits::BITS - 1, Pagemap, MinBaseSizeBits()>,
LogRange<2>,
GlobalRange<>>;
GlobalRange>;

#ifdef SNMALLOC_META_PROTECTED
// Introduce two global ranges, so we don't mix Object and Meta
using CentralObjectRange = Pipe<
GlobalR,
LargeBuddyRange<24, bits::BITS - 1, Pagemap, MinBaseSizeBits()>,
LogRange<3>,
GlobalRange<>>;
GlobalRange>;

using CentralMetaRange = Pipe<
GlobalR,
SubRange<PAL, 6>, // Use SubRange to introduce guard pages.
LargeBuddyRange<24, bits::BITS - 1, Pagemap, MinBaseSizeBits()>,
LogRange<4>,
GlobalRange<>>;
GlobalRange>;

// Source for object allocations
using StatsObject =
Pipe<CentralObjectRange, CommitRange<PAL>, StatsRange<>>;
using StatsObject = Pipe<CentralObjectRange, CommitRange<PAL>, StatsRange>;

using ObjectRange =
Pipe<StatsObject, LargeBuddyRange<21, 21, Pagemap>, LogRange<5>>;

using StatsMeta = Pipe<CentralMetaRange, CommitRange<PAL>, StatsRange<>>;
using StatsMeta = Pipe<CentralMetaRange, CommitRange<PAL>, StatsRange>;

using MetaRange = Pipe<
StatsMeta,
LargeBuddyRange<21 - 6, bits::BITS - 1, Pagemap>,
SmallBuddyRange<>>;
SmallBuddyRange>;

// Create global range that can service small meta-data requests.
// Don't want to add this to the CentralMetaRange to move Commit outside the
// lock on the common case.
using GlobalMetaRange = Pipe<StatsMeta, SmallBuddyRange<>, GlobalRange<>>;
using GlobalMetaRange = Pipe<StatsMeta, SmallBuddyRange, GlobalRange>;
using Stats = StatsCombiner<StatsObject, StatsMeta>;
#else
// Source for object allocations and metadata
// No separation between the two
using Stats = Pipe<GlobalR, StatsRange<>>;
using Stats = Pipe<GlobalR, StatsRange>;
using ObjectRange = Pipe<
Stats,
CommitRange<PAL>,
LargeBuddyRange<21, 21, Pagemap>,
SmallBuddyRange<>>;
using GlobalMetaRange = Pipe<ObjectRange, GlobalRange<>>;
SmallBuddyRange>;
using GlobalMetaRange = Pipe<ObjectRange, GlobalRange>;
#endif

struct LocalState
Expand Down
48 changes: 24 additions & 24 deletions src/snmalloc/backend_helpers/commitrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,36 @@

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

public:
/**
* We use a nested Apply type to enable a Pipe operation.
*/
template<typename ParentRange2>
using Apply = CommitRange<PAL, ParentRange2>;
public:
static constexpr bool Aligned = ParentRange::Aligned;

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

static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe;
constexpr Type() = default;

constexpr CommitRange() = default;
capptr::Chunk<void> alloc_range(size_t size)
{
SNMALLOC_ASSERT(size >= OS_PAGE_SIZE);

capptr::Chunk<void> alloc_range(size_t size)
{
auto range = parent.alloc_range(size);
if (range != nullptr)
PAL::template notify_using<NoZero>(range.unsafe_ptr(), size);
return range;
}
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)
{
PAL::notify_not_using(base.unsafe_ptr(), size);
parent.dealloc_range(base, size);
}
void dealloc_range(capptr::Chunk<void> base, size_t 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 f7e100a

Please sign in to comment.