1010
1111namespace snmalloc
1212{
13- /* *
14- * Global key for all remote lists.
15- */
16- inline static FreeListKey key_global (0xdeadbeef , 0xbeefdead , 0xdeadbeef );
17-
1813 /* *
1914 *
2015 * A RemoteAllocator is the message queue of freed objects. It exposes a MPSC
@@ -44,6 +39,16 @@ namespace snmalloc
4439 */
4540 struct alignas (REMOTE_MIN_ALIGN) RemoteAllocator
4641 {
42+ /* *
43+ * Global key for all remote lists.
44+ *
45+ * Note that we use a single key for all remote free lists and queues.
46+ * This is so that we do not have to recode next pointers when sending
47+ * segments, and look up specific keys based on destination. This is
48+ * potentially more performant, but could make it easier to guess the key.
49+ */
50+ inline static FreeListKey key_global{0xdeadbeef , 0xbeefdead , 0xdeadbeef };
51+
4752 using alloc_id_t = address_t ;
4853
4954 // Store the message queue on a separate cacheline. It is mutable data that
@@ -83,11 +88,10 @@ namespace snmalloc
8388 }
8489
8590 template <typename Domesticator_head>
86- inline bool
87- can_dequeue (const FreeListKey& key, Domesticator_head domesticate_head)
91+ inline bool can_dequeue (Domesticator_head domesticate_head)
8892 {
8993 return domesticate_head (front.load ())
90- ->atomic_read_next (key , domesticate_head) == nullptr ;
94+ ->atomic_read_next (key_global , domesticate_head) == nullptr ;
9195 }
9296
9397 /* *
@@ -101,11 +105,10 @@ namespace snmalloc
101105 void enqueue (
102106 freelist::HeadPtr first,
103107 freelist::HeadPtr last,
104- const FreeListKey& key,
105108 Domesticator_head domesticate_head)
106109 {
107110 invariant ();
108- freelist::Object::atomic_store_null (last, key );
111+ freelist::Object::atomic_store_null (last, key_global );
109112
110113 // Exchange needs to be acq_rel.
111114 // * It needs to be a release, so nullptr in next is visible.
@@ -116,7 +119,8 @@ namespace snmalloc
116119
117120 if (SNMALLOC_LIKELY (prev != nullptr ))
118121 {
119- freelist::Object::atomic_store_next (domesticate_head (prev), first, key);
122+ freelist::Object::atomic_store_next (
123+ domesticate_head (prev), first, key_global);
120124 return ;
121125 }
122126
@@ -136,7 +140,6 @@ namespace snmalloc
136140 typename Domesticator_queue,
137141 typename Cb>
138142 void dequeue (
139- const FreeListKey& key,
140143 Domesticator_head domesticate_head,
141144 Domesticator_queue domesticate_queue,
142145 Cb cb)
@@ -150,7 +153,8 @@ namespace snmalloc
150153
151154 while (address_cast (curr) != address_cast (b))
152155 {
153- freelist::HeadPtr next = curr->atomic_read_next (key, domesticate_queue);
156+ freelist::HeadPtr next =
157+ curr->atomic_read_next (key_global, domesticate_queue);
154158 // We have observed a non-linearisable effect of the queue.
155159 // Just go back to allocating normally.
156160 if (SNMALLOC_UNLIKELY (next == nullptr ))
0 commit comments