Skip to content

Commit

Permalink
Move key_global into RemoteAllocator
Browse files Browse the repository at this point in the history
There was a mis-compilation in a Verona configuration that lead to
two instances of key_global existing.  This change moves it inside
a struct that seems to fix the issue.

The rest of the changes are limiting the use of key_global as both
RemoteCache and RemoteAllocator must use the same configuration,
so there is no need to take the key_global as a parameter.
  • Loading branch information
mjp41 committed Mar 28, 2023
1 parent d8f174c commit a933e5a
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/snmalloc/backend/globalconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ namespace snmalloc
LocalEntropy entropy;
entropy.init<Pal>();
// Initialise key for remote deallocation lists
key_global = FreeListKey(entropy.get_free_list_key());
RemoteAllocator::key_global = FreeListKey(entropy.get_free_list_key());

// Need to randomise pagemap location. If requested and not a
// StrictProvenance architecture, randomize its table's location within a
Expand Down
14 changes: 7 additions & 7 deletions src/snmalloc/mem/corealloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ namespace snmalloc
}
};

return !(message_queue().can_dequeue(key_global, domesticate));
return !(message_queue().can_dequeue(domesticate));
}

/**
Expand Down Expand Up @@ -502,11 +502,11 @@ namespace snmalloc
[](freelist::QueuePtr p) SNMALLOC_FAST_PATH_LAMBDA {
return freelist::HeadPtr::unsafe_from(p.unsafe_ptr());
};
message_queue().dequeue(key_global, domesticate_first, domesticate, cb);
message_queue().dequeue(domesticate_first, domesticate, cb);
}
else
{
message_queue().dequeue(key_global, domesticate, domesticate, cb);
message_queue().dequeue(domesticate, domesticate, cb);
}

if (need_post)
Expand Down Expand Up @@ -548,7 +548,7 @@ namespace snmalloc
need_post = true;
attached_cache->remote_dealloc_cache
.template dealloc<sizeof(CoreAllocator)>(
entry.get_remote()->trunc_id(), p.as_void(), key_global);
entry.get_remote()->trunc_id(), p.as_void());
}
}

Expand Down Expand Up @@ -643,7 +643,7 @@ namespace snmalloc
bool sent_something =
attached_cache->remote_dealloc_cache
.post<sizeof(CoreAllocator), Config>(
backend_state_ptr(), public_state()->trunc_id(), key_global);
backend_state_ptr(), public_state()->trunc_id());

return sent_something;
}
Expand Down Expand Up @@ -838,7 +838,7 @@ namespace snmalloc
while (p_tame != nullptr)
{
bool need_post = true; // Always going to post, so ignore.
auto n_tame = p_tame->atomic_read_next(key_global, domesticate);
auto n_tame = p_tame->atomic_read_next(RemoteAllocator::key_global, domesticate);
const PagemapEntry& entry =
Config::Backend::get_metaentry(snmalloc::address_cast(p_tame));
handle_dealloc_remote(entry, p_tame.as_void(), need_post);
Expand Down Expand Up @@ -891,7 +891,7 @@ namespace snmalloc
c->remote_allocator = public_state();

// Set up remote cache.
c->remote_dealloc_cache.init(entropy.get_free_list_key());
c->remote_dealloc_cache.init();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/snmalloc/mem/localalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ namespace snmalloc
const PagemapEntry& entry =
Config::Backend::template get_metaentry(address_cast(p));
local_cache.remote_dealloc_cache.template dealloc<sizeof(CoreAlloc)>(
entry.get_remote()->trunc_id(), p, key_global);
entry.get_remote()->trunc_id(), p);
post_remote_cache();
return;
}
Expand Down Expand Up @@ -670,7 +670,7 @@ namespace snmalloc
if (local_cache.remote_dealloc_cache.reserve_space(entry))
{
local_cache.remote_dealloc_cache.template dealloc<sizeof(CoreAlloc)>(
remote->trunc_id(), p_tame, key_global);
remote->trunc_id(), p_tame);
# ifdef SNMALLOC_TRACING
message<1024>(
"Remote dealloc fast {} ({})", p_raw, alloc_size(p_raw));
Expand Down
2 changes: 1 addition & 1 deletion src/snmalloc/mem/localcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace snmalloc
}

return remote_dealloc_cache.post<allocator_size, Config>(
local_state, remote_allocator->trunc_id(), key_global);
local_state, remote_allocator->trunc_id());
}

template<
Expand Down
22 changes: 10 additions & 12 deletions src/snmalloc/mem/remoteallocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@

namespace snmalloc
{
/**
* Global key for all remote lists.
*/
inline static FreeListKey key_global(0xdeadbeef, 0xbeefdead, 0xdeadbeef);

/**
*
* A RemoteAllocator is the message queue of freed objects. It exposes a MPSC
Expand Down Expand Up @@ -44,6 +39,11 @@ namespace snmalloc
*/
struct alignas(REMOTE_MIN_ALIGN) RemoteAllocator
{
/**
* Global key for all remote lists.
*/
inline static FreeListKey key_global{0xdeadbeef, 0xbeefdead, 0xdeadbeef};

using alloc_id_t = address_t;

// Store the message queue on a separate cacheline. It is mutable data that
Expand Down Expand Up @@ -84,10 +84,10 @@ namespace snmalloc

template<typename Domesticator_head>
inline bool
can_dequeue(const FreeListKey& key, Domesticator_head domesticate_head)
can_dequeue(Domesticator_head domesticate_head)
{
return domesticate_head(front.load())
->atomic_read_next(key, domesticate_head) == nullptr;
->atomic_read_next(key_global, domesticate_head) == nullptr;
}

/**
Expand All @@ -101,11 +101,10 @@ namespace snmalloc
void enqueue(
freelist::HeadPtr first,
freelist::HeadPtr last,
const FreeListKey& key,
Domesticator_head domesticate_head)
{
invariant();
freelist::Object::atomic_store_null(last, key);
freelist::Object::atomic_store_null(last, key_global);

// Exchange needs to be acq_rel.
// * It needs to be a release, so nullptr in next is visible.
Expand All @@ -116,7 +115,7 @@ namespace snmalloc

if (SNMALLOC_LIKELY(prev != nullptr))
{
freelist::Object::atomic_store_next(domesticate_head(prev), first, key);
freelist::Object::atomic_store_next(domesticate_head(prev), first, key_global);
return;
}

Expand All @@ -136,7 +135,6 @@ namespace snmalloc
typename Domesticator_queue,
typename Cb>
void dequeue(
const FreeListKey& key,
Domesticator_head domesticate_head,
Domesticator_queue domesticate_queue,
Cb cb)
Expand All @@ -150,7 +148,7 @@ namespace snmalloc

while (address_cast(curr) != address_cast(b))
{
freelist::HeadPtr next = curr->atomic_read_next(key, domesticate_queue);
freelist::HeadPtr next = curr->atomic_read_next(key_global, domesticate_queue);
// We have observed a non-linearisable effect of the queue.
// Just go back to allocating normally.
if (SNMALLOC_UNLIKELY(next == nullptr))
Expand Down
19 changes: 10 additions & 9 deletions src/snmalloc/mem/remotecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,22 @@ namespace snmalloc
template<size_t allocator_size>
SNMALLOC_FAST_PATH void dealloc(
RemoteAllocator::alloc_id_t target_id,
capptr::Alloc<void> p,
const FreeListKey& key)
capptr::Alloc<void> p)
{
SNMALLOC_ASSERT(initialised);
auto r = p.template as_reinterpret<freelist::Object::T<>>();

list[get_slot<allocator_size>(target_id, 0)].add(r, key);
list[get_slot<allocator_size>(target_id, 0)].add(r, RemoteAllocator::key_global);
}

template<size_t allocator_size, typename Config>
bool post(
typename Config::LocalState* local_state,
RemoteAllocator::alloc_id_t id,
const FreeListKey& key)
RemoteAllocator::alloc_id_t id)
{
// Use same key as the remote allocator, so segments can be
// posted to a remote allocator without reencoding.
const auto& key = RemoteAllocator::key_global;
SNMALLOC_ASSERT(initialised);
size_t post_round = 0;
bool sent_something = false;
Expand Down Expand Up @@ -118,11 +119,11 @@ namespace snmalloc
auto domesticate_nop = [](freelist::QueuePtr p) {
return freelist::HeadPtr::unsafe_from(p.unsafe_ptr());
};
remote->enqueue(first, last, key, domesticate_nop);
remote->enqueue(first, last, domesticate_nop);
}
else
{
remote->enqueue(first, last, key, domesticate);
remote->enqueue(first, last, domesticate);
}
sent_something = true;
}
Expand Down Expand Up @@ -166,7 +167,7 @@ namespace snmalloc
* Must be called before anything else to ensure actually initialised
* not just zero init.
*/
void init(const FreeListKey& key)
void init()
{
#ifndef NDEBUG
initialised = true;
Expand All @@ -175,7 +176,7 @@ namespace snmalloc
{
// We do not need to initialise with a particular slab, so pass
// a null address.
l.init(0, key);
l.init(0, RemoteAllocator::key_global);
}
capacity = REMOTE_CACHE;
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/func/domestication/domestication.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ int main()

LocalEntropy entropy;
entropy.init<DefaultPal>();
key_global = FreeListKey(entropy.get_free_list_key());
RemoteAllocator::key_global = FreeListKey(entropy.get_free_list_key());

auto alloc1 = new Alloc();

Expand Down

0 comments on commit a933e5a

Please sign in to comment.