@@ -33,18 +33,29 @@ _STL_DISABLE_CLANG_WARNINGS
33
33
#pragma clang attribute _STD_ATOMIC_HEADER.push([[gnu::target("cx16")]], apply_to = function)
34
34
#endif // ^^^ defined(__clang__) && defined(_M_X64) ^^^
35
35
36
- // Controls whether ARM64 ldar/ldapr/stlr should be used
37
- #ifndef _STD_ATOMIC_USE_ARM64_LDAR_STLR
38
36
#if defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)
39
- #ifdef __clang__ // TRANSITION, LLVM-62103
40
- #define _STD_ATOMIC_USE_ARM64_LDAR_STLR 0
41
- #else // ^^^ Clang doesn't support new intrinsics / __load_acquire/__stlr intrinsics are available vvv
42
37
#define _STD_ATOMIC_USE_ARM64_LDAR_STLR 1
43
- #endif // ^^^ __load_acquire/__stlr intrinsics are available ^^^
38
+ #ifdef __clang__
39
+ #define __LOAD_ACQUIRE_ARM64(_Width, _Ptr) \
40
+ static_cast<__int##_Width>(__atomic_load_n(reinterpret_cast<const volatile unsigned __int##_Width*>(_Ptr), 2))
41
+ #define __STORE_RELEASE(_Width, _Ptr, _Desired) \
42
+ _Compiler_barrier(); \
43
+ __atomic_store_n( \
44
+ reinterpret_cast<volatile unsigned __int##_Width*>(_Ptr), static_cast<unsigned __int##_Width>(_Desired), 3)
45
+ #else // ^^^ Clang / MSVC vvv
46
+ #define __LOAD_ACQUIRE_ARM64(_Width, _Ptr) \
47
+ static_cast<__int##_Width>(__load_acquire##_Width(reinterpret_cast<const volatile unsigned __int##_Width*>(_Ptr)))
48
+ #define __STORE_RELEASE(_Width, _Ptr, _Desired) \
49
+ _Compiler_barrier(); \
50
+ __stlr##_Width( \
51
+ reinterpret_cast<volatile unsigned __int##_Width*>(_Ptr), static_cast<unsigned __int##_Width>(_Desired))
52
+ #endif // ^^^ MSVC ^^^
44
53
#else // ^^^ ARM64/ARM64EC/HYBRID_X86_ARM64 / Other architectures vvv
45
54
#define _STD_ATOMIC_USE_ARM64_LDAR_STLR 0
55
+ #define __STORE_RELEASE(_Width, _Ptr, _Desired) \
56
+ _Compiler_or_memory_barrier(); \
57
+ __iso_volatile_store##_Width((_Ptr), (_Desired))
46
58
#endif // ^^^ Other architectures ^^^
47
- #endif // _STD_ATOMIC_USE_ARM64_LDAR_STLR
48
59
49
60
#define ATOMIC_BOOL_LOCK_FREE 2
50
61
#define ATOMIC_CHAR_LOCK_FREE 2
@@ -122,9 +133,6 @@ extern "C" inline void _Check_memory_order(const unsigned int _Order) noexcept {
122
133
123
134
#if _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1
124
135
125
- #define __LOAD_ACQUIRE_ARM64(_Width, _Ptr) \
126
- static_cast<__int##_Width>(__load_acquire##_Width(reinterpret_cast<const volatile unsigned __int##_Width*>(_Ptr)))
127
-
128
136
#define _ATOMIC_LOAD_ARM64(_Result, _Width, _Ptr, _Order_var) \
129
137
switch (_Order_var) { \
130
138
case _Atomic_memory_order_relaxed: \
@@ -162,27 +170,12 @@ extern "C" inline void _Check_memory_order(const unsigned int _Order) noexcept {
162
170
break; \
163
171
}
164
172
165
- #if _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1
166
-
167
- #define __STORE_RELEASE(_Width, _Ptr, _Desired) \
168
- _Compiler_barrier(); \
169
- __stlr##_Width( \
170
- reinterpret_cast<volatile unsigned __int##_Width*>(_Ptr), static_cast<unsigned __int##_Width>(_Desired));
171
-
172
- #else // ^^^ _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1 / _STD_ATOMIC_USE_ARM64_LDAR_STLR == 0 vvv
173
-
174
- #define __STORE_RELEASE(_Width, _Ptr, _Desired) \
175
- _Compiler_or_memory_barrier(); \
176
- __iso_volatile_store##_Width((_Ptr), (_Desired));
177
-
178
- #endif // ^^^ _STD_ATOMIC_USE_ARM64_LDAR_STLR == 0 ^^^
179
-
180
173
#define _ATOMIC_STORE_PREFIX(_Width, _Ptr, _Desired) \
181
174
case _Atomic_memory_order_relaxed: \
182
175
__iso_volatile_store##_Width((_Ptr), (_Desired)); \
183
176
return; \
184
177
case _Atomic_memory_order_release: \
185
- __STORE_RELEASE(_Width, _Ptr, _Desired) \
178
+ __STORE_RELEASE(_Width, _Ptr, _Desired); \
186
179
return; \
187
180
default: \
188
181
case _Atomic_memory_order_consume: \
@@ -196,15 +189,9 @@ extern "C" inline void _Check_memory_order(const unsigned int _Order) noexcept {
196
189
__iso_volatile_store##_Width((_Ptr), (_Desired)); \
197
190
_Memory_barrier();
198
191
199
- #if _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1
200
- #define _ATOMIC_STORE_SEQ_CST_ARM64(_Width, _Ptr, _Desired) \
201
- _Compiler_barrier(); \
202
- __stlr##_Width( \
203
- reinterpret_cast<volatile unsigned __int##_Width*>(_Ptr), static_cast<unsigned __int##_Width>(_Desired)); \
192
+ #define _ATOMIC_STORE_SEQ_CST_ARM64(_Width, _Ptr, _Desired) \
193
+ __STORE_RELEASE(_Width, _Ptr, _Desired); \
204
194
_Memory_barrier();
205
- #else // ^^^ _STD_ATOMIC_USE_ARM64_LDAR_STLR == 1 / _STD_ATOMIC_USE_ARM64_LDAR_STLR == 0 vvv
206
- #define _ATOMIC_STORE_SEQ_CST_ARM64 _ATOMIC_STORE_SEQ_CST_ARM
207
- #endif // ^^^ _STD_ATOMIC_USE_ARM64_LDAR_STLR == 0 ^^^
208
195
209
196
#define _ATOMIC_STORE_SEQ_CST_X86_X64(_Width, _Ptr, _Desired) (void) _InterlockedExchange##_Width((_Ptr), (_Desired));
210
197
#define _ATOMIC_STORE_32_SEQ_CST_X86_X64(_Ptr, _Desired) \
@@ -257,7 +244,11 @@ extern "C" inline void _Atomic_thread_fence(const unsigned int _Order) noexcept
257
244
_Compiler_barrier();
258
245
}
259
246
#elif defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)
260
- _Memory_barrier();
247
+ if (_Order == _Atomic_memory_order_acquire || _Order == _Atomic_memory_order_consume) {
248
+ _Memory_load_acquire_barrier();
249
+ } else {
250
+ _Memory_barrier();
251
+ }
261
252
#else // ^^^ ARM32/ARM64/ARM64EC/HYBRID_X86_ARM64 / unsupported hardware vvv
262
253
#error Unsupported hardware
263
254
#endif // ^^^ unsupported hardware ^^^
@@ -519,7 +510,7 @@ inline void _Atomic_lock_acquire(long& _Spinlock) noexcept {
519
510
}
520
511
}
521
512
#elif defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)
522
- while (_InterlockedExchange (&_Spinlock, 1) != 0) { // TRANSITION, GH-1133: _InterlockedExchange_acq
513
+ while (_InterlockedExchange_acq (&_Spinlock, 1) != 0) {
523
514
while (__iso_volatile_load32(&reinterpret_cast<int&>(_Spinlock)) != 0) {
524
515
__yield();
525
516
}
@@ -530,15 +521,7 @@ inline void _Atomic_lock_acquire(long& _Spinlock) noexcept {
530
521
}
531
522
532
523
inline void _Atomic_lock_release(long& _Spinlock) noexcept {
533
- #if (defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64)) || (defined(_M_X64) && !defined(_M_ARM64EC))
534
- _InterlockedExchange(&_Spinlock, 0); // TRANSITION, GH-1133: same as ARM
535
- #elif defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64)
536
- _Memory_barrier();
537
- __iso_volatile_store32(reinterpret_cast<int*>(&_Spinlock), 0);
538
- _Memory_barrier(); // TRANSITION, GH-1133: remove
539
- #else // ^^^ defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) ^^^
540
- #error Unsupported hardware
541
- #endif
524
+ __STORE_RELEASE(32, reinterpret_cast<int*>(&_Spinlock), 0);
542
525
}
543
526
544
527
inline void _Atomic_lock_acquire(_Smtx_t* _Spinlock) noexcept {
0 commit comments