in src/mem/remotecache.h [79:149]
bool post(
typename SharedStateHandle::LocalState* local_state,
RemoteAllocator::alloc_id_t id,
const FreeListKey& key)
{
SNMALLOC_ASSERT(initialised);
size_t post_round = 0;
bool sent_something = false;
auto domesticate =
[local_state](freelist::QueuePtr p) SNMALLOC_FAST_PATH_LAMBDA {
return capptr_domesticate<SharedStateHandle>(local_state, p);
};
while (true)
{
auto my_slot = get_slot<allocator_size>(id, post_round);
for (size_t i = 0; i < REMOTE_SLOTS; i++)
{
if (i == my_slot)
continue;
if (!list[i].empty())
{
auto [first, last] = list[i].extract_segment(key);
MetaEntry entry = SharedStateHandle::Pagemap::get_metaentry(
local_state, address_cast(first));
if constexpr (SharedStateHandle::Options.QueueHeadsAreTame)
{
auto domesticate_nop = [](freelist::QueuePtr p) {
return freelist::HeadPtr(p.unsafe_ptr());
};
entry.get_remote()->enqueue(first, last, key, domesticate_nop);
}
else
{
entry.get_remote()->enqueue(first, last, key, domesticate);
}
sent_something = true;
}
}
if (list[my_slot].empty())
break;
// Entries could map back onto the "resend" list,
// so take copy of the head, mark the last element,
// and clear the original list.
freelist::Iter<> resend;
list[my_slot].close(resend, key);
post_round++;
while (!resend.empty())
{
// Use the next N bits to spread out remote deallocs in our own
// slot.
auto r = resend.take(key, domesticate);
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);
}
}
// Reset capacity as we have empty everything
capacity = REMOTE_CACHE;
return sent_something;
}