NFC: FreeListIter domestication plumbing
Just an intermediate syntactic step to chase dependencies. All these introduced "domestication" callbacks are just the identity function, but they will let us thread the LocalAlloc's handle to the Backend state down to where it's needed.
This commit is contained in:
committed by
Nathaniel Wesley Filardo
parent
a34b7a5973
commit
7750676598
@@ -180,8 +180,11 @@ namespace snmalloc
|
||||
void* small_alloc_one(size_t size)
|
||||
{
|
||||
SNMALLOC_ASSERT(attached_cache != nullptr);
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
// Use attached cache, and fill it if it is empty.
|
||||
return attached_cache->template alloc<NoZero, SharedStateHandle>(
|
||||
domesticate,
|
||||
size,
|
||||
[&](
|
||||
sizeclass_t sizeclass,
|
||||
@@ -278,7 +281,9 @@ namespace snmalloc
|
||||
FreeListIter<capptr::bounds::Alloc, capptr::bounds::Alloc> fl;
|
||||
auto more = meta->free_queue.close(fl, key);
|
||||
UNUSED(more);
|
||||
void* p = finish_alloc_no_zero(fl.take(key), sizeclass);
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
void* p = finish_alloc_no_zero(fl.take(key, domesticate), sizeclass);
|
||||
|
||||
#ifdef SNMALLOC_CHECK_CLIENT
|
||||
// Check free list is well-formed on platforms with
|
||||
@@ -286,7 +291,7 @@ namespace snmalloc
|
||||
size_t count = 1; // Already taken one above.
|
||||
while (!fl.empty())
|
||||
{
|
||||
fl.take(key);
|
||||
fl.take(key, domesticate);
|
||||
count++;
|
||||
}
|
||||
// Check the list contains all the elements
|
||||
@@ -301,7 +306,7 @@ namespace snmalloc
|
||||
|
||||
while (!fl.empty())
|
||||
{
|
||||
fl.take(key);
|
||||
fl.take(key, domesticate);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -634,8 +639,10 @@ namespace snmalloc
|
||||
if (meta->needed() == 0)
|
||||
alloc_classes[sizeclass].unused--;
|
||||
|
||||
auto [p, still_active] =
|
||||
Metaslab::alloc_free_list(meta, fast_free_list, entropy, sizeclass);
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
auto [p, still_active] = Metaslab::alloc_free_list(
|
||||
domesticate, meta, fast_free_list, entropy, sizeclass);
|
||||
|
||||
if (still_active)
|
||||
{
|
||||
@@ -701,8 +708,10 @@ namespace snmalloc
|
||||
// Build a free list for the slab
|
||||
alloc_new_list(slab, meta, rsize, slab_size, entropy);
|
||||
|
||||
auto [p, still_active] =
|
||||
Metaslab::alloc_free_list(meta, fast_free_list, entropy, sizeclass);
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
auto [p, still_active] = Metaslab::alloc_free_list(
|
||||
domesticate, meta, fast_free_list, entropy, sizeclass);
|
||||
|
||||
if (still_active)
|
||||
{
|
||||
@@ -750,7 +759,8 @@ namespace snmalloc
|
||||
|
||||
auto posted =
|
||||
attached_cache->flush<sizeof(CoreAllocator), SharedStateHandle>(
|
||||
backend_state_ptr(), [&](auto p) { dealloc_local_object(p); });
|
||||
backend_state_ptr(),
|
||||
[&](capptr::Alloc<void> p) { dealloc_local_object(p); });
|
||||
|
||||
// We may now have unused slabs, return to the global allocator.
|
||||
for (sizeclass_t sizeclass = 0; sizeclass < NUM_SIZECLASSES; sizeclass++)
|
||||
|
||||
@@ -416,12 +416,11 @@ namespace snmalloc
|
||||
/**
|
||||
* Moves the iterator on, and returns the current value.
|
||||
*/
|
||||
FreeObject::HeadPtr<BView, BQueue> take(const FreeListKey& key)
|
||||
template<typename Domesticator>
|
||||
FreeObject::HeadPtr<BView, BQueue>
|
||||
take(const FreeListKey& key, Domesticator domesticate)
|
||||
{
|
||||
auto c = curr;
|
||||
// TODO: Placeholder
|
||||
auto domesticate = [](FreeObject::QueuePtr<BQueue> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
auto next = curr->read_next(key, domesticate);
|
||||
|
||||
Aal::prefetch(next.unsafe_ptr());
|
||||
|
||||
@@ -211,6 +211,9 @@ namespace snmalloc
|
||||
SNMALLOC_FAST_PATH void* small_alloc(size_t size)
|
||||
{
|
||||
// SNMALLOC_ASSUME(size <= sizeclass_to_size(NUM_SIZECLASSES));
|
||||
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
auto slowpath =
|
||||
[&](
|
||||
sizeclass_t sizeclass,
|
||||
@@ -239,7 +242,7 @@ namespace snmalloc
|
||||
};
|
||||
|
||||
return local_cache.template alloc<zero_mem, SharedStateHandle>(
|
||||
size, slowpath);
|
||||
domesticate, size, slowpath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,6 +82,8 @@ namespace snmalloc
|
||||
typename SharedStateHandle::LocalState* local_state, DeallocFun dealloc)
|
||||
{
|
||||
auto& key = entropy.get_free_list_key();
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
|
||||
for (size_t i = 0; i < NUM_SIZECLASSES; i++)
|
||||
{
|
||||
@@ -89,7 +91,7 @@ namespace snmalloc
|
||||
// call.
|
||||
while (!small_fast_free_lists[i].empty())
|
||||
{
|
||||
auto p = small_fast_free_lists[i].take(key);
|
||||
auto p = small_fast_free_lists[i].take(key, domesticate);
|
||||
SNMALLOC_ASSERT(Metaslab::is_start_of_object(i, address_cast(p)));
|
||||
dealloc(p.as_void());
|
||||
}
|
||||
@@ -99,18 +101,22 @@ namespace snmalloc
|
||||
local_state, remote_allocator->trunc_id(), key_global);
|
||||
}
|
||||
|
||||
template<ZeroMem zero_mem, typename SharedStateHandle, typename Slowpath>
|
||||
SNMALLOC_FAST_PATH void* alloc(size_t size, Slowpath slowpath)
|
||||
template<
|
||||
ZeroMem zero_mem,
|
||||
typename SharedStateHandle,
|
||||
typename Slowpath,
|
||||
typename Domesticator>
|
||||
SNMALLOC_FAST_PATH void*
|
||||
alloc(Domesticator domesticate, size_t size, Slowpath slowpath)
|
||||
{
|
||||
auto& key = entropy.get_free_list_key();
|
||||
|
||||
sizeclass_t sizeclass = size_to_sizeclass(size);
|
||||
stats.alloc_request(size);
|
||||
stats.sizeclass_alloc(sizeclass);
|
||||
auto& fl = small_fast_free_lists[sizeclass];
|
||||
if (likely(!fl.empty()))
|
||||
{
|
||||
auto p = fl.take(key);
|
||||
auto p = fl.take(key, domesticate);
|
||||
return finish_alloc<zero_mem, SharedStateHandle>(p, sizeclass);
|
||||
}
|
||||
return slowpath(sizeclass, &fl);
|
||||
|
||||
@@ -154,9 +154,11 @@ namespace snmalloc
|
||||
* component, but with randomisation, it may only return part of the
|
||||
* available objects for this metaslab.
|
||||
*/
|
||||
template<typename Domesticator>
|
||||
static SNMALLOC_FAST_PATH
|
||||
std::pair<FreeObject::QueuePtr<capptr::bounds::Alloc>, bool>
|
||||
alloc_free_list(
|
||||
Domesticator domesticate,
|
||||
Metaslab* meta,
|
||||
FreeListIter<capptr::bounds::Alloc, capptr::bounds::Alloc>&
|
||||
fast_free_list,
|
||||
@@ -167,7 +169,7 @@ namespace snmalloc
|
||||
|
||||
std::remove_reference_t<decltype(fast_free_list)> tmp_fl;
|
||||
auto remaining = meta->free_queue.close(tmp_fl, key);
|
||||
auto p = tmp_fl.take(key);
|
||||
auto p = tmp_fl.take(key, domesticate);
|
||||
fast_free_list = tmp_fl;
|
||||
|
||||
#ifdef SNMALLOC_CHECK_CLIENT
|
||||
|
||||
@@ -92,6 +92,8 @@ namespace snmalloc
|
||||
SNMALLOC_ASSERT(initialised);
|
||||
size_t post_round = 0;
|
||||
bool sent_something = false;
|
||||
auto domesticate = [](FreeObject::QueuePtr<capptr::bounds::Alloc> p)
|
||||
SNMALLOC_FAST_PATH_LAMBDA { return p; };
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -127,7 +129,7 @@ namespace snmalloc
|
||||
{
|
||||
// Use the next N bits to spread out remote deallocs in our own
|
||||
// slot.
|
||||
auto r = resend.take(key);
|
||||
auto r = resend.take(key, domesticate);
|
||||
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
|
||||
local_state, address_cast(r));
|
||||
auto i = entry.get_remote()->trunc_id();
|
||||
|
||||
Reference in New Issue
Block a user