Plumb LocalState ptrs through to Pagemap accessors

David points out that we might not have a static way to get at the pagemap, so
it is potentially useful to pass pointers to state objects down from the
Allocators.
This commit is contained in:
Nathaniel Wesley Filardo
2021-08-24 16:34:30 +01:00
committed by Nathaniel Wesley Filardo
parent 3710e351fe
commit 3af9d35099
12 changed files with 141 additions and 75 deletions

View File

@@ -114,6 +114,21 @@ namespace snmalloc
}
}
/**
* Return a pointer to the backend state.
*/
LocalState* backend_state_ptr()
{
if constexpr (SharedStateHandle::Options.CoreAllocOwnsLocalState)
{
return &backend_state;
}
else
{
return backend_state;
}
}
/**
* Return this allocator's "truncated" ID, an integer useful as a hash
* value of this allocator.
@@ -376,8 +391,8 @@ namespace snmalloc
for (size_t i = 0; i < REMOTE_BATCH; i++)
{
auto p = message_queue().peek();
auto& entry =
SharedStateHandle::Pagemap::get_metaentry(snmalloc::address_cast(p));
auto& entry = SharedStateHandle::Pagemap::get_metaentry(
backend_state_ptr(), snmalloc::address_cast(p));
auto r = message_queue().dequeue(key_global);
@@ -516,9 +531,10 @@ namespace snmalloc
SNMALLOC_FAST_PATH bool post()
{
// stats().remote_post(); // TODO queue not in line!
bool sent_something = attached_cache->remote_dealloc_cache
.post<sizeof(CoreAllocator), SharedStateHandle>(
public_state()->trunc_id(), key_global);
bool sent_something =
attached_cache->remote_dealloc_cache
.post<sizeof(CoreAllocator), SharedStateHandle>(
backend_state_ptr(), public_state()->trunc_id(), key_global);
return sent_something;
}
@@ -538,8 +554,8 @@ namespace snmalloc
SNMALLOC_FAST_PATH void dealloc_local_object(void* p)
{
auto entry =
SharedStateHandle::Pagemap::get_metaentry(snmalloc::address_cast(p));
auto entry = SharedStateHandle::Pagemap::get_metaentry(
backend_state_ptr(), snmalloc::address_cast(p));
if (likely(dealloc_local_object_fast(entry, p, entropy)))
return;
@@ -666,7 +682,7 @@ namespace snmalloc
bool need_post = true; // Always going to post, so ignore.
auto n = p->atomic_read_next(key_global);
auto& entry = SharedStateHandle::Pagemap::get_metaentry(
snmalloc::address_cast(p));
backend_state_ptr(), snmalloc::address_cast(p));
handle_dealloc_remote(entry, p, need_post);
p = n;
}
@@ -681,7 +697,7 @@ namespace snmalloc
auto posted =
attached_cache->flush<sizeof(CoreAllocator), SharedStateHandle>(
[&](auto p) { dealloc_local_object(p); });
backend_state_ptr(), [&](auto 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++)

View File

@@ -260,8 +260,8 @@ namespace snmalloc
std::cout << "Remote dealloc post" << p << " size " << alloc_size(p)
<< std::endl;
#endif
MetaEntry entry =
SharedStateHandle::Pagemap::get_metaentry(address_cast(p));
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
core_alloc->backend_state_ptr(), address_cast(p));
local_cache.remote_dealloc_cache.template dealloc<sizeof(CoreAlloc)>(
entry.get_remote()->trunc_id(), CapPtr<void, CBAlloc>(p), key_global);
post_remote_cache();
@@ -472,8 +472,8 @@ namespace snmalloc
// before init, that maps null to a remote_deallocator that will never be
// in thread local state.
const MetaEntry& entry =
SharedStateHandle::Pagemap::get_metaentry(address_cast(p));
const MetaEntry& entry = SharedStateHandle::Pagemap::get_metaentry(
core_alloc->backend_state_ptr(), address_cast(p));
if (likely(local_cache.remote_allocator == entry.get_remote()))
{
if (likely(CoreAlloc::dealloc_local_object_fast(
@@ -583,8 +583,8 @@ namespace snmalloc
// To handle this case we require the uninitialised pagemap contain an
// entry for the first chunk of memory, that states it represents a large
// object, so we can pull the check for null off the fast path.
MetaEntry entry =
SharedStateHandle::Pagemap::get_metaentry(address_cast(p_raw));
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
core_alloc->backend_state_ptr(), address_cast(p_raw));
if (likely(entry.get_remote() != SharedStateHandle::fake_large_remote))
return sizeclass_to_size(entry.get_sizeclass());
@@ -611,7 +611,7 @@ namespace snmalloc
// TODO bring back the CHERI bits. Wes to review if required.
MetaEntry entry =
SharedStateHandle::Pagemap::template get_metaentry<true>(
address_cast(p_raw));
core_alloc->backend_state_ptr(), address_cast(p_raw));
auto sizeclass = entry.get_sizeclass();
if (likely(entry.get_remote() != SharedStateHandle::fake_large_remote))
{

View File

@@ -74,7 +74,8 @@ namespace snmalloc
size_t allocator_size,
typename SharedStateHandle,
typename DeallocFun>
bool flush(DeallocFun dealloc)
bool flush(
typename SharedStateHandle::LocalState* local_state, DeallocFun dealloc)
{
auto& key = entropy.get_free_list_key();
@@ -92,7 +93,7 @@ namespace snmalloc
}
return remote_dealloc_cache.post<allocator_size, SharedStateHandle>(
remote_allocator->trunc_id(), key_global);
local_state, remote_allocator->trunc_id(), key_global);
}
template<ZeroMem zero_mem, typename SharedStateHandle, typename Slowpath>

View File

@@ -76,7 +76,10 @@ namespace snmalloc
}
template<size_t allocator_size, typename SharedStateHandle>
bool post(RemoteAllocator::alloc_id_t id, const FreeListKey& key)
bool post(
typename SharedStateHandle::LocalState* local_state,
RemoteAllocator::alloc_id_t id,
const FreeListKey& key)
{
SNMALLOC_ASSERT(initialised);
size_t post_round = 0;
@@ -94,8 +97,8 @@ namespace snmalloc
if (!list[i].empty())
{
auto [first, last] = list[i].extract_segment(key);
MetaEntry entry =
SharedStateHandle::Pagemap::get_metaentry(address_cast(first));
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
local_state, address_cast(first));
entry.get_remote()->enqueue(first, last, key);
sent_something = true;
}
@@ -117,8 +120,8 @@ namespace snmalloc
// Use the next N bits to spread out remote deallocs in our own
// slot.
auto r = resend.take(key);
MetaEntry entry =
SharedStateHandle::Pagemap::get_metaentry(address_cast(r));
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
local_state, address_cast(r));
auto i = entry.get_remote()->trunc_id();
size_t slot = get_slot<allocator_size>(i, post_round);
list[slot].add(r, key);

View File

@@ -108,7 +108,7 @@ namespace snmalloc
#endif
MetaEntry entry{meta, remote, sizeclass};
SharedStateHandle::Pagemap::set_metaentry(
address_cast(slab), slab_size, entry);
&local_state, address_cast(slab), slab_size, entry);
return {slab, meta};
}