66
77#include < atomic>
88
9+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10+
11+ // Define a CPU-specific spin_loop_pause function.
12+ // "static inline" documentation: https://gcc.gnu.org/onlinedocs/gcc/Inline.html
13+
914#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
1015#include < emmintrin.h>
16+ #endif
17+
1118namespace atomic_queue {
19+
20+ #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
1221constexpr int CACHE_LINE_SIZE = 64 ;
1322static inline void spin_loop_pause () noexcept {
1423 _mm_pause ();
1524}
16- } // namespace atomic_queue
25+
1726#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64)
18- namespace atomic_queue {
1927constexpr int CACHE_LINE_SIZE = 64 ;
2028static inline void spin_loop_pause () noexcept {
2129#if (defined(__ARM_ARCH_6K__) || \
@@ -36,52 +44,42 @@ static inline void spin_loop_pause() noexcept {
3644 asm volatile (" nop" ::: " memory" );
3745#endif
3846}
39- } // namespace atomic_queue
47+
4048#elif defined(__ppc64__) || defined(__powerpc64__)
41- namespace atomic_queue {
4249constexpr int CACHE_LINE_SIZE = 128 ; // TODO: Review that this is the correct value.
4350static inline void spin_loop_pause () noexcept {
4451 asm volatile (" or 31,31,31 # very low priority" ); // TODO: Review and benchmark that this is the right instruction.
4552}
46- } // namespace atomic_queue
53+
4754#elif defined(__s390x__)
48- namespace atomic_queue {
4955constexpr int CACHE_LINE_SIZE = 256 ; // TODO: Review that this is the correct value.
5056static inline void spin_loop_pause () noexcept {} // TODO: Find the right instruction to use here, if any.
51- } // namespace atomic_queue
57+
5258#elif defined(__riscv)
53- namespace atomic_queue {
5459constexpr int CACHE_LINE_SIZE = 64 ;
5560static inline void spin_loop_pause () noexcept {
5661 asm volatile (" .insn i 0x0F, 0, x0, x0, 0x010" );
5762}
58- } // namespace atomic_queue
63+
5964#elif defined(__loongarch__)
60- namespace atomic_queue {
6165constexpr int CACHE_LINE_SIZE = 64 ;
62- static inline void spin_loop_pause () noexcept
63- {
66+ static inline void spin_loop_pause () noexcept {
6467 asm volatile (" nop \n nop \n nop \n nop \n nop \n nop \n nop \n nop" );
6568}
66- } // namespace atomic_queue
69+
6770#else
6871#ifdef _MSC_VER
6972#pragma message("Unknown CPU architecture. Using L1 cache line size of 64 bytes and no spinloop pause instruction.")
7073#else
7174#warning "Unknown CPU architecture. Using L1 cache line size of 64 bytes and no spinloop pause instruction."
7275#endif
73- namespace atomic_queue {
76+
7477constexpr int CACHE_LINE_SIZE = 64 ; // TODO: Review that this is the correct value.
7578static inline void spin_loop_pause () noexcept {}
76- } // namespace atomic_queue
7779#endif
7880
7981// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8082
81- namespace atomic_queue {
82-
83- // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84-
8583auto constexpr A = std::memory_order_acquire;
8684auto constexpr R = std::memory_order_release;
8785auto constexpr X = std::memory_order_relaxed;
0 commit comments