@@ -56,19 +56,19 @@ struct GetIndexShuffleBits<false, array_size, elements_per_cache_line> {
56
56
// the element within the cache line) with the next N bits (which are the index of the cache line)
57
57
// of the element index.
58
58
template <int BITS>
59
- constexpr unsigned remap_index (unsigned index) noexcept {
59
+ ATOMIC_QUEUE_INLINE static constexpr unsigned remap_index (unsigned index) noexcept {
60
60
unsigned constexpr mix_mask{(1u << BITS) - 1 };
61
61
unsigned const mix{(index ^ (index >> BITS)) & mix_mask};
62
62
return index ^ mix ^ (mix << BITS);
63
63
}
64
64
65
65
template <>
66
- constexpr unsigned remap_index<0 >(unsigned index) noexcept {
66
+ ATOMIC_QUEUE_INLINE constexpr unsigned remap_index<0 >(unsigned index) noexcept {
67
67
return index;
68
68
}
69
69
70
70
template <int BITS, class T >
71
- constexpr T& map (T* elements, unsigned index) noexcept {
71
+ ATOMIC_QUEUE_INLINE static constexpr T& map (T* elements, unsigned index) noexcept {
72
72
return elements[remap_index<BITS>(index)];
73
73
}
74
74
@@ -87,30 +87,30 @@ constexpr T& map(T* elements, unsigned index) noexcept {
87
87
// ++a;
88
88
89
89
template <class T >
90
- constexpr T decrement (T x) noexcept {
90
+ ATOMIC_QUEUE_INLINE static constexpr T decrement (T x) noexcept {
91
91
return x - 1 ;
92
92
}
93
93
94
94
template <class T >
95
- constexpr T increment (T x) noexcept {
95
+ ATOMIC_QUEUE_INLINE static constexpr T increment (T x) noexcept {
96
96
return x + 1 ;
97
97
}
98
98
99
99
template <class T >
100
- constexpr T or_equal (T x, unsigned u) noexcept {
100
+ ATOMIC_QUEUE_INLINE static constexpr T or_equal (T x, unsigned u) noexcept {
101
101
return x | x >> u;
102
102
}
103
103
104
104
template <class T , class ... Args>
105
- constexpr T or_equal (T x, unsigned u, Args... rest) noexcept {
105
+ ATOMIC_QUEUE_INLINE static constexpr T or_equal (T x, unsigned u, Args... rest) noexcept {
106
106
return or_equal (or_equal (x, u), rest...);
107
107
}
108
108
109
- constexpr uint32_t round_up_to_power_of_2 (uint32_t a) noexcept {
109
+ ATOMIC_QUEUE_INLINE static constexpr uint32_t round_up_to_power_of_2 (uint32_t a) noexcept {
110
110
return increment (or_equal (decrement (a), 1 , 2 , 4 , 8 , 16 ));
111
111
}
112
112
113
- constexpr uint64_t round_up_to_power_of_2 (uint64_t a) noexcept {
113
+ ATOMIC_QUEUE_INLINE static constexpr uint64_t round_up_to_power_of_2 (uint64_t a) noexcept {
114
114
return increment (or_equal (decrement (a), 1 , 2 , 4 , 8 , 16 , 32 ));
115
115
}
116
116
@@ -125,11 +125,23 @@ constexpr T nil() noexcept {
125
125
}
126
126
127
127
template <class T >
128
- inline void destroy_n (T* p, unsigned n) noexcept {
128
+ ATOMIC_QUEUE_INLINE static void destroy_n (T* p, unsigned n) noexcept {
129
129
for (auto q = p + n; p != q;)
130
130
(p++)->~T ();
131
131
}
132
132
133
+ template <class T >
134
+ ATOMIC_QUEUE_INLINE static void swap_relaxed (std::atomic<T>& a, std::atomic<T>& b) noexcept {
135
+ auto a2 = a.load (X);
136
+ a.store (b.load (X), X);
137
+ b.store (a2, X);
138
+ }
139
+
140
+ template <class T >
141
+ ATOMIC_QUEUE_INLINE static void copy_relaxed (std::atomic<T>& a, std::atomic<T> const & b) noexcept {
142
+ a.store (b.load (X), X);
143
+ }
144
+
133
145
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
134
146
135
147
} // namespace details
@@ -152,18 +164,15 @@ class AtomicQueueCommon {
152
164
, tail_(b.tail_.load(X)) {}
153
165
154
166
AtomicQueueCommon& operator =(AtomicQueueCommon const & b) noexcept {
155
- head_. store (b. head_ . load (X), X );
156
- tail_. store (b. tail_ . load (X), X );
167
+ details::copy_relaxed ( head_, b. head_ );
168
+ details::copy_relaxed ( tail_, b. tail_ );
157
169
return *this ;
158
170
}
159
171
172
+ // Relatively semi-special swap is not thread-safe either.
160
173
void swap (AtomicQueueCommon& b) noexcept {
161
- unsigned h = head_.load (X);
162
- unsigned t = tail_.load (X);
163
- head_.store (b.head_ .load (X), X);
164
- tail_.store (b.tail_ .load (X), X);
165
- b.head_ .store (h, X);
166
- b.tail_ .store (t, X);
174
+ details::swap_relaxed (head_, b.head_ );
175
+ details::swap_relaxed (tail_, b.tail_ );
167
176
}
168
177
169
178
template <class T , T NIL>
0 commit comments