@@ -176,7 +176,7 @@ class AtomicQueueCommon {
176
176
}
177
177
178
178
template <class T , T NIL>
179
- static T do_pop_atomic (std::atomic<T>& q_element) noexcept {
179
+ ATOMIC_QUEUE_INLINE static T do_pop_atomic (std::atomic<T>& q_element) noexcept {
180
180
if (Derived::spsc_) {
181
181
for (;;) {
182
182
T element = q_element.load (A);
@@ -202,7 +202,7 @@ class AtomicQueueCommon {
202
202
}
203
203
204
204
template <class T , T NIL>
205
- static void do_push_atomic (T element, std::atomic<T>& q_element) noexcept {
205
+ ATOMIC_QUEUE_INLINE static void do_push_atomic (T element, std::atomic<T>& q_element) noexcept {
206
206
assert (element != NIL);
207
207
if (Derived::spsc_) {
208
208
while (ATOMIC_QUEUE_UNLIKELY (q_element.load (X) != NIL))
@@ -222,7 +222,7 @@ class AtomicQueueCommon {
222
222
enum State : unsigned char { EMPTY, STORING, STORED, LOADING };
223
223
224
224
template <class T >
225
- static T do_pop_any (std::atomic<unsigned char >& state, T& q_element) noexcept {
225
+ ATOMIC_QUEUE_INLINE static T do_pop_any (std::atomic<unsigned char >& state, T& q_element) noexcept {
226
226
if (Derived::spsc_) {
227
227
while (ATOMIC_QUEUE_UNLIKELY (state.load (A) != STORED))
228
228
if (Derived::maximize_throughput_)
@@ -248,7 +248,7 @@ class AtomicQueueCommon {
248
248
}
249
249
250
250
template <class U , class T >
251
- static void do_push_any (U&& element, std::atomic<unsigned char >& state, T& q_element) noexcept {
251
+ ATOMIC_QUEUE_INLINE static void do_push_any (U&& element, std::atomic<unsigned char >& state, T& q_element) noexcept {
252
252
if (Derived::spsc_) {
253
253
while (ATOMIC_QUEUE_UNLIKELY (state.load (A) != EMPTY))
254
254
if (Derived::maximize_throughput_)
@@ -274,7 +274,7 @@ class AtomicQueueCommon {
274
274
275
275
public:
276
276
template <class T >
277
- bool try_push (T&& element) noexcept {
277
+ ATOMIC_QUEUE_INLINE bool try_push (T&& element) noexcept {
278
278
auto head = head_.load (X);
279
279
if (Derived::spsc_) {
280
280
if (static_cast <int >(head - tail_.load (X)) >= static_cast <int >(static_cast <Derived&>(*this ).size_ ))
@@ -293,7 +293,7 @@ class AtomicQueueCommon {
293
293
}
294
294
295
295
template <class T >
296
- bool try_pop (T& element) noexcept {
296
+ ATOMIC_QUEUE_INLINE bool try_pop (T& element) noexcept {
297
297
auto tail = tail_.load (X);
298
298
if (Derived::spsc_) {
299
299
if (static_cast <int >(head_.load (X) - tail) <= 0 )
@@ -312,7 +312,7 @@ class AtomicQueueCommon {
312
312
}
313
313
314
314
template <class T >
315
- void push (T&& element) noexcept {
315
+ ATOMIC_QUEUE_INLINE void push (T&& element) noexcept {
316
316
unsigned head;
317
317
if (Derived::spsc_) {
318
318
head = head_.load (X);
@@ -325,7 +325,7 @@ class AtomicQueueCommon {
325
325
static_cast <Derived&>(*this ).do_push (std::forward<T>(element), head);
326
326
}
327
327
328
- auto pop () noexcept {
328
+ ATOMIC_QUEUE_INLINE auto pop () noexcept {
329
329
unsigned tail;
330
330
if (Derived::spsc_) {
331
331
tail = tail_.load (X);
@@ -338,21 +338,21 @@ class AtomicQueueCommon {
338
338
return static_cast <Derived&>(*this ).do_pop (tail);
339
339
}
340
340
341
- bool was_empty () const noexcept {
341
+ ATOMIC_QUEUE_INLINE bool was_empty () const noexcept {
342
342
return !was_size ();
343
343
}
344
344
345
- bool was_full () const noexcept {
345
+ ATOMIC_QUEUE_INLINE bool was_full () const noexcept {
346
346
return was_size () >= capacity ();
347
347
}
348
348
349
- unsigned was_size () const noexcept {
349
+ ATOMIC_QUEUE_INLINE unsigned was_size () const noexcept {
350
350
// tail_ can be greater than head_ because of consumers doing pop, rather that try_pop, when the queue is empty.
351
351
unsigned n{head_.load (X) - tail_.load (X)};
352
352
return static_cast <int >(n) < 0 ? 0 : n; // Windows headers break std::min/max by default. Do std::max<int>(n, 0) the hard way here.
353
353
}
354
354
355
- unsigned capacity () const noexcept {
355
+ ATOMIC_QUEUE_INLINE unsigned capacity () const noexcept {
356
356
return static_cast <Derived const &>(*this ).size_ ;
357
357
}
358
358
};
@@ -372,12 +372,12 @@ class AtomicQueue : public AtomicQueueCommon<AtomicQueue<T, SIZE, NIL, MINIMIZE_
372
372
373
373
alignas (CACHE_LINE_SIZE) std::atomic<T> elements_[size_];
374
374
375
- T do_pop (unsigned tail) noexcept {
375
+ ATOMIC_QUEUE_INLINE T do_pop (unsigned tail) noexcept {
376
376
std::atomic<T>& q_element = details::map<SHUFFLE_BITS>(elements_, tail % size_);
377
377
return Base::template do_pop_atomic<T, NIL>(q_element);
378
378
}
379
379
380
- void do_push (T element, unsigned head) noexcept {
380
+ ATOMIC_QUEUE_INLINE void do_push (T element, unsigned head) noexcept {
381
381
std::atomic<T>& q_element = details::map<SHUFFLE_BITS>(elements_, head % size_);
382
382
Base::template do_push_atomic<T, NIL>(element, q_element);
383
383
}
@@ -412,13 +412,13 @@ class AtomicQueue2 : public AtomicQueueCommon<AtomicQueue2<T, SIZE, MINIMIZE_CON
412
412
alignas (CACHE_LINE_SIZE) std::atomic<unsigned char> states_[size_] = {};
413
413
alignas (CACHE_LINE_SIZE) T elements_[size_] = {};
414
414
415
- T do_pop (unsigned tail) noexcept {
415
+ ATOMIC_QUEUE_INLINE T do_pop (unsigned tail) noexcept {
416
416
unsigned index = details::remap_index<SHUFFLE_BITS>(tail % size_);
417
417
return Base::do_pop_any (states_[index], elements_[index]);
418
418
}
419
419
420
420
template <class U >
421
- void do_push (U&& element, unsigned head) noexcept {
421
+ ATOMIC_QUEUE_INLINE void do_push (U&& element, unsigned head) noexcept {
422
422
unsigned index = details::remap_index<SHUFFLE_BITS>(head % size_);
423
423
Base::do_push_any (std::forward<U>(element), states_[index], elements_[index]);
424
424
}
@@ -455,12 +455,12 @@ class AtomicQueueB : private std::allocator_traits<A>::template rebind_alloc<std
455
455
alignas (CACHE_LINE_SIZE) unsigned size_;
456
456
std::atomic<T>* elements_;
457
457
458
- T do_pop (unsigned tail) noexcept {
458
+ ATOMIC_QUEUE_INLINE T do_pop (unsigned tail) noexcept {
459
459
std::atomic<T>& q_element = details::map<SHUFFLE_BITS>(elements_, tail & (size_ - 1 ));
460
460
return Base::template do_pop_atomic<T, NIL>(q_element);
461
461
}
462
462
463
- void do_push (T element, unsigned head) noexcept {
463
+ ATOMIC_QUEUE_INLINE void do_push (T element, unsigned head) noexcept {
464
464
std::atomic<T>& q_element = details::map<SHUFFLE_BITS>(elements_, head & (size_ - 1 ));
465
465
Base::template do_push_atomic<T, NIL>(element, q_element);
466
466
}
@@ -543,13 +543,13 @@ class AtomicQueueB2 : private std::allocator_traits<A>::template rebind_alloc<un
543
543
static constexpr auto SHUFFLE_BITS = details::GetCacheLineIndexBits<STATES_PER_CACHE_LINE>::value;
544
544
static_assert (SHUFFLE_BITS, " Unexpected SHUFFLE_BITS." );
545
545
546
- T do_pop (unsigned tail) noexcept {
546
+ ATOMIC_QUEUE_INLINE T do_pop (unsigned tail) noexcept {
547
547
unsigned index = details::remap_index<SHUFFLE_BITS>(tail & (size_ - 1 ));
548
548
return Base::do_pop_any (states_[index], elements_[index]);
549
549
}
550
550
551
551
template <class U >
552
- void do_push (U&& element, unsigned head) noexcept {
552
+ ATOMIC_QUEUE_INLINE void do_push (U&& element, unsigned head) noexcept {
553
553
unsigned index = details::remap_index<SHUFFLE_BITS>(head & (size_ - 1 ));
554
554
Base::do_push_any (std::forward<U>(element), states_[index], elements_[index]);
555
555
}
@@ -634,12 +634,12 @@ struct RetryDecorator : Queue {
634
634
635
635
using Queue::Queue;
636
636
637
- void push (T element) noexcept {
637
+ ATOMIC_QUEUE_INLINE void push (T element) noexcept {
638
638
while (!this ->try_push (element))
639
639
spin_loop_pause ();
640
640
}
641
641
642
- T pop () noexcept {
642
+ ATOMIC_QUEUE_INLINE T pop () noexcept {
643
643
T element;
644
644
while (!this ->try_pop (element))
645
645
spin_loop_pause ();
0 commit comments