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__
41#ifdef NEFORCE_COMPILER_MSVC
45# if defined(NEFORCE_ARCH_X86)
46 ::_ReadWriteBarrier();
48 volatile long guard = 0;
49 ::_InterlockedIncrement(&guard);
50 ::_ReadWriteBarrier();
52# elif defined(NEFORCE_ARCH_ARM)
54 ::_Memory_load_acquire_barrier();
56 ::_ReadWriteBarrier();
59 ::_ReadWriteBarrier();
62 __atomic_thread_fence(
static_cast<int32_t>(mo));
73#ifdef NEFORCE_COMPILER_MSVC
75 ::_ReadWriteBarrier();
78 __atomic_signal_fence(
static_cast<int32_t>(mo));
86#ifdef NEFORCE_COMPILER_MSVC
89struct interlocked_exchange_impl;
92struct interlocked_exchange_impl<1> {
94 static T call(
volatile T* target, T value) {
95 return static_cast<T
>(
96 ::_InterlockedExchange8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
100struct interlocked_exchange_impl<2> {
101 template <
typename T>
102 static T call(
volatile T* target, T value) {
103 return static_cast<T
>(
104 ::_InterlockedExchange16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
108struct interlocked_exchange_impl<4> {
109 template <
typename T>
110 static T call(
volatile T* target, T value) {
111 return static_cast<T
>(
112 ::_InterlockedExchange(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
116struct interlocked_exchange_impl<8> {
117 template <
typename T>
118 static T call(
volatile T* target, T value) {
119# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
120 return static_cast<T
>(
121 ::_InterlockedExchange64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
123 return static_cast<T
>(
124 ::_interlockedexchange64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
129template <
size_t Size>
130struct interlocked_compare_exchange_impl;
133struct interlocked_compare_exchange_impl<1> {
134 template <
typename T>
135 static bool call(
volatile T* target, T* expected, T desired) {
137 ::_InterlockedCompareExchange8(
reinterpret_cast<volatile char*
>(target),
138 *
reinterpret_cast<char*
>(&desired), *
reinterpret_cast<char*
>(expected));
139 if (old == *
reinterpret_cast<char*
>(expected)) {
142 *
reinterpret_cast<char*
>(expected) = old;
147struct interlocked_compare_exchange_impl<2> {
148 template <
typename T>
149 static bool call(
volatile T* target, T* expected, T desired) {
150 const short old = ::_InterlockedCompareExchange16(
reinterpret_cast<volatile short*
>(target),
151 *
reinterpret_cast<short*
>(&desired),
152 *
reinterpret_cast<short*
>(expected));
153 if (old == *
reinterpret_cast<short*
>(expected)) {
156 *
reinterpret_cast<short*
>(expected) = old;
161struct interlocked_compare_exchange_impl<4> {
162 template <
typename T>
163 static bool call(
volatile T* target, T* expected, T desired) {
165 ::_InterlockedCompareExchange(
reinterpret_cast<volatile long*
>(target),
166 *
reinterpret_cast<long*
>(&desired), *
reinterpret_cast<long*
>(expected));
167 if (old == *
reinterpret_cast<long*
>(expected)) {
170 *
reinterpret_cast<long*
>(expected) = old;
175struct interlocked_compare_exchange_impl<8> {
176 template <
typename T>
177 static bool call(
volatile T* target, T* expected, T desired) {
178 const long long old = ::_InterlockedCompareExchange64(
reinterpret_cast<volatile long long*
>(target),
179 *
reinterpret_cast<long long*
>(&desired),
180 *
reinterpret_cast<long long*
>(expected));
181 if (old == *
reinterpret_cast<long long*
>(expected)) {
184 *
reinterpret_cast<long long*
>(expected) = old;
189struct interlocked_compare_exchange_impl<16> {
190# if !(defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_ARCH_AARCH64))
192 struct futex_lock_128 {
195 static futex_lock_128& for_addr(
const void* addr)
noexcept {
197 static futex_lock_128 pool[pool_size];
198 return pool[(
reinterpret_cast<uintptr_t>(addr) >> 4) % pool_size];
201 void lock(
const void* )
noexcept {
203 if (::_InterlockedCompareExchange(&state_, 1, 0) == 0) {
207 [
this] { return ::_InterlockedExchangeAdd(&state_, 0); });
211 void unlock(
const void* )
noexcept {
212 ::_InterlockedExchange(&state_, 0);
218 template <
typename T>
219 static bool call(
volatile T* target, T* expected, T desired) {
220 alignas(16)
long long exp_arr[2];
221 alignas(16)
long long des_arr[2];
226# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_ARCH_AARCH64)
227 result = ::_InterlockedCompareExchange128(
reinterpret_cast<volatile long long*
>(target), des_arr[1], des_arr[0],
230 auto& flock = futex_lock_128::for_addr(target);
232 if (_NEFORCE
memory_compare(
const_cast<T*
>(target), exp_arr, 16) == 0) {
233 _NEFORCE
memory_copy(
const_cast<T*
>(target), des_arr, 16);
234 flock.unlock(target);
237 _NEFORCE
memory_copy(exp_arr,
const_cast<T*
>(target), 16);
238 flock.unlock(target);
250template <
size_t Size>
251struct interlocked_fetch_add_impl;
254struct interlocked_fetch_add_impl<1> {
255 template <
typename T>
256 static T call(
volatile T* target, T value) {
257 return static_cast<T
>(
258 ::_InterlockedExchangeAdd8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
262struct interlocked_fetch_add_impl<2> {
263 template <
typename T>
264 static T call(
volatile T* target, T value) {
265 return static_cast<T
>(
266 ::_InterlockedExchangeAdd16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
270struct interlocked_fetch_add_impl<4> {
271 template <
typename T>
272 static T call(
volatile T* target, T value) {
273 return static_cast<T
>(
274 ::_InterlockedExchangeAdd(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
278struct interlocked_fetch_add_impl<8> {
279 template <
typename T>
280 static T call(
volatile T* target, T value) {
281# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
282 return static_cast<T
>(::_InterlockedExchangeAdd64(
reinterpret_cast<volatile long long*
>(target),
283 static_cast<long long>(value)));
285 return static_cast<T
>(::_interlockedexchangeadd64(
reinterpret_cast<volatile long long*
>(target),
286 static_cast<long long>(value)));
291template <
size_t Size>
292struct interlocked_fetch_and_impl;
295struct interlocked_fetch_and_impl<1> {
296 template <
typename T>
297 static T call(
volatile T* target, T value) {
298 return static_cast<T
>(::_InterlockedAnd8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
302struct interlocked_fetch_and_impl<2> {
303 template <
typename T>
304 static T call(
volatile T* target, T value) {
305 return static_cast<T
>(
306 ::_InterlockedAnd16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
310struct interlocked_fetch_and_impl<4> {
311 template <
typename T>
312 static T call(
volatile T* target, T value) {
313 return static_cast<T
>(::_InterlockedAnd(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
317struct interlocked_fetch_and_impl<8> {
318 template <
typename T>
319 static T call(
volatile T* target, T value) {
320# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
321 return static_cast<T
>(
322 ::_InterlockedAnd64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
324 return static_cast<T
>(
325 ::_interlockedadd64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
330template <
size_t Size>
331struct interlocked_fetch_or_impl;
334struct interlocked_fetch_or_impl<1> {
335 template <
typename T>
336 static T call(
volatile T* target, T value) {
337 return static_cast<T
>(::_InterlockedOr8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
341struct interlocked_fetch_or_impl<2> {
342 template <
typename T>
343 static T call(
volatile T* target, T value) {
344 return static_cast<T
>(::_InterlockedOr16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
348struct interlocked_fetch_or_impl<4> {
349 template <
typename T>
350 static T call(
volatile T* target, T value) {
351 return static_cast<T
>(::_InterlockedOr(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
355struct interlocked_fetch_or_impl<8> {
356 template <
typename T>
357 static T call(
volatile T* target, T value) {
358# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
359 return static_cast<T
>(
360 ::_InterlockedOr64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
362 return static_cast<T
>(
363 ::_interlockedor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
368template <
size_t Size>
369struct interlocked_fetch_xor_impl;
372struct interlocked_fetch_xor_impl<1> {
373 template <
typename T>
374 static T call(
volatile T* target, T value) {
375 return static_cast<T
>(::_InterlockedXor8(
reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
379struct interlocked_fetch_xor_impl<2> {
380 template <
typename T>
381 static T call(
volatile T* target, T value) {
382 return static_cast<T
>(
383 ::_InterlockedXor16(
reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
387struct interlocked_fetch_xor_impl<4> {
388 template <
typename T>
389 static T call(
volatile T* target, T value) {
390 return static_cast<T
>(::_InterlockedXor(
reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
394struct interlocked_fetch_xor_impl<8> {
395 template <
typename T>
396 static T call(
volatile T* target, T value) {
397# if defined(NEFORCE_ARCH_BITS_64) || defined(NEFORCE_COMPILER_CLANG_CL)
398 return static_cast<T
>(
399 ::_InterlockedXor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
401 return static_cast<T
>(
402 ::_interlockedxor64(
reinterpret_cast<volatile long long*
>(target),
static_cast<long long>(value)));
407template <
size_t Size>
408struct atomic_is_always_lock_free_impl {
409 static constexpr bool value =
false;
412struct atomic_is_always_lock_free_impl<1> {
413 static constexpr bool value =
true;
416struct atomic_is_always_lock_free_impl<2> {
417 static constexpr bool value =
true;
420struct atomic_is_always_lock_free_impl<4> {
421 static constexpr bool value =
true;
424struct atomic_is_always_lock_free_impl<8> {
425 static constexpr bool value =
true;
428struct atomic_is_always_lock_free_impl<16> {
429# if defined(NEFORCE_ARCH_X86_64) || defined(NEFORCE_ARCH_AARCH64)
430 static constexpr bool value =
true;
432 static constexpr bool value =
false;
461#ifdef NEFORCE_COMPILER_GNUC
462 __atomic_store_n(ptr, value,
static_cast<int32_t>(mo));
464 inner::interlocked_exchange_impl<
sizeof(T)>::call(ptr, value);
466 ::_ReadWriteBarrier();
482#ifdef NEFORCE_COMPILER_GNUC
483 return __atomic_load_n(ptr,
static_cast<int32_t>(mo));
487 ::_ReadWriteBarrier();
506#ifdef NEFORCE_COMPILER_GNUC
507 return __atomic_exchange_n(ptr, value,
static_cast<int32_t>(mo));
511 ::_ReadWriteBarrier();
535#ifdef NEFORCE_COMPILER_GNUC
536 return __atomic_compare_exchange_n(ptr, expected, desired,
true,
static_cast<int32_t>(
success),
537 static_cast<int32_t>(failure));
539# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
540 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, desired);
542 ::_ReadWriteBarrier();
549# if defined(NEFORCE_ARCH_ARM)
550 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 1) {
551 asm volatile(
"ldrexb %[loaded], [%[ptr]]\n\t"
552 "cmp %[loaded], %[old_val]\n\t"
554 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
556 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
557 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
560 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 2) {
561 asm volatile(
"ldrexh %[loaded], [%[ptr]]\n\t"
562 "cmp %[loaded], %[old_val]\n\t"
564 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
566 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
567 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
570 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
571 asm volatile(
"ldrex %[loaded], [%[ptr]]\n\t"
572 "cmp %[loaded], %[old_val]\n\t"
574 "strex %w[success], %w[desired], [%[ptr]]\n\t"
576 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
577 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
580 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
588 "ldrexd %[lo], %[hi], [%[ptr]]\n\t"
589 "cmp %[lo], %[old_lo]\n\t"
590 "cmpeq %[hi], %[old_hi]\n\t"
592 "strexd %[success], %[des_lo], %[des_hi], [%[ptr]]\n\t"
594 : [lo]
"=&r"(loaded_lo), [hi]
"=&r"(loaded_hi), [
success]
"=&r"(tmp_success)
595 : [ptr]
"r"(ptr), [old_lo]
"r"(old_lo), [old_hi]
"r"(old_hi), [des_lo]
"r"(des_lo), [des_hi]
"r"(des_hi)
597 loaded =
static_cast<T
>(
static_cast<uint64_t>(loaded_lo) | (
static_cast<uint64_t>(loaded_hi) << 32));
598 success_flag = (tmp_success == 0);
599 if (loaded != old_val) {
605# elif defined(NEFORCE_ARCH_RISCV)
606 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
607 asm volatile(
"lr.w %[loaded], (%[ptr])\n\t"
608 "bne %[loaded], %[old_val], 1f\n\t"
609 "sc.w %[success], %[desired], (%[ptr])\n\t"
611 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
612 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
615 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
616 asm volatile(
"lr.d %[loaded], (%[ptr])\n\t"
617 "bne %[loaded], %[old_val], 1f\n\t"
618 "sc.d %[success], %[desired], (%[ptr])\n\t"
620 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
621 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
624# elif defined(NEFORCE_ARCH_LOONGARCH)
625 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
628 asm volatile(
"ll.w %[loaded], %[ptr]\n\t"
629 "bne %[loaded], %[old_val], 1f\n\t"
630 "sc.w %[des_copy], %[ptr]\n\t"
632 "move %[success], %[des_copy]\n\t"
633 : [loaded]
"=&r"(loaded), [des_copy]
"+r"(des_copy), [
success]
"=r"(sc_result)
634 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val)
636 success_flag = (sc_result == 0);
638 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
639 asm volatile(
"ll.d %[loaded], %[ptr]\n\t"
640 "bne %[loaded], %[old_val], 1f\n\t"
641 "sc.d %[desired], %[ptr]\n\t"
642 "move %[success], %[desired]\n\t"
644 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
645 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
649 if (loaded != old_val) {
653 return success_flag == 0;
676#ifdef NEFORCE_COMPILER_GNUC
677 return __atomic_compare_exchange_n(ptr, expected, desired,
false,
static_cast<int32_t>(
success),
678 static_cast<int32_t>(failure));
680# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
688 if (*expected != old_val) {
709#ifdef NEFORCE_COMPILER_GNUC
710 return __atomic_fetch_add(ptr, value,
static_cast<int32_t>(mo));
714 ::_ReadWriteBarrier();
733#ifdef NEFORCE_COMPILER_GNUC
734 return __atomic_fetch_sub(ptr, value,
static_cast<int32_t>(mo));
753#ifdef NEFORCE_COMPILER_GNUC
754 return __atomic_fetch_and(ptr, value,
static_cast<int32_t>(mo));
758 ::_ReadWriteBarrier();
777#ifdef NEFORCE_COMPILER_GNUC
778 return __atomic_fetch_or(ptr, value,
static_cast<int32_t>(mo));
782 ::_ReadWriteBarrier();
801#ifdef NEFORCE_COMPILER_GNUC
802 return __atomic_fetch_xor(ptr, value,
static_cast<int32_t>(mo));
806 ::_ReadWriteBarrier();
825#ifdef NEFORCE_COMPILER_GNUC
826 return __atomic_add_fetch(ptr, value,
static_cast<int32_t>(mo));
845#ifdef NEFORCE_COMPILER_GNUC
846 return __atomic_sub_fetch(ptr, value,
static_cast<int32_t>(mo));
865#ifdef NEFORCE_COMPILER_GNUC
866 return __atomic_and_fetch(ptr, value,
static_cast<int32_t>(mo));
885#ifdef NEFORCE_COMPILER_GNUC
886 return __atomic_or_fetch(ptr, value,
static_cast<int32_t>(mo));
905#ifdef NEFORCE_COMPILER_GNUC
906 return __atomic_xor_fetch(ptr, value,
static_cast<int32_t>(mo));
929#ifdef NEFORCE_COMPILER_GNUC
930 return __atomic_compare_exchange(ptr, expected, desired,
true,
static_cast<int32_t>(
success),
931 static_cast<int32_t>(failure));
933# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
934 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
936 ::_ReadWriteBarrier();
943# if defined(NEFORCE_ARCH_ARM)
944 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 1) {
945 asm volatile(
"ldrexb %[loaded], [%[ptr]]\n\t"
946 "cmp %[loaded], %[old_val]\n\t"
948 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
950 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
951 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
954 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 2) {
955 asm volatile(
"ldrexh %[loaded], [%[ptr]]\n\t"
956 "cmp %[loaded], %[old_val]\n\t"
958 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
960 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
961 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
964 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
965 asm volatile(
"ldrex %[loaded], [%[ptr]]\n\t"
966 "cmp %[loaded], %[old_val]\n\t"
968 "strex %w[success], %w[desired], [%[ptr]]\n\t"
970 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
971 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
974 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
975 asm volatile(
"ldrexd %[loaded], [%[ptr]]\n\t"
976 "cmp %[loaded], %[old_val]\n\t"
978 "strexd %w[success], %[desired], [%[ptr]]\n\t"
980 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
981 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
984# elif defined(NEFORCE_ARCH_RISCV)
985 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
986 asm volatile(
"lr.w %[loaded], (%[ptr])\n\t"
987 "bne %[loaded], %[old_val], 1f\n\t"
988 "sc.w %[success], %[desired], (%[ptr])\n\t"
990 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
991 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
994 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
995 asm volatile(
"lr.d %[loaded], (%[ptr])\n\t"
996 "bne %[loaded], %[old_val], 1f\n\t"
997 "sc.d %[success], %[desired], (%[ptr])\n\t"
999 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1000 : [ptr]
"r"(ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1003# elif defined(NEFORCE_ARCH_LOONGARCH)
1004 NEFORCE_IF_CONSTEXPR(
sizeof(T) == 4) {
1005 asm volatile(
"ll.w %[loaded], %[ptr]\n\t"
1006 "bne %[loaded], %[old_val], 1f\n\t"
1007 "sc.w %[desired], %[ptr]\n\t"
1008 "move %[success], %[desired]\n\t"
1010 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1011 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1014 else NEFORCE_IF_CONSTEXPR(
sizeof(T) == 8) {
1015 asm volatile(
"ll.d %[loaded], %[ptr]\n\t"
1016 "bne %[loaded], %[old_val], 1f\n\t"
1017 "sc.d %[desired], %[ptr]\n\t"
1018 "move %[success], %[desired]\n\t"
1020 : [loaded]
"=&r"(loaded), [
success]
"=&r"(success_flag)
1021 : [ptr]
"m"(*ptr), [old_val]
"r"(old_val), [desired]
"r"(desired)
1025 if (loaded != old_val) {
1029 return success_flag == 0;
1045template <
typename T>
1050#ifdef NEFORCE_COMPILER_GNUC
1051 return __atomic_compare_exchange(ptr, expected, desired,
false,
static_cast<int32_t>(
success),
1052 static_cast<int32_t>(failure));
1054# if defined(NEFORCE_ARCH_X86) || defined(NEFORCE_ARCH_AARCH64)
1055 const bool result = inner::interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
1057 ::_ReadWriteBarrier();
1082template <
typename T>
1084#ifdef NEFORCE_COMPILER_GNUC
1102template <
typename T>
1104#ifdef NEFORCE_COMPILER_GNUC
1105 alignas(T)
byte_t buffer[
sizeof(T)];
1107 __atomic_load(ptr, dest,
static_cast<int32_t>(mo));
1113 ::_ReadWriteBarrier();
1128template <
typename T>
1131#ifdef NEFORCE_COMPILER_GNUC
1132 alignas(T)
byte_t buffer[
sizeof(T)];
1134 __atomic_exchange(ptr, _NEFORCE
addressof(desired), dest,
static_cast<int32_t>(mo));
1153template <
typename T>
1158 new_value = old_value + value;
1171template <
typename T>
1176 new_value = old_value - value;
1189template <
typename T>
1194 new_value = old_value + value;
1207template <
typename T>
1212 new_value = old_value - value;
1224template <
size_t Size,
size_t Align>
1226#ifdef NEFORCE_COMPILER_GNUC
1227 return __atomic_is_lock_free(Size,
reinterpret_cast<void*
>(-Align));
1229 return inner::atomic_is_always_lock_free_impl<Size>::value;
1245#ifdef NEFORCE_COMPILER_MSVC
1266 flag_(static_cast<
value_type>(static_cast<
int>(flag) != 0 ? 1 : 0)) {}
1274#ifdef NEFORCE_COMPILER_GNUC
1275 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1277 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1279 ::_ReadWriteBarrier();
1281 return old_val != 0;
1289#ifdef NEFORCE_COMPILER_GNUC
1290 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1292 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1294 ::_ReadWriteBarrier();
1296 return old_val != 0;
1306#ifdef NEFORCE_COMPILER_GNUC
1308 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1311 const long as_bytes =
flag_;
1313 ::_ReadWriteBarrier();
1315 return as_bytes != 0;
1324#ifdef NEFORCE_COMPILER_GNUC
1326 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1329 const long as_bytes =
flag_;
1331 ::_ReadWriteBarrier();
1333 return as_bytes != 0;
1343 const auto value =
static_cast<value_type>(old);
1345 [
this, mo] {
return this->
test(mo); });
1353 const auto value =
static_cast<value_type>(old);
1355 [
this, mo] {
return this->
test(mo); });
1373#ifdef NEFORCE_SUPPORT_INTEL_TSX
1384#ifdef NEFORCE_COMPILER_GNUC
1395#ifdef NEFORCE_SUPPORT_INTEL_TSX
1406#ifdef NEFORCE_COMPILER_GNUC
1421template <
typename T>
1429 static constexpr size_t align_inner =
sizeof(T) >
alignof(T) ?
sizeof(T) : alignof(T);
1434 atomic_base() noexcept = default;
1435 ~atomic_base() noexcept = default;
1436 atomic_base(const atomic_base&) = delete;
1437 atomic_base& operator=(const atomic_base&) = delete;
1438 atomic_base& operator=(const atomic_base&) volatile = delete;
1439 atomic_base(atomic_base&&) noexcept = default;
1440 atomic_base& operator=(atomic_base&&) noexcept = default;
1623#ifdef NEFORCE_SUPPORT_INTEL_TSX
1640#ifdef NEFORCE_SUPPORT_INTEL_TSX
1659#ifdef NEFORCE_SUPPORT_INTEL_TSX
1674#ifdef NEFORCE_SUPPORT_INTEL_TSX
1908template <
typename T>
1909struct atomic_base<T*> {
1917 return dest *
sizeof(T);
2054#ifdef NEFORCE_SUPPORT_INTEL_TSX
2065#ifdef NEFORCE_COMPILER_GNUC
2066 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2068 ::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_),
reinterpret_cast<void*
>(ptr));
2070 ::_ReadWriteBarrier();
2080#ifdef NEFORCE_SUPPORT_INTEL_TSX
2091#ifdef NEFORCE_COMPILER_GNUC
2092 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2094 ::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr);
2096 ::_ReadWriteBarrier();
2107#ifdef NEFORCE_SUPPORT_INTEL_TSX
2116#ifdef NEFORCE_COMPILER_GNUC
2117 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2121 ::_ReadWriteBarrier();
2131#ifdef NEFORCE_SUPPORT_INTEL_TSX
2140#ifdef NEFORCE_COMPILER_GNUC
2141 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2145 ::_ReadWriteBarrier();
2159#ifdef NEFORCE_COMPILER_GNUC
2160 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2163 static_cast<value_type>(::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2165 ::_ReadWriteBarrier();
2176#ifdef NEFORCE_COMPILER_GNUC
2177 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2180 static_cast<value_type>(::_InterlockedExchangePointer(
reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2182 ::_ReadWriteBarrier();
2308 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2311 return reinterpret_cast<value_type>(old_val);
2319 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2322 return reinterpret_cast<value_type>(old_val);
2333 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2336 return reinterpret_cast<value_type>(old_val);
2344 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<ptrdiff_t>(
sizeof(T)));
2347 return reinterpret_cast<value_type>(old_val);
2359template <
typename Float>
2360struct atomic_float_base {
2367 alignas(
alignof(Float)) Float float_ =
static_cast<Float
>(0);
2370 atomic_float_base() =
default;
2371 atomic_float_base(
const atomic_float_base&) =
delete;
2372 atomic_float_base& operator=(
const atomic_float_base&) =
delete;
2373 atomic_float_base& operator=(
const atomic_float_base&)
volatile =
delete;
2374 atomic_float_base(atomic_float_base&&) noexcept = default;
2375 atomic_float_base& operator=(atomic_float_base&&) noexcept = default;
2445 operator Float() const noexcept {
return this->
load(); }
2450 operator Float() const volatile noexcept {
return this->
load(); }
2624template <
typename T,
bool IsIntegral = is_
integral_v<T>,
bool IsFloatingPo
int = is_
floating_po
int_v<T>>
2632template <
typename T>
2637 static constexpr int align_inner = (
sizeof(T) & (
sizeof(T) - 1)) != 0U ||
sizeof(T) > 16 ? 0 :
sizeof(T);
2673 operator T() const noexcept {
return this->
load(); }
2780template <
typename T>
2781struct atomic_ref_base<T, true, false> {
2794 atomic_ref_base() =
delete;
2795 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
2796 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
2821 NEFORCE_NODISCARD
operator T() const noexcept {
return this->
load(); }
3037template <
typename Float>
3038struct atomic_ref_base<Float, false, true> {
3051 atomic_ref_base() =
delete;
3052 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
3053 atomic_ref_base& operator=(
const atomic_ref_base&) =
delete;
3078 operator Float() const noexcept {
return this->
load(); }
3223#ifdef NEFORCE_COMPILER_CLANG
3224# pragma clang diagnostic push
3225# pragma clang diagnostic ignored "-Watomic-alignment"
3228template <
typename T>
3231 using value_type = T*;
3237 static constexpr difference_type real_type_sizes(
const difference_type dest)
noexcept {
3239 return dest *
sizeof(T);
3244 static constexpr size_t required_alignment =
sizeof(T*) == 8 ? 8 : alignof(T*);
3264 T* operator=(T* value)
noexcept {
3273 operator T*()
const noexcept {
return this->load(); }
3279 NEFORCE_NODISCARD
bool is_lock_free() const noexcept {
3382 NEFORCE_ALWAYS_INLINE value_type fetch_add(
const difference_type dest,
3384 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<difference_type
>(
sizeof(T)));
3386 return reinterpret_cast<value_type
>(old_val);
3395 NEFORCE_ALWAYS_INLINE value_type fetch_sub(
const difference_type dest,
3397 const auto byte_offset =
static_cast<uintptr_t>(dest *
static_cast<difference_type
>(
sizeof(T)));
3399 return reinterpret_cast<value_type
>(old_val);
3406 value_type operator++(
int)
noexcept {
return fetch_add(1); }
3412 value_type operator--(
int)
noexcept {
return fetch_sub(1); }
3418 value_type operator++() noexcept {
return fetch_add(1) + 1; }
3424 value_type operator--() noexcept {
return fetch_sub(1) - 1; }
3431 value_type operator+=(
const difference_type dest)
noexcept {
return fetch_add(dest) + dest; }
3438 value_type operator-=(
const difference_type dest)
noexcept {
return fetch_sub(dest) - dest; }
3441#ifdef NEFORCE_COMPILER_CLANG
3442# pragma clang diagnostic pop
3449NEFORCE_END_NAMESPACE__
constexpr T * addressof(T &x) 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_fetch_add_any(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
原子获取并或操作
remove_volatile_t< T > atomic_sub_fetch(volatile T *ptr, atomic_diff_t< T > value, 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
强比较交换操作
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_sub_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子获取并减去操作
T atomic_add_fetch_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子添加并获取操作
constexpr bool is_always_lock_free() noexcept
检查是否支持无锁操作
void atomic_wait_address_v(const T *addr, T old, Func f) noexcept
基于值的原子等待
void atomic_notify_address(const T *addr, const bool all) noexcept
原子通知
T atomic_sub_fetch_any(T *ptr, remove_volatile_t< T > value, 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_load_any(const T *ptr, memory_order mo) noexcept
通用原子加载操作
void atomic_thread_fence(const 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_signal_fence(const 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
原子与并获取操作
void atomic_store_any(T *ptr, remove_volatile_t< T > value, const 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_sub(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并减去操作
remove_volatile_t< T > atomic_or_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子或并获取操作
remove_volatile_t< T > atomic_load(const volatile T *ptr, const memory_order mo) noexcept
原子加载操作
conditional_t< is_pointer_v< T >, ptrdiff_t, remove_volatile_t< T > > atomic_diff_t
原子操作的差值类型
void atomic_store(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子存储操作
remove_volatile_t< T > atomic_fetch_and(volatile 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
通用原子交换操作
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
弱比较交换操作
remove_volatile_t< T > atomic_fetch_add(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并添加操作
constexpr bool is_integral_v
is_integral的便捷变量模板
constexpr bool is_floating_point_v
is_floating_point的便捷变量模板
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 long uint64_t
64位无符号整数类型
#define NEFORCE_CONSTEXPR_ASSERT(COND)
编译时常量断言
long platform_wait_t
平台等待类型别名
constexpr int memory_compare(const void *lhs, const void *rhs, size_t count) noexcept
比较两个内存区域的内容
constexpr void * memory_copy(void *NEFORCE_RESTRICT dest, const void *NEFORCE_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
constexpr bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
constexpr auto memory_order_relaxed
宽松内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_consume
数据依赖内存顺序常量
constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
@ memory_order_mask
内存顺序掩码
typename remove_volatile< T >::type remove_volatile_t
remove_volatile的便捷别名
constexpr T exchange(T &val, U &&new_val) noexcept(is_nothrow_move_constructible_v< T > &&is_nothrow_assignable_v< T &, U >)
将新值赋给对象并返回旧值
constexpr bool is_nothrow_copy_constructible_v
is_nothrow_copy_constructible的便捷变量模板
constexpr bool is_trivially_copyable_v
is_trivially_copyable的便捷变量模板
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--(int) noexcept
后置递减运算符
value_type operator++(int) volatile noexcept
volatile版本的后置递增运算符
void store(value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子存储指针操作
value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载指针操作
value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载指针操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换指针操作
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) noexcept
简化版弱比较交换指针操作
value_type operator--(int) 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 exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子交换指针操作
value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去指针偏移
value_type fetch_add(const ptrdiff_t dest, 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 operator+=(const ptrdiff_t dest) noexcept
指针加法赋值运算符
value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去指针偏移
value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换指针操作
value_type operator--() noexcept
前置递减运算符
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
void notify_one() noexcept
通知一个等待线程
value_type operator=(const value_type ptr) noexcept
赋值运算符
value_type operator++() volatile noexcept
volatile版本的前置递增运算符
value_type operator-=(const ptrdiff_t dest) volatile noexcept
volatile版本的指针减法赋值运算符
bool is_lock_free() const noexcept
检查是否支持无锁操作
void store(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储指针操作
value_type operator--() volatile noexcept
volatile版本的前置递减运算符
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换指针操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换指针操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换指针操作
value_type operator++() noexcept
前置递增运算符
value_type operator=(const value_type ptr) 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 mo=memory_order_seq_cst) noexcept
简化版强比较交换指针操作
ptrdiff_t difference_type
差值类型
value_type operator-=(const ptrdiff_t dest) noexcept
指针减法赋值运算符
value_type operator++(int) noexcept
后置递增运算符
void notify_all() noexcept
通知所有等待线程
value_type operator--(int) noexcept
后置递减运算符
value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
value_type load(const memory_order mo=memory_order_seq_cst) const 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) noexcept
原子交换操作
void notify_one() noexcept
通知一个等待线程
value_type operator|=(value_type value) volatile noexcept
volatile版本的位或赋值运算符
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type operator--() noexcept
前置递减运算符
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并异或操作
void notify_all() noexcept
通知所有等待线程
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
value_type operator--() volatile noexcept
volatile版本的前置递减运算符
value_type operator-=(value_type value) volatile noexcept
volatile版本的减法赋值运算符
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type operator=(value_type value) volatile noexcept
volatile版本的赋值运算符
bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
value_type operator^=(value_type value) noexcept
位异或赋值运算符
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
value_type operator++(int) volatile noexcept
volatile版本的后置递增运算符
value_type operator++(int) noexcept
后置递增运算符
value_type operator+=(value_type value) noexcept
加法赋值运算符
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并与操作
value_type exchange(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 mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
value_type operator--(int) 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
赋值运算符
void store(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
value_type operator++() noexcept
前置递增运算符
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
value_type operator+=(value_type value) volatile noexcept
volatile版本的加法赋值运算符
bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) 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版本的位异或赋值运算符
void store(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
value_type operator|=(value_type value) noexcept
位或赋值运算符
bool compare_exchange_strong(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 success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
value_type operator++() volatile noexcept
volatile版本的前置递增运算符
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加操作
value_type operator&=(value_type value) noexcept
位与赋值运算符
value_type fetch_or(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 fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并异或操作
void notify_one() 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 noexcept
测试标志值
void wait(const bool old, const memory_order mo=memory_order_seq_cst) const noexcept
等待标志值改变
void clear(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的清除标志
void clear(const memory_order mo=memory_order_seq_cst) noexcept
清除标志
bool test(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的测试标志值
void notify_all() noexcept
通知所有等待线程
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
value_type fetch_sub(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 success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
value_type operator-=(value_type value) volatile noexcept
volatile版本的减法赋值运算符
Float load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
Float operator=(Float value) noexcept
赋值运算符
value_type difference_type
差值类型
value_type operator+=(value_type value) volatile noexcept
volatile版本的加法赋值运算符
void store(Float value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
Float operator=(Float value) 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) volatile noexcept
volatile版本的原子获取并添加操作
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
bool compare_exchange_strong(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
void store(Float value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
void notify_one() noexcept
通知一个等待线程
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) 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) noexcept
简化版弱比较交换操作
Float exchange(Float desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
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
原子加载操作
void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void notify_all() noexcept
通知所有等待线程
value_type operator+=(value_type value) noexcept
加法赋值运算符
bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
static constexpr size_t required_alignment
对齐需求
value_type difference_type
差值类型
bool compare_exchange_strong(Float &expected, 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 mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
Float operator=(Float value) noexcept
赋值运算符
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
void notify_one() noexcept
通知一个等待线程
bool compare_exchange_weak(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
bool compare_exchange_strong(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
void notify_all() noexcept
通知所有等待线程
bool is_lock_free() const noexcept
检查是否支持无锁操作
bool compare_exchange_weak(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
原子存储操作
atomic_ref_base(T &value)
构造函数
T operator=(T value) noexcept
赋值运算符
void wait(T old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
void notify_one() noexcept
通知一个等待线程
static constexpr size_t required_alignment
对齐需求
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type operator--(int) noexcept
后置递减运算符
bool compare_exchange_weak(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
原子获取并异或操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
void notify_one() noexcept
通知一个等待线程
static constexpr size_t required_alignment
对齐需求
bool compare_exchange_weak(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
value_type operator++() noexcept
前置递增运算符
value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
T operator=(T value) noexcept
赋值运算符
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
value_type operator^=(value_type value) noexcept
位异或赋值运算符
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
void wait(T old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
value_type difference_type
差值类型
bool compare_exchange_strong(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
atomic_ref_base(T &value)
构造函数
value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
value_type operator&=(value_type value) noexcept
位与赋值运算符
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
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 operator|=(value_type value) noexcept
位或赋值运算符
void notify_all() noexcept
通知所有等待线程
value_type operator--() noexcept
前置递减运算符
value_type operator++(int) noexcept
后置递增运算符
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作