1#ifndef NEFORCE_CORE_ASYNC_ATOMIC_BASE_HPP__
2#define NEFORCE_CORE_ASYNC_ATOMIC_BASE_HPP__
14#ifdef NEFORCE_COMPILER_MSVC
17#ifdef NEFORCE_COMPILER_CLANG_CL
18# include <intrin0.inl.h>
20NEFORCE_BEGIN_NAMESPACE__
34#ifdef NEFORCE_COMPILER_MSVC
36# pragma warning(disable : 6001)
46#ifdef NEFORCE_COMPILER_MSVC
50# ifdef NEFORCE_ARCH_ARM
52 ::__dmb(::_ARM64_BARRIER_ISHLD);
54 ::__dmb(::_ARM64_BARRIER_ISH);
57 ::_ReadWriteBarrier();
64 ::_InterlockedIncrement(&guard);
65 ::_ReadWriteBarrier();
69 __atomic_thread_fence(
static_cast<int32_t>(mo));
73#ifdef NEFORCE_COMPILER_MSVC
84#ifdef NEFORCE_COMPILER_MSVC
86 ::_ReadWriteBarrier();
89 __atomic_signal_fence(
static_cast<int32_t>(mo));
98struct atomic_load_verifier {
100 static void verify(
const volatile T* , remove_volatile_t<T>& )
noexcept {}
103#ifdef NEFORCE_COMPILER_MSVC
105template <
size_t Size>
106struct interlocked_exchange_impl;
109struct interlocked_exchange_impl<1> {
110 template <
typename T>
111 static T call(
volatile T* target, T value) {
112 return static_cast<T
>(
113 ::_InterlockedExchange8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
117struct interlocked_exchange_impl<2> {
118 template <
typename T>
119 static T call(
volatile T* target, T value) {
120 return static_cast<T
>(
121 ::_InterlockedExchange16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
125struct interlocked_exchange_impl<4> {
126 template <
typename T>
127 static T call(
volatile T* target, T value) {
128 return static_cast<T
>(
129 ::_InterlockedExchange(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
133struct interlocked_exchange_impl<8> {
134 template <
typename T>
135 static T call(
volatile T* target, T value) {
136# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
137 return static_cast<T
>(
138 ::_InterlockedExchange64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
140 return static_cast<T
>(
141 ::_interlockedexchange64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
146template <
size_t Size>
147struct interlocked_compare_exchange_impl;
150struct interlocked_compare_exchange_impl<1> {
151 template <
typename T>
152 static bool call(
volatile T* target, T* expected, T desired) {
154 ::_InterlockedCompareExchange8(
reinterpret_cast<volatile char*
>(target),
155 *
reinterpret_cast<char*
>(&desired), *
reinterpret_cast<char*
>(expected));
156 if (old == *
reinterpret_cast<char*
>(expected)) {
159 *
reinterpret_cast<char*
>(expected) = old;
164struct interlocked_compare_exchange_impl<2> {
165 template <
typename T>
166 static bool call(
volatile T* target, T* expected, T desired) {
167 const short old = ::_InterlockedCompareExchange16(
reinterpret_cast<volatile short*
>(target),
168 *
reinterpret_cast<short*
>(&desired),
169 *
reinterpret_cast<short*
>(expected));
170 if (old == *
reinterpret_cast<short*
>(expected)) {
173 *
reinterpret_cast<short*
>(expected) = old;
178struct interlocked_compare_exchange_impl<4> {
179 template <
typename T>
180 static bool call(
volatile T* target, T* expected, T desired) {
182 ::_InterlockedCompareExchange(
reinterpret_cast<volatile long*
>(target),
183 *
reinterpret_cast<long*
>(&desired), *
reinterpret_cast<long*
>(expected));
184 if (old == *
reinterpret_cast<long*
>(expected)) {
187 *
reinterpret_cast<long*
>(expected) = old;
192struct interlocked_compare_exchange_impl<8> {
193 template <
typename T>
194 static bool call(
volatile T* target, T* expected, T desired) {
195 const long long old = ::_InterlockedCompareExchange64(
reinterpret_cast<volatile long long*
>(target),
196 *
reinterpret_cast<long long*
>(&desired),
197 *
reinterpret_cast<long long*
>(expected));
198 if (old == *
reinterpret_cast<long long*
>(expected)) {
201 *
reinterpret_cast<long long*
>(expected) = old;
206struct interlocked_compare_exchange_impl<16> {
207# if !(defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_ARCH_AARCH64))
209 struct futex_lock_128 {
210 alignas(64)
volatile platform_wait_t state_ = 0;
212 static futex_lock_128& for_addr(
const void* addr)
noexcept {
214 static futex_lock_128 pool[pool_size];
215 return pool[(
reinterpret_cast<uintptr_t>(addr) >> 4) % pool_size];
218 void lock(
const void* )
noexcept {
220 if (::_InterlockedCompareExchange(&state_, 1, 0) == 0) {
224 [
this] { return ::_InterlockedExchangeAdd(&state_, 0); });
228 void unlock(
const void* )
noexcept {
229 ::_InterlockedExchange(&state_, 0);
235 template <
typename T>
236 static bool call(
volatile T* target, T* expected, T desired) {
237 alignas(16)
long long exp_arr[2];
238 alignas(16)
long long des_arr[2];
243# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_ARCH_AARCH64)
244 result = ::_InterlockedCompareExchange128(
reinterpret_cast<volatile long long*
>(target), des_arr[1], des_arr[0],
247 auto& flock = futex_lock_128::for_addr(target);
249 if (_NEFORCE
memory_compare(
const_cast<T*
>(target), exp_arr, 16) == 0) {
250 _NEFORCE
memory_copy(
const_cast<T*
>(target), des_arr, 16);
251 flock.unlock(target);
254 _NEFORCE
memory_copy(exp_arr,
const_cast<T*
>(target), 16);
255 flock.unlock(target);
267template <
size_t Size>
268struct interlocked_fetch_add_impl;
271struct interlocked_fetch_add_impl<1> {
272 template <
typename T>
273 static T call(
volatile T* target, T value) {
274 return static_cast<T
>(
275 ::_InterlockedExchangeAdd8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
279struct interlocked_fetch_add_impl<2> {
280 template <
typename T>
281 static T call(
volatile T* target, T value) {
282 return static_cast<T
>(
283 ::_InterlockedExchangeAdd16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
287struct interlocked_fetch_add_impl<4> {
288 template <
typename T>
289 static T call(
volatile T* target, T value) {
290 return static_cast<T
>(
291 ::_InterlockedExchangeAdd(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
295struct interlocked_fetch_add_impl<8> {
296 template <
typename T>
297 static T call(
volatile T* target, T value) {
298# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
299 return static_cast<T
>(::_InterlockedExchangeAdd64(
reinterpret_cast<volatile long long*
>(target),
300 static_cast<long long>(value)));
302 return static_cast<T
>(::_interlockedexchangeadd64(
reinterpret_cast<volatile long long*
>(target),
303 static_cast<long long>(value)));
308template <
size_t Size>
309struct interlocked_fetch_and_impl;
312struct interlocked_fetch_and_impl<1> {
313 template <
typename T>
314 static T call(
volatile T* target, T value) {
315 return static_cast<T
>(::_InterlockedAnd8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
319struct interlocked_fetch_and_impl<2> {
320 template <
typename T>
321 static T call(
volatile T* target, T value) {
322 return static_cast<T
>(
323 ::_InterlockedAnd16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
327struct interlocked_fetch_and_impl<4> {
328 template <
typename T>
329 static T call(
volatile T* target, T value) {
330 return static_cast<T
>(::_InterlockedAnd(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
334struct interlocked_fetch_and_impl<8> {
335 template <
typename T>
336 static T call(
volatile T* target, T value) {
337# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
338 return static_cast<T
>(
339 ::_InterlockedAnd64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
341 return static_cast<T
>(
342 ::_interlockedadd64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
347template <
size_t Size>
348struct interlocked_fetch_or_impl;
351struct interlocked_fetch_or_impl<1> {
352 template <
typename T>
353 static T call(
volatile T* target, T value) {
354 return static_cast<T
>(::_InterlockedOr8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
358struct interlocked_fetch_or_impl<2> {
359 template <
typename T>
360 static T call(
volatile T* target, T value) {
361 return static_cast<T
>(::_InterlockedOr16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
365struct interlocked_fetch_or_impl<4> {
366 template <
typename T>
367 static T call(
volatile T* target, T value) {
368 return static_cast<T
>(::_InterlockedOr(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
372struct interlocked_fetch_or_impl<8> {
373 template <
typename T>
374 static T call(
volatile T* target, T value) {
375# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
376 return static_cast<T
>(
377 ::_InterlockedOr64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
379 return static_cast<T
>(
380 ::_interlockedor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
385template <
size_t Size>
386struct interlocked_fetch_xor_impl;
389struct interlocked_fetch_xor_impl<1> {
390 template <
typename T>
391 static T call(
volatile T* target, T value) {
392 return static_cast<T
>(::_InterlockedXor8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
396struct interlocked_fetch_xor_impl<2> {
397 template <
typename T>
398 static T call(
volatile T* target, T value) {
399 return static_cast<T
>(
400 ::_InterlockedXor16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
404struct interlocked_fetch_xor_impl<4> {
405 template <
typename T>
406 static T call(
volatile T* target, T value) {
407 return static_cast<T
>(::_InterlockedXor(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
411struct interlocked_fetch_xor_impl<8> {
412 template <
typename T>
413 static T call(
volatile T* target, T value) {
414# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
415 return static_cast<T
>(
416 ::_InterlockedXor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
418 return static_cast<T
>(
419 ::_interlockedxor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
424template <
size_t Size>
425struct atomic_is_always_lock_free_impl {
426 static constexpr bool value =
false;
429struct atomic_is_always_lock_free_impl<1> {
430 static constexpr bool value =
true;
433struct atomic_is_always_lock_free_impl<2> {
434 static constexpr bool value =
true;
437struct atomic_is_always_lock_free_impl<4> {
438 static constexpr bool value =
true;
441struct atomic_is_always_lock_free_impl<8> {
442 static constexpr bool value =
true;
445struct atomic_is_always_lock_free_impl<16> {
446# if defined(NEFORCE_ARCH_X86_64) || defined(NEFORCE_ARCH_AARCH64)
447 static constexpr bool value =
true;
449 static constexpr bool value =
false;
454struct atomic_load_verifier<16> {
455 template <
typename T>
456 static void verify(
const volatile T* target, remove_volatile_t<T>& result)
noexcept {
457 _NEFORCE
memory_copy(&result,
const_cast<const T*
>(target), 16);
458 auto* mutable_target =
const_cast<volatile T*
>(target);
459 interlocked_compare_exchange_impl<16>::call(mutable_target, &result, result);
488#ifdef NEFORCE_COMPILER_GNUC
489 __atomic_store_n(ptr, value,
static_cast<int32_t>(mo));
491 inner::interlocked_exchange_impl<
sizeof(T)>::call(ptr, value);
493 ::_ReadWriteBarrier();
509#ifdef NEFORCE_COMPILER_GNUC
510 return __atomic_load_n(ptr,
static_cast<int32_t>(mo));
514 ::_ReadWriteBarrier();
533#ifdef NEFORCE_COMPILER_GNUC
534 return __atomic_exchange_n(ptr, value,
static_cast<int32_t>(mo));
538 ::_ReadWriteBarrier();
562#ifdef NEFORCE_COMPILER_GNUC
563 return __atomic_compare_exchange_n(ptr, expected, desired,
true,
static_cast<int32_t>(
success),
564 static_cast<int32_t>(failure));
566# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
567 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, desired);
569 ::_ReadWriteBarrier();
576# if defined(NEFORCE_ARCH_ARM)
577 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 1) {
578 asm volatile(
"ldrexb %[loaded], [%[ptr]]\n\t"
579 "cmp %[loaded], %[old_val]\n\t"
581 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
583 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
584 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
587 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 2) {
588 asm volatile(
"ldrexh %[loaded], [%[ptr]]\n\t"
589 "cmp %[loaded], %[old_val]\n\t"
591 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
593 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
594 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
597 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
598 asm volatile(
"ldrex %[loaded], [%[ptr]]\n\t"
599 "cmp %[loaded], %[old_val]\n\t"
601 "strex %w[success], %w[desired], [%[ptr]]\n\t"
603 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
604 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
607 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
615 "ldrexd %[lo], %[hi], [%[ptr]]\n\t"
616 "cmp %[lo], %[old_lo]\n\t"
617 "cmpeq %[hi], %[old_hi]\n\t"
619 "strexd %[success], %[des_lo], %[des_hi], [%[ptr]]\n\t"
621 : [lo]
"=&r"(loaded_lo), [hi]
"=&r"(loaded_hi), [
success]
"=&r"(tmp_success)
622 : [ptr]
"r"(ptr), [old_lo]
"r"(old_lo), [old_hi]
"r"(old_hi), [des_lo]
"r"(des_lo), [des_hi]
"r"(des_hi)
624 loaded =
static_cast<T
>(
static_cast<uint64_t>(loaded_lo) | (
static_cast<uint64_t>(loaded_hi) << 32));
625 success_flag = (tmp_success == 0);
626 if (loaded != old_val) {
632# elif defined(NEFORCE_ARCH_RISCV)
633 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
634 asm volatile(
"lr.w %[loaded], (%[ptr])\n\t"
635 "bne %[loaded], %[old_val], 1f\n\t"
636 "sc.w %[success], %[desired], (%[ptr])\n\t"
638 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
639 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
642 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
643 asm volatile(
"lr.d %[loaded], (%[ptr])\n\t"
644 "bne %[loaded], %[old_val], 1f\n\t"
645 "sc.d %[success], %[desired], (%[ptr])\n\t"
647 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
648 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
651# elif defined(NEFORCE_ARCH_LOONGARCH)
652 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
655 asm volatile(
"ll.w %[loaded], %[ptr]\n\t"
656 "bne %[loaded], %[old_val], 1f\n\t"
657 "sc.w %[des_copy], %[ptr]\n\t"
659 "move %[success], %[des_copy]\n\t"
660 : [loaded]
"=&r"(loaded), [des_copy]
"+r"(des_copy), [
success]
"=r"(sc_result)
661 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val)
663 success_flag = (sc_result == 0);
665 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
666 asm volatile(
"ll.d %[loaded], %[ptr]\n\t"
667 "bne %[loaded], %[old_val], 1f\n\t"
668 "sc.d %[desired], %[ptr]\n\t"
669 "move %[success], %[desired]\n\t"
671 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
672 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
676 if (loaded != old_val) {
680 return success_flag == 0;
703#ifdef NEFORCE_COMPILER_GNUC
704 return __atomic_compare_exchange_n(ptr, expected, desired,
false,
static_cast<int32_t>(
success),
705 static_cast<int32_t>(failure));
707# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
715 if (*expected != old_val) {
736#ifdef NEFORCE_COMPILER_GNUC
737 return __atomic_fetch_add(ptr, value,
static_cast<int32_t>(mo));
741 ::_ReadWriteBarrier();
760#ifdef NEFORCE_COMPILER_GNUC
761 return __atomic_fetch_sub(ptr, value,
static_cast<int32_t>(mo));
780#ifdef NEFORCE_COMPILER_GNUC
781 return __atomic_fetch_and(ptr, value,
static_cast<int32_t>(mo));
785 ::_ReadWriteBarrier();
804#ifdef NEFORCE_COMPILER_GNUC
805 return __atomic_fetch_or(ptr, value,
static_cast<int32_t>(mo));
809 ::_ReadWriteBarrier();
828#ifdef NEFORCE_COMPILER_GNUC
829 return __atomic_fetch_xor(ptr, value,
static_cast<int32_t>(mo));
833 ::_ReadWriteBarrier();
852#ifdef NEFORCE_COMPILER_GNUC
853 return __atomic_add_fetch(ptr, value,
static_cast<int32_t>(mo));
872#ifdef NEFORCE_COMPILER_GNUC
873 return __atomic_sub_fetch(ptr, value,
static_cast<int32_t>(mo));
892#ifdef NEFORCE_COMPILER_GNUC
893 return __atomic_and_fetch(ptr, value,
static_cast<int32_t>(mo));
912#ifdef NEFORCE_COMPILER_GNUC
913 return __atomic_or_fetch(ptr, value,
static_cast<int32_t>(mo));
932#ifdef NEFORCE_COMPILER_GNUC
933 return __atomic_xor_fetch(ptr, value,
static_cast<int32_t>(mo));
956#ifdef NEFORCE_COMPILER_GNUC
957 return __atomic_compare_exchange(ptr, expected, desired,
true,
static_cast<int32_t>(
success),
958 static_cast<int32_t>(failure));
960# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
961 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
963 ::_ReadWriteBarrier();
970# if defined(NEFORCE_ARCH_ARM)
971 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 1) {
972 asm volatile(
"ldrexb %[loaded], [%[ptr]]\n\t"
973 "cmp %[loaded], %[old_val]\n\t"
975 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
977 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
978 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
981 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 2) {
982 asm volatile(
"ldrexh %[loaded], [%[ptr]]\n\t"
983 "cmp %[loaded], %[old_val]\n\t"
985 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
987 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
988 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
991 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
992 asm volatile(
"ldrex %[loaded], [%[ptr]]\n\t"
993 "cmp %[loaded], %[old_val]\n\t"
995 "strex %w[success], %w[desired], [%[ptr]]\n\t"
997 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
998 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1001 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
1002 asm volatile(
"ldrexd %[loaded], [%[ptr]]\n\t"
1003 "cmp %[loaded], %[old_val]\n\t"
1005 "strexd %w[success], %[desired], [%[ptr]]\n\t"
1007 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1008 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1011# elif defined(NEFORCE_ARCH_RISCV)
1012 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
1013 asm volatile(
"lr.w %[loaded], (%[ptr])\n\t"
1014 "bne %[loaded], %[old_val], 1f\n\t"
1015 "sc.w %[success], %[desired], (%[ptr])\n\t"
1017 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1018 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1021 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
1022 asm volatile(
"lr.d %[loaded], (%[ptr])\n\t"
1023 "bne %[loaded], %[old_val], 1f\n\t"
1024 "sc.d %[success], %[desired], (%[ptr])\n\t"
1026 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1027 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1030# elif defined(NEFORCE_ARCH_LOONGARCH)
1031 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
1032 asm volatile(
"ll.w %[loaded], %[ptr]\n\t"
1033 "bne %[loaded], %[old_val], 1f\n\t"
1034 "sc.w %[desired], %[ptr]\n\t"
1035 "move %[success], %[desired]\n\t"
1037 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1038 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1041 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
1042 asm volatile(
"ll.d %[loaded], %[ptr]\n\t"
1043 "bne %[loaded], %[old_val], 1f\n\t"
1044 "sc.d %[desired], %[ptr]\n\t"
1045 "move %[success], %[desired]\n\t"
1047 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1048 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1052 if (loaded != old_val) {
1056 return success_flag == 0;
1072template <
typename T>
1077#ifdef NEFORCE_COMPILER_GNUC
1078 return __atomic_compare_exchange(ptr, expected, desired,
false,
static_cast<int32_t>(
success),
1079 static_cast<int32_t>(failure));
1081# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
1082 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
1084 ::_ReadWriteBarrier();
1109template <
typename T>
1111#ifdef NEFORCE_COMPILER_GNUC
1129template <
typename T>
1131#ifdef NEFORCE_COMPILER_GNUC
1132 alignas(T)
byte_t buffer[
sizeof(T)];
1134 __atomic_load(ptr, dest,
static_cast<int32_t>(mo));
1140 inner::atomic_load_verifier<
sizeof(T)>::verify(ptr, result);
1142 ::_ReadWriteBarrier();
1157template <
typename T>
1160#ifdef NEFORCE_COMPILER_GNUC
1161 alignas(T)
byte_t buffer[
sizeof(T)];
1163 __atomic_exchange(ptr, _NEFORCE
addressof(desired), dest,
static_cast<int32_t>(mo));
1182template <
typename T>
1187 new_value = old_value + value;
1200template <
typename T>
1205 new_value = old_value - value;
1218template <
typename T>
1223 new_value = old_value + value;
1236template <
typename T>
1241 new_value = old_value - value;
1253template <
size_t Size,
size_t Align>
1255#ifdef NEFORCE_COMPILER_GNUC
1256 return __atomic_is_lock_free(Size,
reinterpret_cast<void*
>(-Align));
1258 return inner::atomic_is_always_lock_free_impl<Size>::value;
1274#ifdef NEFORCE_COMPILER_MSVC
1295 flag_(static_cast<
value_type>(static_cast<
int>(flag) != 0 ? 1 : 0)) {}
1303#ifdef NEFORCE_COMPILER_GNUC
1304 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1306 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1308 ::_ReadWriteBarrier();
1310 return old_val != 0;
1318#ifdef NEFORCE_COMPILER_GNUC
1319 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1321 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1323 ::_ReadWriteBarrier();
1325 return old_val != 0;
1335#ifdef NEFORCE_COMPILER_GNUC
1337 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1340 const long as_bytes =
flag_;
1342 ::_ReadWriteBarrier();
1344 return as_bytes != 0;
1353#ifdef NEFORCE_COMPILER_GNUC
1355 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1358 const long as_bytes =
flag_;
1360 ::_ReadWriteBarrier();
1362 return as_bytes != 0;
1372 const auto value =
static_cast<value_type>(old);
1374 [
this, mo] {
return this->
test(mo); });
1382 const auto value =
static_cast<value_type>(old);
1384 [
this, mo] {
return this->
test(mo); });
1402#ifdef NEFORCE_SUPPORT_INTEL_TSX
1413#ifdef NEFORCE_COMPILER_GNUC
1424#ifdef NEFORCE_SUPPORT_INTEL_TSX
1435#ifdef NEFORCE_COMPILER_GNUC
1450template <
typename T>
1458 static constexpr size_t align_inner =
sizeof(T) >
alignof(T) ?
sizeof(T) : alignof(T);
1463 atomic_base() noexcept = default;
1464 ~atomic_base() noexcept = default;
1465 atomic_base(const atomic_base&) = delete;
1466 atomic_base& operator=(const atomic_base&) = delete;
1467 atomic_base& operator=(const atomic_base&) volatile = delete;
1468 atomic_base(atomic_base&&) noexcept = default;
1469 atomic_base& operator=(atomic_base&&) noexcept = default;
1652#ifdef NEFORCE_SUPPORT_INTEL_TSX
1669#ifdef NEFORCE_SUPPORT_INTEL_TSX
1688#ifdef NEFORCE_SUPPORT_INTEL_TSX
1703#ifdef NEFORCE_SUPPORT_INTEL_TSX
1937template <
typename T>
1938struct atomic_base<T*> {
1946 return dest *
sizeof(T);
2083#ifdef NEFORCE_SUPPORT_INTEL_TSX
2094#ifdef NEFORCE_COMPILER_GNUC
2095 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2097 ::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_),
reinterpret_cast<void*
>(ptr));
2099 ::_ReadWriteBarrier();
2109#ifdef NEFORCE_SUPPORT_INTEL_TSX
2120#ifdef NEFORCE_COMPILER_GNUC
2121 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2123 ::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr);
2125 ::_ReadWriteBarrier();
2136#ifdef NEFORCE_SUPPORT_INTEL_TSX
2145#ifdef NEFORCE_COMPILER_GNUC
2146 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2150 ::_ReadWriteBarrier();
2160#ifdef NEFORCE_SUPPORT_INTEL_TSX
2169#ifdef NEFORCE_COMPILER_GNUC
2170 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2174 ::_ReadWriteBarrier();
2188#ifdef NEFORCE_COMPILER_GNUC
2189 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2192 static_cast<value_type>(::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2194 ::_ReadWriteBarrier();
2205#ifdef NEFORCE_COMPILER_GNUC
2206 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2209 static_cast<value_type>(::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2211 ::_ReadWriteBarrier();
2337 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2340 return reinterpret_cast<value_type>(old_val);
2348 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2351 return reinterpret_cast<value_type>(old_val);
2362 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2365 return reinterpret_cast<value_type>(old_val);
2373 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2376 return reinterpret_cast<value_type>(old_val);
2388template <
typename Float>
2389struct atomic_float_base {
2396 alignas(
alignof(Float)) Float float_ =
static_cast<Float
>(0);
2399 atomic_float_base() =
default;
2400 atomic_float_base(
const atomic_float_base&) =
delete;
2401 atomic_float_base& operator=(
const atomic_float_base&) =
delete;
2402 atomic_float_base& operator=(
const atomic_float_base&)
volatile =
delete;
2403 atomic_float_base(atomic_float_base&&) noexcept = default;
2404 atomic_float_base& operator=(atomic_float_base&&) noexcept = default;
2474 operator Float() const noexcept {
return this->
load(); }
2479 operator Float() const volatile noexcept {
return this->
load(); }
2653template <
typename T,
bool IsIntegral = is_
integral_v<T>,
bool IsFloatingPo
int = is_
floating_po
int_v<T>>
2661template <
typename T>
2666 static constexpr int align_inner = (
sizeof(T) & (
sizeof(T) - 1)) != 0U ||
sizeof(T) > 16 ? 0 :
sizeof(T);
2702 operator T() const noexcept {
return this->
load(); }
2809template <
typename T>
2810struct atomic_ref_base<T, true, false> {
2823 atomic_ref_base() =
delete;
2824 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
2825 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
2850 NEFORCE_NODISCARD
operator T() const noexcept {
return this->
load(); }
3066template <
typename Float>
3067struct atomic_ref_base<Float, false, true> {
3080 atomic_ref_base() =
delete;
3081 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
3082 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
3107 operator Float() const noexcept {
return this->
load(); }
3252#ifdef NEFORCE_COMPILER_CLANG
3253# pragma clang diagnostic push
3254# pragma clang diagnostic ignored "-Watomic-alignment"
3261template <
typename T>
3262struct atomic_ref_base<T*,
false,
false> {
3272 return dest *
sizeof(T);
3279 atomic_ref_base() =
delete;
3280 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
3281 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
3306 operator T*()
const noexcept {
return this->
load(); }
3419 return reinterpret_cast<value_type>(old_val);
3432 return reinterpret_cast<value_type>(old_val);
3474#ifdef NEFORCE_COMPILER_CLANG
3475# pragma clang diagnostic pop
3482NEFORCE_END_NAMESPACE__
constexpr T * addressof(T &x) noexcept
获取对象的地址
remove_volatile_t< T > atomic_or_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子或并获取操作
void atomic_signal_fence(const memory_order mo) noexcept
信号内存屏障
void atomic_store(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子存储操作
remove_volatile_t< T > atomic_load_any(const T *ptr, memory_order mo) noexcept
通用原子加载操作
bool atomic_cmpexch_strong(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
remove_volatile_t< T > atomic_fetch_and(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并与操作
T atomic_fetch_sub_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子获取并减去操作
remove_volatile_t< T > atomic_fetch_xor(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并异或操作
remove_volatile_t< T > atomic_and_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子与并获取操作
remove_volatile_t< T > atomic_fetch_or(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并或操作
conditional_t< is_pointer_v< T >, ptrdiff_t, remove_volatile_t< T > > atomic_diff_t
原子操作的差值类型
remove_volatile_t< T > atomic_fetch_sub(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并减去操作
bool atomic_cmpexch_weak(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool atomic_cmpexch_weak_any(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > *desired, const memory_order success, const memory_order failure) noexcept
通用弱比较交换操作
T atomic_fetch_add_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子获取并添加操作
void atomic_wait_address_v(const T *addr, T old, Func f) noexcept
基于值的原子等待
T atomic_sub_fetch_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子减去并获取操作
constexpr bool is_always_lock_free() noexcept
检查是否支持无锁操作
bool atomic_cmpexch_strong_any(volatile T *ptr, remove_volatile_t< T > *expected, remove_volatile_t< T > *desired, const memory_order success, const memory_order failure) noexcept
通用强比较交换操作
T atomic_add_fetch_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子添加并获取操作
remove_volatile_t< T > atomic_exchange(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子交换操作
remove_volatile_t< T > atomic_fetch_add(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并添加操作
remove_volatile_t< T > atomic_xor_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子异或并获取操作
remove_volatile_t< T > atomic_add_fetch(volatile T *ptr, atomic_diff_t< T > value, memory_order mo) noexcept
原子添加并获取操作
void atomic_store_any(T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
通用原子存储操作
remove_volatile_t< T > atomic_exchange_any(T *ptr, remove_volatile_t< T > desired, memory_order mo) noexcept
通用原子交换操作
remove_volatile_t< T > atomic_sub_fetch(volatile T *ptr, atomic_diff_t< T > value, memory_order mo) noexcept
原子减去并获取操作
void atomic_thread_fence(const memory_order mo) noexcept
线程内存屏障
remove_volatile_t< T > atomic_load(const volatile T *ptr, const memory_order mo) noexcept
原子加载操作
void atomic_notify_address(const T *addr, const bool all) noexcept
原子通知
constexpr bool is_floating_point_v
is_floating_point的便捷变量模板
constexpr bool is_integral_v
is_integral的便捷变量模板
constexpr bool is_integral_like_v
is_integral_like的便捷变量模板
constexpr bool is_object_v
is_object的便捷变量模板
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long uint64_t
64位无符号整数类型
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
long platform_wait_t
平台等待类型别名
constexpr void * memory_copy(void *__restrict dest, const void *__restrict src, size_t count) noexcept
从源内存复制到目标内存
constexpr int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_consume
数据依赖内存顺序常量
constexpr bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
constexpr auto memory_order_relaxed
宽松内存顺序常量
@ memory_order_mask
内存顺序掩码
typename remove_volatile< T >::type remove_volatile_t
remove_volatile的便捷别名
constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换指针操作
value_type operator-=(const ptrdiff_t dest) noexcept
指针减法赋值运算符
value_type operator--(int) noexcept
后置递减运算符
value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去指针偏移
ptrdiff_t difference_type
差值类型
value_type fetch_add(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加指针偏移
value_type operator++(int) volatile noexcept
volatile版本的后置递增运算符
value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换指针操作
value_type operator++(int) noexcept
后置递增运算符
value_type operator+=(const ptrdiff_t dest) volatile noexcept
volatile版本的指针加法赋值运算符
value_type operator++() volatile noexcept
volatile版本的前置递增运算符
value_type operator+=(const ptrdiff_t dest) noexcept
指针加法赋值运算符
value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载指针操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type operator=(const value_type ptr) volatile noexcept
volatile版本的赋值运算符
value_type operator--(int) volatile noexcept
volatile版本的后置递减运算符
value_type operator=(const value_type ptr) noexcept
赋值运算符
value_type operator--() noexcept
前置递减运算符
value_type operator--() volatile noexcept
volatile版本的前置递减运算符
void store(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储指针操作
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换指针操作
value_type fetch_add(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加指针偏移
value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去指针偏移
value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载指针操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换指针操作
value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子交换指针操作
value_type operator++() noexcept
前置递增运算符
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换指针操作
void store(value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子存储指针操作
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换指针操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
value_type operator-=(const ptrdiff_t dest) volatile noexcept
volatile版本的指针减法赋值运算符
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换指针操作
void notify_all() noexcept
通知所有等待线程
void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待指针改变
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换指针操作
void notify_one() noexcept
通知一个等待线程
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换指针操作
value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并异或操作
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
value_type operator=(value_type value) volatile noexcept
volatile版本的赋值运算符
value_type operator--(int) volatile noexcept
volatile版本的后置递减运算符
value_type operator&=(value_type value) volatile noexcept
volatile版本的位与赋值运算符
void notify_one() noexcept
通知一个等待线程
value_type operator=(value_type value) noexcept
赋值运算符
value_type operator--() volatile noexcept
volatile版本的前置递减运算符
value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并或操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
void notify_all() noexcept
通知所有等待线程
value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并或操作
value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加操作
value_type operator+=(value_type value) volatile noexcept
volatile版本的加法赋值运算符
void store(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并异或操作
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
value_type operator^=(value_type value) volatile noexcept
volatile版本的位异或赋值运算符
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
value_type operator&=(value_type value) noexcept
位与赋值运算符
value_type operator--(int) noexcept
后置递减运算符
value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
value_type operator++() noexcept
前置递增运算符
value_type operator++() volatile noexcept
volatile版本的前置递增运算符
value_type operator|=(value_type value) volatile noexcept
volatile版本的位或赋值运算符
value_type operator-=(value_type value) volatile noexcept
volatile版本的减法赋值运算符
value_type operator+=(value_type value) noexcept
加法赋值运算符
value_type operator--() noexcept
前置递减运算符
void store(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
value_type operator|=(value_type value) noexcept
位或赋值运算符
value_type operator++(int) noexcept
后置递增运算符
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并与操作
value_type operator^=(value_type value) noexcept
位异或赋值运算符
value_type operator++(int) volatile noexcept
volatile版本的后置递增运算符
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool test(const memory_order mo=memory_order_seq_cst) const noexcept
测试标志值
void clear(const memory_order mo=memory_order_seq_cst) noexcept
清除标志
bool test_and_set(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的测试并设置标志
void wait(const bool old, const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的等待标志值改变
bool test_and_set(const memory_order mo=memory_order_seq_cst) noexcept
测试并设置标志
bool test(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的测试标志值
void clear(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的清除标志
void notify_all() noexcept
通知所有等待线程
void notify_one() noexcept
通知一个等待线程
void wait(const bool old, const memory_order mo=memory_order_seq_cst) const noexcept
等待标志值改变
void notify_one() noexcept
通知一个等待线程
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
Float operator=(Float value) volatile noexcept
volatile版本的赋值运算符
void store(Float value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
Float load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
value_type operator+=(value_type value) volatile noexcept
volatile版本的加法赋值运算符
bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type operator-=(value_type value) volatile noexcept
volatile版本的减法赋值运算符
value_type difference_type
差值类型
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
void store(Float value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
void notify_all() noexcept
通知所有等待线程
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
Float load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
Float operator=(Float value) noexcept
赋值运算符
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
void store(Float value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
static constexpr size_t required_alignment
对齐需求
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
atomic_ref_base(Float &value)
构造函数
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
Float load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
value_type difference_type
差值类型
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
void notify_one() noexcept
通知一个等待线程
Float operator=(Float value) noexcept
赋值运算符
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
void notify_all() noexcept
通知所有等待线程
static constexpr size_t required_alignment
对齐需求
atomic_ref_base(T &value)
构造函数
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
void notify_one() noexcept
通知一个等待线程
bool compare_exchange_strong(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
bool compare_exchange_weak(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
T operator=(T value) noexcept
赋值运算符
void notify_all() noexcept
通知所有等待线程
bool is_lock_free() const noexcept
检查是否支持无锁操作
void wait(T old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
bool compare_exchange_weak(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_strong(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并异或操作
value_type difference_type
差值类型
value_type operator+=(value_type value) noexcept
加法赋值运算符
value_type operator--(int) noexcept
后置递减运算符
value_type operator++(int) noexcept
后置递增运算符
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
bool compare_exchange_weak(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
void notify_one() noexcept
通知一个等待线程
static constexpr size_t required_alignment
对齐需求
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
value_type operator|=(value_type value) noexcept
位或赋值运算符
value_type operator&=(value_type value) noexcept
位与赋值运算符
value_type operator++() noexcept
前置递增运算符
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
T operator=(T value) noexcept
赋值运算符
void wait(T old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type operator^=(value_type value) noexcept
位异或赋值运算符
bool compare_exchange_weak(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
atomic_ref_base(T &value)
构造函数
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并或操作
void notify_all() noexcept
通知所有等待线程
value_type operator--() noexcept
前置递减运算符
bool compare_exchange_weak(T *&expected, T *desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换指针操作
value_type operator--(int) noexcept
后置递减运算符
T * operator=(T *value) noexcept
赋值运算符
void wait(T *old, const memory_order mo=memory_order_seq_cst) const noexcept
等待指针改变
bool compare_exchange_strong(T *&expected, T *desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换指针操作
value_type operator++() noexcept
前置递增运算符
value_type fetch_add(const difference_type dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加指针偏移
T * exchange(T *desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换指针操作
T * load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载指针操作
ptrdiff_t difference_type
差值类型
bool compare_exchange_strong(T *&expected, T *desire, const memory_order success, const memory_order failure) noexcept
强比较交换指针操作
value_type operator-=(const difference_type dest) noexcept
指针减法赋值运算符
bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type operator--() noexcept
前置递减运算符
value_type operator+=(const difference_type dest) noexcept
指针加法赋值运算符
void notify_all() noexcept
通知所有等待线程
static constexpr size_t required_alignment
对齐需求
value_type fetch_sub(const difference_type dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去指针偏移
atomic_ref_base(T *&value)
构造函数
void store(T *value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储指针操作
void notify_one() noexcept
通知一个等待线程
bool compare_exchange_weak(T *&expected, T *desire, const memory_order success, const memory_order failure) noexcept
弱比较交换指针操作
value_type operator++(int) noexcept
后置递增运算符