1#ifndef MSTL_CORE_ASYNC_ATOMIC_BASE_HPP__
2#define MSTL_CORE_ASYNC_ATOMIC_BASE_HPP__
12#ifdef MSTL_PLATFORM_WINDOWS__
111 return failure_order | modifiers;
133#ifdef MSTL_COMPILER_MSVC__
135#if defined(MSTL_ARCH_X86__)
136 ::_ReadWriteBarrier();
139 ::_InterlockedIncrement(&guard);
140 ::_ReadWriteBarrier();
142#elif defined(MSTL_ARCH_ARM__)
144 ::_Memory_load_acquire_barrier();
146 ::_ReadWriteBarrier();
152 __atomic_thread_fence(
static_cast<int32_t>(mo));
163#ifdef MSTL_COMPILER_MSVC__
166 __atomic_signal_fence(
static_cast<int32_t>(mo));
175#ifdef MSTL_COMPILER_MSVC__
183template <
size_t Size>
184struct interlocked_exchange_impl;
187struct interlocked_exchange_impl<1> {
188 template <
typename T>
189 static T call(
volatile T* target, T value) {
190 return static_cast<T
>(::_InterlockedExchange8(
191 reinterpret_cast<volatile char*
>(target),
192 static_cast<char>(value)));
197struct interlocked_exchange_impl<2> {
198 template <
typename T>
199 static T call(
volatile T* target, T value) {
200 return static_cast<T
>(::_InterlockedExchange16(
201 reinterpret_cast<volatile short*
>(target),
202 static_cast<short>(value)));
207struct interlocked_exchange_impl<4> {
208 template <
typename T>
209 static T call(
volatile T* target, T value) {
210 return static_cast<T
>(::_InterlockedExchange(
211 reinterpret_cast<volatile long*
>(target),
212 static_cast<long>(value)));
217struct interlocked_exchange_impl<8> {
218 template <
typename T>
219 static T call(
volatile T* target, T value) {
220 return static_cast<T
>(::_interlockedexchange64(
221 reinterpret_cast<volatile long long*
>(target),
222 static_cast<long long>(value)));
231template <
size_t Size>
232struct interlocked_compare_exchange_impl;
235struct interlocked_compare_exchange_impl<1> {
236 template <
typename T>
237 static bool call(
volatile T* target, T* expected, T desired) {
238 const char old = ::_InterlockedCompareExchange8(
239 reinterpret_cast<volatile char*
>(target),
240 *
reinterpret_cast<char*
>(&desired),
241 *
reinterpret_cast<char*
>(expected));
242 if (old == *
reinterpret_cast<char*
>(expected))
return true;
243 *
reinterpret_cast<char*
>(expected) = old;
249struct interlocked_compare_exchange_impl<2> {
250 template <
typename T>
251 static bool call(
volatile T* target, T* expected, T desired) {
252 const short old = ::_InterlockedCompareExchange16(
253 reinterpret_cast<volatile short*
>(target),
254 *
reinterpret_cast<short*
>(&desired),
255 *
reinterpret_cast<short*
>(expected));
256 if (old == *
reinterpret_cast<short*
>(expected))
return true;
257 *
reinterpret_cast<short*
>(expected) = old;
263struct interlocked_compare_exchange_impl<4> {
264 template <
typename T>
265 static bool call(
volatile T* target, T* expected, T desired) {
266 const long old = ::_InterlockedCompareExchange(
267 reinterpret_cast<volatile long*
>(target),
268 *
reinterpret_cast<long*
>(&desired),
269 *
reinterpret_cast<long*
>(expected));
270 if (old == *
reinterpret_cast<long*
>(expected))
return true;
271 *
reinterpret_cast<long*
>(expected) = old;
277struct interlocked_compare_exchange_impl<8> {
278 template <
typename T>
279 static bool call(
volatile T* target, T* expected, T desired) {
280 const long long old = ::_InterlockedCompareExchange64(
281 reinterpret_cast<volatile long long*
>(target),
282 *
reinterpret_cast<long long*
>(&desired),
283 *
reinterpret_cast<long long*
>(expected));
284 if (old == *
reinterpret_cast<long long*
>(expected))
return true;
285 *
reinterpret_cast<long long*
>(expected) = old;
291struct interlocked_compare_exchange_impl<16> {
292 template <
typename T>
293 static bool call(
volatile T* target, T* expected, T desired) {
294 alignas(16)
long long exp_arr[2];
295 alignas(16)
long long des_arr[2];
299 const bool result = ::_InterlockedCompareExchange128(
300 reinterpret_cast<volatile long long*
>(target),
301 des_arr[1], des_arr[0], exp_arr) != 0;
315template <
size_t Size>
316struct interlocked_fetch_add_impl;
319struct interlocked_fetch_add_impl<1> {
320 template <
typename T>
321 static T call(
volatile T* target, T value) {
322 return static_cast<T
>(::_InterlockedExchangeAdd8(
323 reinterpret_cast<volatile char*
>(target),
324 static_cast<char>(value)));
329struct interlocked_fetch_add_impl<2> {
330 template <
typename T>
331 static T call(
volatile T* target, T value) {
332 return static_cast<T
>(::_InterlockedExchangeAdd16(
333 reinterpret_cast<volatile short*
>(target),
334 static_cast<short>(value)));
339struct interlocked_fetch_add_impl<4> {
340 template <
typename T>
341 static T call(
volatile T* target, T value) {
342 return static_cast<T
>(::_InterlockedExchangeAdd(
343 reinterpret_cast<volatile long*
>(target),
344 static_cast<long>(value)));
349struct interlocked_fetch_add_impl<8> {
350 template <
typename T>
351 static T call(
volatile T* target, T value) {
352 return static_cast<T
>(::_interlockedexchangeadd64(
353 reinterpret_cast<volatile long long*
>(target),
354 static_cast<long long>(value)));
363template <
size_t Size>
364struct interlocked_fetch_and_impl;
367struct interlocked_fetch_and_impl<1> {
368 template <
typename T>
369 static T call(
volatile T* target, T value) {
370 return static_cast<T
>(::_InterlockedAnd8(
371 reinterpret_cast<volatile char*
>(target),
372 static_cast<char>(value)));
377struct interlocked_fetch_and_impl<2> {
378 template <
typename T>
379 static T call(
volatile T* target, T value) {
380 return static_cast<T
>(::_InterlockedAnd16(
381 reinterpret_cast<volatile short*
>(target),
382 static_cast<short>(value)));
387struct interlocked_fetch_and_impl<4> {
388 template <
typename T>
389 static T call(
volatile T* target, T value) {
390 return static_cast<T
>(::_InterlockedAnd(
391 reinterpret_cast<volatile long*
>(target),
392 static_cast<long>(value)));
397struct interlocked_fetch_and_impl<8> {
398 template <
typename T>
399 static T call(
volatile T* target, T value) {
400 return static_cast<T
>(::_interlockedand64(
401 reinterpret_cast<volatile long long*
>(target),
402 static_cast<long long>(value)));
411template <
size_t Size>
412struct interlocked_fetch_or_impl;
415struct interlocked_fetch_or_impl<1> {
416 template <
typename T>
417 static T call(
volatile T* target, T value) {
418 return static_cast<T
>(::_InterlockedOr8(
419 reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
423struct interlocked_fetch_or_impl<2> {
424 template <
typename T>
425 static T call(
volatile T* target, T value) {
426 return static_cast<T
>(::_InterlockedOr16(
427 reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
431struct interlocked_fetch_or_impl<4> {
432 template <
typename T>
433 static T call(
volatile T* target, T value) {
434 return static_cast<T
>(::_InterlockedOr(
435 reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
439struct interlocked_fetch_or_impl<8> {
440 template <
typename T>
441 static T call(
volatile T* target, T value) {
442 return static_cast<T
>(::_interlockedor64(
443 reinterpret_cast<volatile long long*
>(target),
444 static_cast<long long>(value)));
453template <
size_t Size>
454struct interlocked_fetch_xor_impl;
457struct interlocked_fetch_xor_impl<1> {
458 template <
typename T>
459 static T call(
volatile T* target, T value) {
460 return static_cast<T
>(::_InterlockedXor8(
461 reinterpret_cast<volatile char*
>(target),
static_cast<char>(value)));
465struct interlocked_fetch_xor_impl<2> {
466 template <
typename T>
467 static T call(
volatile T* target, T value) {
468 return static_cast<T
>(::_InterlockedXor16(
469 reinterpret_cast<volatile short*
>(target),
static_cast<short>(value)));
473struct interlocked_fetch_xor_impl<4> {
474 template <
typename T>
475 static T call(
volatile T* target, T value) {
476 return static_cast<T
>(::_InterlockedXor(
477 reinterpret_cast<volatile long*
>(target),
static_cast<long>(value)));
481struct interlocked_fetch_xor_impl<8> {
482 template <
typename T>
483 static T call(
volatile T* target, T value) {
484 return static_cast<T
>(::_interlockedxor64(
485 reinterpret_cast<volatile long long*
>(target),
486 static_cast<long long>(value)));
492#ifdef MSTL_COMPILER_GNUC__
500template <
size_t Size>
501struct atomic_is_always_lock_free_impl {
502 static constexpr bool value = __atomic_always_lock_free(Size,
nullptr);
507template <
size_t Size>
508struct atomic_is_always_lock_free_impl {
509 static constexpr bool value =
false;
512struct atomic_is_always_lock_free_impl<1> {
513 static constexpr bool value =
true;
516struct atomic_is_always_lock_free_impl<2> {
517 static constexpr bool value =
true;
520struct atomic_is_always_lock_free_impl<4> {
521 static constexpr bool value =
true;
524struct atomic_is_always_lock_free_impl<8> {
525 static constexpr bool value =
true;
556MSTL_ALWAYS_INLINE_INLINE
void
558 static_assert(is_integral_v<T>,
"T must be integral type");
559#ifdef MSTL_COMPILER_GNUC__
560 __atomic_store_n(ptr, value,
static_cast<int32_t>(mo));
562 _INNER interlocked_exchange_impl<
sizeof(T)>::call(ptr, value);
564 ::_ReadWriteBarrier();
580 static_assert(is_integral_v<T>,
"T must be integral type");
581#ifdef MSTL_COMPILER_GNUC__
582 return __atomic_load_n(ptr,
static_cast<int32_t>(mo));
586 ::_ReadWriteBarrier();
604 static_assert(is_integral_v<T>,
"T must be integral type");
605#ifdef MSTL_COMPILER_GNUC__
606 return __atomic_exchange_n(ptr, value,
static_cast<int32_t>(mo));
610 ::_ReadWriteBarrier();
629MSTL_ALWAYS_INLINE_INLINE
bool
633 static_assert(is_integral_v<T>,
"T must be integral type");
635#ifdef MSTL_COMPILER_GNUC__
636 return __atomic_compare_exchange_n(
637 ptr, expected, desired,
true,
640#if defined(MSTL_ARCH_X86__)
641 const bool result =
_INNER interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, desired);
643 ::_ReadWriteBarrier();
650#if defined(MSTL_ARCH_ARM__)
651 MSTL_IF_CONSTEXPR (
sizeof(T) == 1) {
653 "ldrexb %[loaded], [%[ptr]]\n\t"
654 "cmp %[loaded], %[old_val]\n\t"
656 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
658 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
659 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
661 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 2) {
663 "ldrexh %[loaded], [%[ptr]]\n\t"
664 "cmp %[loaded], %[old_val]\n\t"
666 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
668 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
669 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
671 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 4) {
673 "ldrex %[loaded], [%[ptr]]\n\t"
674 "cmp %[loaded], %[old_val]\n\t"
676 "strex %w[success], %w[desired], [%[ptr]]\n\t"
678 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
679 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
681 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 8) {
683 "ldrexd %[loaded], [%[ptr]]\n\t"
684 "cmp %[loaded], %[old_val]\n\t"
686 "strexd %w[success], %[desired], [%[ptr]]\n\t"
688 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
689 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
692#elif defined(MSTL_ARCH_RISCV__)
693 MSTL_IF_CONSTEXPR (
sizeof(T) == 4) {
695 "lr.w %[loaded], (%[ptr])\n\t"
696 "bne %[loaded], %[old_val], 1f\n\t"
697 "sc.w %[success], %[desired], (%[ptr])\n\t"
699 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
700 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
702 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 8) {
704 "lr.d %[loaded], (%[ptr])\n\t"
705 "bne %[loaded], %[old_val], 1f\n\t"
706 "sc.d %[success], %[desired], (%[ptr])\n\t"
708 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
709 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
712#elif defined(MSTL_ARCH_LOONGARCH__)
713 MSTL_IF_CONSTEXPR (
sizeof(T) == 4) {
715 "ll.w %[loaded], %[ptr]\n\t"
716 "bne %[loaded], %[old_val], 1f\n\t"
717 "sc.w %[desired], %[ptr]\n\t"
718 "move %[success], %[desired]\n\t"
720 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
721 : [ptr]
"m" (*ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
723 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 8) {
725 "ll.d %[loaded], %[ptr]\n\t"
726 "bne %[loaded], %[old_val], 1f\n\t"
727 "sc.d %[desired], %[ptr]\n\t"
728 "move %[success], %[desired]\n\t"
730 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
731 : [ptr]
"m" (*ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
735 if (loaded != old_val) {
739 return success_flag == 0;
757MSTL_ALWAYS_INLINE_INLINE
bool
761 static_assert(is_integral_v<T>,
"T must be integral type");
763#ifdef MSTL_COMPILER_GNUC__
764 return __atomic_compare_exchange_n(
765 ptr, expected, desired,
false,
768#if defined(MSTL_ARCH_X86__)
773 if (
_INNER cmpexch_weak(ptr, expected, desired,
success, failure)) {
776 if (*expected != old_val) {
796 static_assert(is_integral_v<T>,
"T must be integral type");
797#ifdef MSTL_COMPILER_GNUC__
798 return __atomic_fetch_add(ptr, value,
static_cast<int32_t>(mo));
802 ::_ReadWriteBarrier();
820 static_assert(is_integral_v<T>,
"T must be integral type");
821#ifdef MSTL_COMPILER_GNUC__
822 return __atomic_fetch_sub(ptr, value,
static_cast<int32_t>(mo));
840 static_assert(is_integral_v<T>,
"T must be integral type");
841#ifdef MSTL_COMPILER_GNUC__
842 return __atomic_fetch_and(ptr, value,
static_cast<int32_t>(mo));
846 ::_ReadWriteBarrier();
864 static_assert(is_integral_v<T>,
"T must be integral type");
865#ifdef MSTL_COMPILER_GNUC__
866 return __atomic_fetch_or(ptr, value,
static_cast<int32_t>(mo));
870 ::_ReadWriteBarrier();
888 static_assert(is_integral_v<T>,
"T must be integral type");
889#ifdef MSTL_COMPILER_GNUC__
890 return __atomic_fetch_xor(ptr, value,
static_cast<int32_t>(mo));
894 ::_ReadWriteBarrier();
912 static_assert(is_integral_v<T>,
"T must be integral type");
913#ifdef MSTL_COMPILER_GNUC__
914 return __atomic_add_fetch(ptr, value,
static_cast<int32_t>(mo));
932 static_assert(is_integral_v<T>,
"T must be integral type");
933#ifdef MSTL_COMPILER_GNUC__
934 return __atomic_sub_fetch(ptr, value,
static_cast<int32_t>(mo));
952 static_assert(is_integral_v<T>,
"T must be integral type");
953#ifdef MSTL_COMPILER_GNUC__
954 return __atomic_and_fetch(ptr, value,
static_cast<int32_t>(mo));
972 static_assert(is_integral_v<T>,
"T must be integral type");
973#ifdef MSTL_COMPILER_GNUC__
974 return __atomic_or_fetch(ptr, value,
static_cast<int32_t>(mo));
992 static_assert(is_integral_v<T>,
"T must be integral type");
993#ifdef MSTL_COMPILER_GNUC__
994 return __atomic_xor_fetch(ptr, value,
static_cast<int32_t>(mo));
1012template <
typename T>
1013MSTL_ALWAYS_INLINE_INLINE
bool
1018#ifdef MSTL_COMPILER_GNUC__
1019 return __atomic_compare_exchange(
1020 ptr, expected, desired,
true,
1023#if defined(MSTL_ARCH_X86__)
1024 const bool result =
_INNER interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
1026 ::_ReadWriteBarrier();
1033#if defined(MSTL_ARCH_ARM__)
1034 MSTL_IF_CONSTEXPR (
sizeof(T) == 1) {
1036 "ldrexb %[loaded], [%[ptr]]\n\t"
1037 "cmp %[loaded], %[old_val]\n\t"
1039 "strexb %w[success], %w[desired], [%[ptr]]\n\t"
1041 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1042 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1044 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 2) {
1046 "ldrexh %[loaded], [%[ptr]]\n\t"
1047 "cmp %[loaded], %[old_val]\n\t"
1049 "strexh %w[success], %w[desired], [%[ptr]]\n\t"
1051 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1052 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1054 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 4) {
1056 "ldrex %[loaded], [%[ptr]]\n\t"
1057 "cmp %[loaded], %[old_val]\n\t"
1059 "strex %w[success], %w[desired], [%[ptr]]\n\t"
1061 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1062 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1064 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 8) {
1066 "ldrexd %[loaded], [%[ptr]]\n\t"
1067 "cmp %[loaded], %[old_val]\n\t"
1069 "strexd %w[success], %[desired], [%[ptr]]\n\t"
1071 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1072 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1075#elif defined(MSTL_ARCH_RISCV__)
1076 MSTL_IF_CONSTEXPR (
sizeof(T) == 4) {
1078 "lr.w %[loaded], (%[ptr])\n\t"
1079 "bne %[loaded], %[old_val], 1f\n\t"
1080 "sc.w %[success], %[desired], (%[ptr])\n\t"
1082 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1083 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1085 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 8) {
1087 "lr.d %[loaded], (%[ptr])\n\t"
1088 "bne %[loaded], %[old_val], 1f\n\t"
1089 "sc.d %[success], %[desired], (%[ptr])\n\t"
1091 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1092 : [ptr]
"r" (ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1095#elif defined(MSTL_ARCH_LOONGARCH__)
1096 MSTL_IF_CONSTEXPR (
sizeof(T) == 4) {
1098 "ll.w %[loaded], %[ptr]\n\t"
1099 "bne %[loaded], %[old_val], 1f\n\t"
1100 "sc.w %[desired], %[ptr]\n\t"
1101 "move %[success], %[desired]\n\t"
1103 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1104 : [ptr]
"m" (*ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1106 }
else MSTL_IF_CONSTEXPR (
sizeof(T) == 8) {
1108 "ll.d %[loaded], %[ptr]\n\t"
1109 "bne %[loaded], %[old_val], 1f\n\t"
1110 "sc.d %[desired], %[ptr]\n\t"
1111 "move %[success], %[desired]\n\t"
1113 : [loaded]
"=&r" (loaded), [
success]
"=&r" (success_flag)
1114 : [ptr]
"m" (*ptr), [old_val]
"r" (old_val), [desired]
"r" (desired)
1118 if (loaded != old_val) {
1122 return success_flag == 0;
1138template <
typename T>
1139MSTL_ALWAYS_INLINE_INLINE
bool
1144#ifdef MSTL_COMPILER_GNUC__
1145 return __atomic_compare_exchange(
1146 ptr, expected, desired,
false,
1149#if defined(MSTL_ARCH_X86__)
1150 const bool result =
_INNER interlocked_compare_exchange_impl<
sizeof(T)>::call(ptr, expected, *desired);
1152 ::_ReadWriteBarrier();
1158 if (
_INNER cmpexch_weak(ptr, expected, desired,
success, failure)) {
1161 if (*expected != old_val) {
1177template <
typename T>
1178MSTL_ALWAYS_INLINE_INLINE
void
1180#ifdef MSTL_COMPILER_GNUC__
1198template <
typename T>
1201#ifdef MSTL_COMPILER_GNUC__
1202 alignas(T)
byte_t buffer[
sizeof(T)];
1204 __atomic_load(ptr, dest,
static_cast<int32_t>(mo));
1210 ::_ReadWriteBarrier();
1225template <
typename T>
1228#ifdef MSTL_COMPILER_GNUC__
1229 alignas(T)
byte_t buffer[
sizeof(T)];
1250template <
typename T>
1255 new_value = old_value + value;
1268template <
typename T>
1273 new_value = old_value - value;
1285template <
typename T>
1290 new_value = old_value + value;
1302template <
typename T>
1307 new_value = old_value - value;
1319template <
size_t Size,
size_t Align>
1321#ifdef MSTL_COMPILER_GNUC__
1322 return __atomic_is_lock_free(Size,
reinterpret_cast<void *
>(-Align));
1324 return _INNER atomic_is_always_lock_free_impl<Size>::value;
1340#ifdef MSTL_PLATFORM_WINDOWS__
1348 atomic_flag() noexcept = default;
1349 atomic_flag(const atomic_flag&) = delete;
1350 atomic_flag& operator =(const atomic_flag&) = delete;
1351 atomic_flag& operator =(const atomic_flag&) volatile = delete;
1352 atomic_flag(atomic_flag&&) noexcept = default;
1353 atomic_flag& operator =(atomic_flag&&) noexcept = default;
1354 ~atomic_flag() noexcept = default;
1368 MSTL_ALWAYS_INLINE
bool
1370#ifdef MSTL_COMPILER_GNUC__
1371 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1373 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1375 return old_val != 0;
1382 MSTL_ALWAYS_INLINE_INLINE
bool
1384#ifdef MSTL_COMPILER_GNUC__
1385 return __atomic_test_and_set(&
flag_,
static_cast<int32_t>(mo));
1387 const long old_val = ::_InterlockedExchange(&
flag_, 1);
1389 return old_val != 0;
1398 MSTL_ALWAYS_INLINE
bool
1400#ifdef MSTL_COMPILER_GNUC__
1402 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1405 const long as_bytes =
flag_;
1407 return as_bytes != 0;
1414 MSTL_ALWAYS_INLINE_INLINE
bool
1416#ifdef MSTL_COMPILER_GNUC__
1418 __atomic_load(&
flag_, &value,
static_cast<int32_t>(mo));
1421 const long as_bytes =
flag_;
1423 return as_bytes != 0;
1432 MSTL_ALWAYS_INLINE
void
1437 [
this, mo] {
return this->
test(mo); }
1444 MSTL_ALWAYS_INLINE_INLINE
void
1449 [
this, mo] {
return this->
test(mo); }
1471 MSTL_ALWAYS_INLINE
void
1478#ifdef MSTL_COMPILER_GNUC__
1488 MSTL_ALWAYS_INLINE_INLINE
void
1495#ifdef MSTL_COMPILER_GNUC__
1510template <
typename T>
1515 static_assert(is_integral_like_v<T>,
"T must be an integral-like type");
1518 static constexpr size_t align_inner =
sizeof(T) >
alignof(T) ?
sizeof(T) : alignof(T);
1526 atomic_base() noexcept = default;
1527 ~atomic_base() noexcept = default;
1528 atomic_base(const atomic_base&) = delete;
1529 atomic_base& operator =(const atomic_base&) = delete;
1530 atomic_base& operator =(const atomic_base&) volatile = delete;
1531 atomic_base(atomic_base&&) noexcept = default;
1532 atomic_base& operator =(atomic_base&&) noexcept = default;
1734 MSTL_ALWAYS_INLINE
void
1746 MSTL_ALWAYS_INLINE
void
1806 MSTL_ALWAYS_INLINE
bool
1816 MSTL_ALWAYS_INLINE
bool
1830 MSTL_ALWAYS_INLINE
bool
1840 MSTL_ALWAYS_INLINE
bool
1855 MSTL_ALWAYS_INLINE
bool
1865 MSTL_ALWAYS_INLINE
bool
1879 MSTL_ALWAYS_INLINE
bool
1888 MSTL_ALWAYS_INLINE
bool
1899 MSTL_ALWAYS_INLINE
void
1902 return this->
load(mo);
2022template <
typename T>
2023struct atomic_base<T*> {
2037 return dest *
sizeof(T);
2044 atomic_base() noexcept = default;
2045 atomic_base(const atomic_base&) = delete;
2046 atomic_base& operator =(const atomic_base&) = delete;
2047 atomic_base& operator =(const atomic_base&) volatile = delete;
2048 atomic_base(atomic_base&&) noexcept = default;
2049 atomic_base& operator =(atomic_base&&) noexcept = default;
2050 ~atomic_base() noexcept = default;
2127#ifdef MSTL_COMPILER_GNUC__
2130 const char* old_ptr =
reinterpret_cast<char*
>(
2131 ::_interlockedexchangeadd64(
2132 reinterpret_cast<volatile long long*
>(&ptr_),
2133 static_cast<long long>(
sizeof(T))));
2134 return reinterpret_cast<value_type>(old_ptr +
sizeof(T));
2142#ifdef MSTL_COMPILER_GNUC__
2145 const char* old_ptr =
reinterpret_cast<char*
>(
2146 ::_interlockedexchangeadd64(
2147 reinterpret_cast<volatile long long*
>(&ptr_),
2148 static_cast<long long>(
sizeof(T))));
2149 return reinterpret_cast<value_type>(old_ptr +
sizeof(T));
2158#ifdef MSTL_COMPILER_GNUC__
2161 const char* old_ptr =
reinterpret_cast<char*
>(
2162 ::_interlockedexchangeadd64(
2163 reinterpret_cast<volatile long long*
>(&ptr_),
2165 return reinterpret_cast<value_type>(old_ptr -
sizeof(T));
2173#ifdef MSTL_COMPILER_GNUC__
2176 const char* old_ptr =
reinterpret_cast<char*
>(
2177 ::_interlockedexchangeadd64(
2178 reinterpret_cast<volatile long long*
>(&ptr_),
2180 return reinterpret_cast<value_type>(old_ptr -
sizeof(T));
2190#ifdef MSTL_COMPILER_GNUC__
2193 const char* old_ptr =
reinterpret_cast<char*
>(
2194 ::_interlockedexchangeadd64(
2195 reinterpret_cast<volatile long long*
>(&ptr_),
2196 static_cast<long long>(dest *
sizeof(T))));
2197 return reinterpret_cast<value_type>(old_ptr + dest *
sizeof(T));
2205#ifdef MSTL_COMPILER_GNUC__
2208 const char* old_ptr =
reinterpret_cast<char*
>(
2209 ::_interlockedexchangeadd64(
2210 reinterpret_cast<volatile long long*
>(&ptr_),
2211 static_cast<long long>(dest *
sizeof(T))));
2212 return reinterpret_cast<value_type>(old_ptr + dest *
sizeof(T));
2222#ifdef MSTL_COMPILER_GNUC__
2225 const char* old_ptr =
reinterpret_cast<char*
>(
2226 ::_interlockedexchangeadd64(
2227 reinterpret_cast<volatile long long*
>(&ptr_),
2228 -dest *
static_cast<ptrdiff_t>(
sizeof(T))));
2229 return reinterpret_cast<value_type>(old_ptr - dest *
sizeof(T));
2237#ifdef MSTL_COMPILER_GNUC__
2240 const char* old_ptr =
reinterpret_cast<char*
>(
2241 ::_interlockedexchangeadd64(
2242 reinterpret_cast<volatile long long*
>(&ptr_),
2243 -dest *
static_cast<ptrdiff_t>(
sizeof(T))));
2244 return reinterpret_cast<value_type>(old_ptr - dest *
sizeof(T));
2268 MSTL_ALWAYS_INLINE
void
2275#ifdef MSTL_COMPILER_GNUC__
2276 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2278 ::_InterlockedExchangePointer(
2279 reinterpret_cast<void* volatile*
>(&ptr_), ptr);
2281 ::_ReadWriteBarrier();
2289 MSTL_ALWAYS_INLINE_INLINE
void
2296#ifdef MSTL_COMPILER_GNUC__
2297 __atomic_store_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2299 ::_InterlockedExchangePointer(
2300 reinterpret_cast<void* volatile*
>(&ptr_), ptr);
2302 ::_ReadWriteBarrier();
2317#ifdef MSTL_COMPILER_GNUC__
2318 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2322 ::_ReadWriteBarrier();
2336#ifdef MSTL_COMPILER_GNUC__
2337 return __atomic_load_n(&ptr_,
static_cast<int32_t>(mo));
2341 ::_ReadWriteBarrier();
2355#ifdef MSTL_COMPILER_GNUC__
2356 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2359 ::_InterlockedExchangePointer(
2360 reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2362 ::_ReadWriteBarrier();
2373#ifdef MSTL_COMPILER_GNUC__
2374 return __atomic_exchange_n(&ptr_, ptr,
static_cast<int32_t>(mo));
2377 ::_InterlockedExchangePointer(
2378 reinterpret_cast<void* volatile*
>(&ptr_), ptr));
2380 ::_ReadWriteBarrier();
2394 MSTL_ALWAYS_INLINE
bool
2407 MSTL_ALWAYS_INLINE_INLINE
bool
2424 MSTL_ALWAYS_INLINE
bool
2434 MSTL_ALWAYS_INLINE
bool
2449 MSTL_ALWAYS_INLINE
bool
2462 MSTL_ALWAYS_INLINE_INLINE
bool
2478 MSTL_ALWAYS_INLINE
bool
2487 MSTL_ALWAYS_INLINE
bool
2498 MSTL_ALWAYS_INLINE
void
2501 return this->
load(mo);
2546#ifdef MSTL_COMPILER_GNUC__
2547 return __atomic_fetch_sub(&ptr_, real_type_sizes(dest),
static_cast<int32_t>(mo));
2549 const char* old_ptr =
reinterpret_cast<char*
>(
2550 ::_interlockedexchangeadd64(
2551 reinterpret_cast<volatile long long*
>(&ptr_),
2552 -dest *
static_cast<ptrdiff_t>(
sizeof(T))));
2554 ::_ReadWriteBarrier();
2556 return reinterpret_cast<value_type>(old_ptr);
2565#ifdef MSTL_COMPILER_GNUC__
2566 return __atomic_fetch_sub(&ptr_, real_type_sizes(dest),
static_cast<int32_t>(mo));
2568 const char* old_ptr =
reinterpret_cast<char*
>(
2569 ::_interlockedexchangeadd64(
2570 reinterpret_cast<volatile long long*
>(&ptr_),
2571 -dest *
static_cast<ptrdiff_t>(
sizeof(T))));
2573 ::_ReadWriteBarrier();
2575 return reinterpret_cast<value_type>(old_ptr);
2588template <
typename Float>
2589struct atomic_float_base {
2590 static_assert(is_floating_point_v<Float>,
"atomic_ref_base need floating point T");
2602 atomic_float_base() =
default;
2603 atomic_float_base(
const atomic_float_base&) =
delete;
2604 atomic_float_base& operator =(
const atomic_float_base&) =
delete;
2605 atomic_float_base& operator =(
const atomic_float_base&)
volatile =
delete;
2606 atomic_float_base(atomic_float_base&&) noexcept = default;
2607 atomic_float_base& operator =(atomic_float_base&&) noexcept = default;
2613 constexpr atomic_float_base(Float value)
2614 noexcept(is_nothrow_copy_constructible_v<Float>)
2620 Float operator =(Float value)
noexcept {
2628 Float operator =(Float value)
volatile noexcept {
2678 operator Float() const noexcept {
2679 return this->
load();
2685 operator Float() const volatile noexcept {
2686 return this->
load();
2772 MSTL_ALWAYS_INLINE
void
2775 return this->
load(mo);
2870template <
typename T,
bool IsIntegral = is_
integral_v<T>,
bool IsFloatingPo
int = is_
floating_po
int_v<T>>
2878template <
typename T>
2880 static_assert(is_trivially_copyable_v<T>,
"atomic_ref_base need trivially copyable T");
2883 static constexpr int align_inner = (
sizeof(T) & (
sizeof(T) - 1)) ||
sizeof(T) > 16 ? 0 :
sizeof(T);
2911 T operator =(T value)
noexcept {
2920 operator T() const noexcept {
2921 return this->
load();
3015 MSTL_ALWAYS_INLINE
void
3018 return this->
load(mo);
3041template <
typename T>
3042struct atomic_ref_base<T, true, false> {
3043 static_assert(is_integral_like_v<T>,
"atomic_ref need integral-like T");
3058 atomic_ref_base() =
delete;
3059 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
3060 atomic_ref_base& operator =(
const atomic_ref_base&) =
delete;
3075 T operator =(T value)
noexcept {
3084 MSTL_NODISCARD
operator T() const noexcept {
3085 return this->
load();
3179 MSTL_ALWAYS_INLINE
void
3182 return this->
load(mo);
3332template <
typename Float>
3333struct atomic_ref_base<Float, false, true> {
3334 static_assert(is_floating_point_v<Float>,
"atomic_ref_base need floating point T");
3348 atomic_ref_base() =
delete;
3349 atomic_ref_base(
const atomic_ref_base&)
noexcept =
default;
3350 atomic_ref_base& operator =(
const atomic_ref_base&) =
delete;
3365 Float operator =(Float value)
noexcept {
3374 operator Float() const noexcept {
3375 return this->
load();
3469 MSTL_ALWAYS_INLINE
void
3472 return this->
load(mo);
3530#ifdef MSTL_COMPILER_CLANG__
3531#pragma clang diagnostic push
3532#pragma clang diagnostic ignored "-Watomic-alignment"
3535template <
typename T>
3538 using value_type = T*;
3549 static constexpr difference_type real_type_sizes(
const difference_type dest)
noexcept {
3550 static_assert(is_object_v<T>,
"atomic_ref_base need object T");
3551 return dest *
sizeof(T);
3556 static constexpr size_t required_alignment =
sizeof(T*) == 8 ? 8 : alignof(T*);
3569 MSTL_CONSTEXPR_ASSERT((
static_cast<uintptr_t>(ptr_) % required_alignment) == 0);
3577 T* operator =(T* value)
noexcept {
3586 operator T*()
const noexcept {
3587 return this->load();
3594 bool is_lock_free() const noexcept {
3634 bool compare_exchange_weak(T*& expected, T* desire,
3647 bool compare_exchange_strong(T*& expected, T* desire,
3659 bool compare_exchange_weak(T*& expected, T* desire,
3671 bool compare_exchange_strong(T*& expected, T* desire,
3681 MSTL_ALWAYS_INLINE
void
3684 return this->load(mo);
3691 MSTL_ALWAYS_INLINE
void notify_one() noexcept {
3698 MSTL_ALWAYS_INLINE
void notify_all() noexcept {
3708 MSTL_ALWAYS_INLINE value_type
3719 MSTL_ALWAYS_INLINE value_type
3728 value_type operator ++(
int)
noexcept {
3729 return fetch_add(1);
3736 value_type operator --(
int)
noexcept {
3737 return fetch_sub(1);
3744 value_type operator ++() noexcept {
3752 value_type operator --() noexcept {
3761 value_type operator +=(
const difference_type dest)
noexcept {
3770 value_type operator -=(
const difference_type dest)
noexcept {
3775#ifdef MSTL_COMPILER_CLANG__
3776#pragma clang diagnostic pop
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_add_fetch(volatile T *ptr, atomic_diff_t< T > value, memory_order mo) noexcept
原子添加并获取操作
MSTL_ALWAYS_INLINE_INLINE void atomic_store(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子存储操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_exchange(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子交换操作
T atomic_fetch_add_any(T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
通用原子获取并添加操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_or_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子或并获取操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_load(const volatile T *ptr, const memory_order mo) noexcept
原子加载操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_or(volatile T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
原子获取并或操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_sub(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并减去操作
MSTL_ALWAYS_INLINE_INLINE 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
通用原子获取并减去操作
constexpr bool is_always_lock_free() noexcept
检查是否支持无锁操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_exchange_any(T *ptr, remove_volatile_t< T > desired, memory_order mo) noexcept
通用原子交换操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_sub_fetch(volatile T *ptr, atomic_diff_t< T > value, memory_order mo) noexcept
原子减去并获取操作
void atomic_wait_address_v(const T *addr, T old, Func f) noexcept
基于值的原子等待
MSTL_ALWAYS_INLINE_INLINE 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
强比较交换操作
void atomic_notify_address(const T *addr, const bool all) noexcept
原子通知
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_load_any(const T *ptr, memory_order mo) noexcept
通用原子加载操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_add(volatile T *ptr, atomic_diff_t< T > value, const memory_order mo) noexcept
原子获取并添加操作
T atomic_sub_fetch_any(T *ptr, remove_volatile_t< T > value) noexcept
通用原子减去并获取操作
MSTL_ALWAYS_INLINE_INLINE 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
弱比较交换操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_xor_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子异或并获取操作
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_fetch_xor(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
原子操作的差值类型
MSTL_ALWAYS_INLINE_INLINE remove_volatile_t< T > atomic_and_fetch(volatile T *ptr, remove_volatile_t< T > value, memory_order mo) noexcept
原子与并获取操作
MSTL_ALWAYS_INLINE_INLINE void atomic_store_any(T *ptr, remove_volatile_t< T > value, const memory_order mo) noexcept
通用原子存储操作
MSTL_ALWAYS_INLINE_INLINE 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
通用弱比较交换操作
MSTL_ALWAYS_INLINE_INLINE 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) noexcept
通用原子添加并获取操作
unsigned char byte_t
字节类型,定义为无符号字符
long long int64_t
64位有符号整数类型
MSTL_CONSTEXPR14 void * memory_copy(void *MSTL_RESTRICT dest, const void *MSTL_RESTRICT src, size_t count) noexcept
从源内存复制到目标内存
MSTL_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
constexpr bool is_valid_cmpexch_failure_order(const memory_order mo) noexcept
检查比较交换失败内存顺序是否有效
MSTL_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
MSTL_ALWAYS_INLINE_INLINE void atomic_thread_fence(const memory_order mo) noexcept
线程内存屏障
constexpr memory_order operator|(memory_order mo, memory_order_modifier mod) noexcept
内存顺序与修饰符的或操作符
MSTL_ALWAYS_INLINE_INLINE void atomic_signal_fence(const memory_order mo) noexcept
信号内存屏障
MSTL_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
constexpr memory_order operator&(memory_order mo, memory_order_modifier mod) noexcept
内存顺序与修饰符的与操作符
MSTL_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_consume
数据依赖内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_seq_cst
顺序一致性内存顺序常量
memory_order_modifier
内存顺序修饰符枚举
constexpr memory_order cmpexch_failure_order(const memory_order mo) noexcept
获取原子比较交换操作失败时的内存顺序
@ release
释放操作,确保前面的读写不会被重排到后面
@ acquire
获取操作,确保后续读写不会被重排到前面
@ consume
数据依赖顺序,用于依赖读取的场景
@ memory_order_mask
内存顺序掩码
@ memory_order_modifier_mask
修饰符掩码
@ memory_order_hle_acquire
HLE获取修饰符
@ memory_order_hle_release
HLE释放修饰符
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
typename remove_volatile< T >::type remove_volatile_t
remove_volatile的便捷别名
MSTL_CONSTEXPR14 T exchange(T &val, U &&new_val) noexcept(conjunction< is_nothrow_move_constructible< T >, is_nothrow_assignable< T &, U > >::value)
将新值赋给对象并返回旧值
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换指针操作
MSTL_ALWAYS_INLINE_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换指针操作
MSTL_ALWAYS_INLINE_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换指针操作
MSTL_ALWAYS_INLINE value_type fetch_add(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加指针偏移
MSTL_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
MSTL_ALWAYS_INLINE value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子交换指针操作
MSTL_ALWAYS_INLINE void store(const value_type ptr, const memory_order mo=memory_order_seq_cst) noexcept
原子存储指针操作
MSTL_ALWAYS_INLINE_INLINE value_type fetch_add(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加指针偏移
MSTL_ALWAYS_INLINE_INLINE void store(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储指针操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
MSTL_ALWAYS_INLINE value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去指针偏移
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换指针操作
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换指针操作
MSTL_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载指针操作
MSTL_ALWAYS_INLINE_INLINE value_type exchange(const value_type ptr, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换指针操作
MSTL_ALWAYS_INLINE_INLINE value_type fetch_sub(const ptrdiff_t dest, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去指针偏移
MSTL_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
强比较交换指针操作
MSTL_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
static constexpr bool is_always_lock_free
是否总是无锁
MSTL_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换指针操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
MSTL_ALWAYS_INLINE_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载指针操作
ptrdiff_t difference_type
差值类型
MSTL_ALWAYS_INLINE void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待指针改变
MSTL_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换指针操作
MSTL_ALWAYS_INLINE value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并或操作
MSTL_ALWAYS_INLINE value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并添加操作
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的弱比较交换操作
MSTL_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版强比较交换操作
MSTL_ALWAYS_INLINE value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并减去操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
MSTL_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
value_type operator--() noexcept
前置递减运算符
MSTL_ALWAYS_INLINE value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并与操作
bool is_lock_free() const volatile noexcept
volatile版本的检查是否支持无锁操作
MSTL_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的原子加载操作
value_type operator-=(value_type value) noexcept
减法赋值运算符
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
MSTL_ALWAYS_INLINE 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
位异或赋值运算符
MSTL_ALWAYS_INLINE value_type fetch_and(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并与操作
value_type operator+=(value_type value) noexcept
加法赋值运算符
MSTL_ALWAYS_INLINE value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
MSTL_ALWAYS_INLINE void store(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作
MSTL_ALWAYS_INLINE value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并异或操作
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
MSTL_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order success, const memory_order failure) volatile noexcept
volatile版本的强比较交换操作
MSTL_ALWAYS_INLINE value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子获取并或操作
MSTL_ALWAYS_INLINE void wait(value_type old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
MSTL_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
value_type operator++() noexcept
前置递增运算符
MSTL_ALWAYS_INLINE value_type fetch_sub(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并减去操作
MSTL_ALWAYS_INLINE value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子交换操作
MSTL_ALWAYS_INLINE value_type load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
MSTL_ALWAYS_INLINE value_type fetch_xor(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并异或操作
static constexpr bool is_always_lock_free
MSTL_ALWAYS_INLINE void store(value_type value, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的原子存储操作
MSTL_ALWAYS_INLINE bool compare_exchange_weak(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的简化版弱比较交换操作
value_type operator|=(value_type value) noexcept
位或赋值运算符
MSTL_ALWAYS_INLINE bool compare_exchange_strong(value_type &expected, value_type desired, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作
value_type operator&=(value_type value) noexcept
位与赋值运算符
MSTL_ALWAYS_INLINE value_type exchange(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
MSTL_ALWAYS_INLINE_INLINE bool test_and_set(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的测试并设置标志
MSTL_ALWAYS_INLINE_INLINE bool test(const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的测试标志值
MSTL_ALWAYS_INLINE_INLINE void clear(const memory_order mo=memory_order_seq_cst) volatile noexcept
volatile版本的清除标志
MSTL_ALWAYS_INLINE void wait(const bool old, const memory_order mo=memory_order_seq_cst) const noexcept
等待标志值改变
MSTL_ALWAYS_INLINE void clear(const memory_order mo=memory_order_seq_cst) noexcept
清除标志
MSTL_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
MSTL_ALWAYS_INLINE bool test_and_set(const memory_order mo=memory_order_seq_cst) noexcept
测试并设置标志
MSTL_ALWAYS_INLINE bool test(const memory_order mo=memory_order_seq_cst) const noexcept
测试标志值
MSTL_ALWAYS_INLINE_INLINE void wait(const bool old, const memory_order mo=memory_order_seq_cst) const volatile noexcept
volatile版本的等待标志值改变
MSTL_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
static constexpr bool is_always_lock_free
是否总是无锁
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
简化版强比较交换操作
Float load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
value_type difference_type
差值类型
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版本的原子获取并减去操作
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
减法赋值运算符
MSTL_ALWAYS_INLINE void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
MSTL_ALWAYS_INLINE void notify_one() 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
弱比较交换操作
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
MSTL_ALWAYS_INLINE void notify_all() 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
原子加载操作
MSTL_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
MSTL_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
bool compare_exchange_strong(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
强比较交换操作
bool is_lock_free() const noexcept
检查是否支持无锁操作
value_type fetch_add(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并添加操作
static constexpr size_t required_alignment
对齐需求
MSTL_ALWAYS_INLINE void wait(Float old, const memory_order mo=memory_order_seq_cst) const noexcept
等待值改变
value_type difference_type
差值类型
static constexpr bool is_always_lock_free
是否总是无锁
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
原子获取并减去操作
bool compare_exchange_weak(Float &expected, Float desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
MSTL_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
bool compare_exchange_weak(T &expected, T desire, const memory_order success, const memory_order failure) noexcept
弱比较交换操作
static constexpr bool is_always_lock_free
是否总是无锁
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
原子加载操作
MSTL_ALWAYS_INLINE void wait(T old, const memory_order mo=memory_order_seq_cst) const 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
原子存储操作
MSTL_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
atomic_ref_base(T &value)
构造函数
static constexpr size_t required_alignment
对齐需求
T exchange(T desire, const memory_order mo=memory_order_seq_cst) noexcept
原子交换操作
MSTL_NODISCARD bool is_lock_free() const 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
原子获取并异或操作
static constexpr bool is_always_lock_free
是否总是无锁
static constexpr size_t required_alignment
对齐需求
bool compare_exchange_weak(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版弱比较交换操作
MSTL_ALWAYS_INLINE void notify_one() noexcept
通知一个等待线程
value_type fetch_and(value_type 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_add(value_type value, const memory_order mo=memory_order_seq_cst) 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)
构造函数
MSTL_ALWAYS_INLINE void wait(T old, 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
原子获取并减去操作
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
value_type fetch_or(value_type value, const memory_order mo=memory_order_seq_cst) noexcept
原子获取并或操作
MSTL_ALWAYS_INLINE void notify_all() noexcept
通知所有等待线程
bool compare_exchange_strong(T &expected, T desire, const memory_order mo=memory_order_seq_cst) noexcept
简化版强比较交换操作