2
3
4
5
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
189#if defined(__cplusplus
)
193#if defined(__clang__
) || (defined(__GNUC__
) && (__GNUC__
> 4
|| (__GNUC__
== 4
&& __GNUC_MINOR__
>= 6
)))
194 #pragma GCC diagnostic push
195 #pragma GCC diagnostic ignored "-Wlong-long"
196 #if defined(__clang__
)
197 #pragma GCC diagnostic ignored "-Wc++11-long-long"
201typedef int c89atomic_memory_order;
204typedef signed char c89atomic_int8;
205typedef unsigned char c89atomic_uint8;
206typedef signed short c89atomic_int16;
207typedef unsigned short c89atomic_uint16;
208typedef signed int c89atomic_int32;
209typedef unsigned int c89atomic_uint32;
210#if (defined(_MSC_VER) && !defined(__clang__
)) || defined(__BORLANDC__)
211 typedef signed __int64 c89atomic_int64;
212 typedef unsigned __int64 c89atomic_uint64;
214 typedef signed long long c89atomic_int64;
215 typedef unsigned long long c89atomic_uint64;
219
220
221
222
223
224
225typedef c89atomic_uint32 c89atomic_bool;
230#if !defined(C89ATOMIC_64BIT) && !defined(C89ATOMIC_32BIT)
233 #define C89ATOMIC_64BIT
235 #define C89ATOMIC_32BIT
240#if !defined(C89ATOMIC_64BIT) && !defined(C89ATOMIC_32BIT)
243 #define C89ATOMIC_64BIT
245 #define C89ATOMIC_32BIT
252#if INTPTR_MAX == INT64_MAX
253#define C89ATOMIC_64BIT
255#define C89ATOMIC_32BIT
259#if defined(__x86_64__
) || defined(_M_X64)
261#elif defined(__i386) || defined(_M_IX86) || defined(__i386__)
263#elif defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
264#define C89ATOMIC_ARM64
265#elif defined(__arm__) || defined(_M_ARM)
266#define C89ATOMIC_ARM32
267#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || defined(_ARCH_PPC64)
268#define C89ATOMIC_PPC64
269#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__powerpc) || defined(__ppc) || defined(_ARCH_PPC)
270#define C89ATOMIC_PPC32
273#if defined(C89ATOMIC_ARM32) || defined(C89ATOMIC_ARM64)
281 #define C89ATOMIC_INLINE __forceinline
282#elif defined(__GNUC__
)
284
285
286
287
288
289
290 #if defined(__STRICT_ANSI__) || !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L
)
291 #define C89ATOMIC_INLINE __inline__ __attribute__((always_inline))
293 #define C89ATOMIC_INLINE inline __attribute__((always_inline))
295#elif defined(__WATCOMC__) || defined(__DMC__)
296 #define C89ATOMIC_INLINE __inline
298 #define C89ATOMIC_INLINE
305
306
307
308
309
310
311
312#if !defined(C89ATOMIC_MODERN_MSVC) &&
313 !defined(C89ATOMIC_LEGACY_MSVC) &&
314 !defined(C89ATOMIC_LEGACY_MSVC_ASM) &&
315 !defined(C89ATOMIC_MODERN_GCC) &&
316 !defined(C89ATOMIC_LEGACY_GCC) &&
317 !defined(C89ATOMIC_LEGACY_GCC_ASM)
318 #if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DMC__) || defined(__BORLANDC__)
319 #if (defined(_MSC_VER) && _MSC_VER > 1600
)
321 #define C89ATOMIC_MODERN_MSVC
324 #if defined(C89ATOMIC_X64)
326
327
328
329 #define C89ATOMIC_LEGACY_MSVC
332 #define C89ATOMIC_LEGACY_MSVC_ASM
335 #elif (defined(__GNUC__
) && (__GNUC__
> 4
|| (__GNUC__
== 4
&& __GNUC_MINOR__
>= 7
))) || defined(__clang__
)
337 #define C89ATOMIC_MODERN_GCC
339 #if defined(__GNUC__) && (__GNUC__ > 4
|| (__GNUC__ == 4
&& __GNUC_MINOR__ >= 1
))
341 #define C89ATOMIC_LEGACY_GCC
344 #define C89ATOMIC_LEGACY_GCC_ASM
352
353
354
355
356
357
358
359
360#if defined(C89ATOMIC_MODERN_MSVC) || defined(C89ATOMIC_LEGACY_MSVC)
363 #define c89atomic_memory_order_relaxed 1
364 #define c89atomic_memory_order_consume 2
365 #define c89atomic_memory_order_acquire 3
366 #define c89atomic_memory_order_release 4
367 #define c89atomic_memory_order_acq_rel 5
368 #define c89atomic_memory_order_seq_cst 6
370 #define C89ATOMIC_MSVC_ARM_INTRINSIC_NORETURN(dst, src, order, intrin, c89atomicType, msvcType)
373 case c89atomic_memory_order_relaxed:
375 intrin##_nf((volatile msvcType*)dst, (msvcType)src);
377 case c89atomic_memory_order_consume:
378 case c89atomic_memory_order_acquire:
380 intrin##_acq((volatile msvcType*)dst, (msvcType)src);
382 case c89atomic_memory_order_release:
384 intrin##_rel((volatile msvcType*)dst, (msvcType)src);
386 case c89atomic_memory_order_acq_rel:
387 case c89atomic_memory_order_seq_cst:
390 intrin((volatile msvcType*)dst, (msvcType)src);
394 #define C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, intrin, c89atomicType, msvcType)
395 c89atomicType result;
398 case c89atomic_memory_order_relaxed:
400 result = (c89atomicType)intrin##_nf((volatile msvcType*)dst, (msvcType)src);
402 case c89atomic_memory_order_consume:
403 case c89atomic_memory_order_acquire:
405 result = (c89atomicType)intrin##_acq((volatile msvcType*)dst, (msvcType)src);
407 case c89atomic_memory_order_release:
409 result = (c89atomicType)intrin##_rel((volatile msvcType*)dst, (msvcType)src);
411 case c89atomic_memory_order_acq_rel:
412 case c89atomic_memory_order_seq_cst:
415 result = (c89atomicType)intrin((volatile msvcType*)dst, (msvcType)src);
420 typedef c89atomic_uint32 c89atomic_flag;
422 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_test_and_set_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
424 #if defined(C89ATOMIC_ARM)
426 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, 1, order, _InterlockedExchange, c89atomic_flag,
long);
431 return (c89atomic_flag)_InterlockedExchange((
volatile long*)dst, (
long)1);
436 static C89ATOMIC_INLINE
void c89atomic_flag_clear_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
438 #if defined(C89ATOMIC_ARM)
440 C89ATOMIC_MSVC_ARM_INTRINSIC_NORETURN(dst, 0, order, _InterlockedExchange, c89atomic_flag,
long);
445 _InterlockedExchange((
volatile long*)dst, (
long)0);
450 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_load_explicit(
volatile const c89atomic_flag* dst, c89atomic_memory_order order)
453 return (c89atomic_uint32)_InterlockedCompareExchange((
volatile long*)dst, 0, 0);
457#if defined(C89ATOMIC_LEGACY_MSVC_ASM)
458 #define c89atomic_memory_order_relaxed 1
459 #define c89atomic_memory_order_consume 2
460 #define c89atomic_memory_order_acquire 3
461 #define c89atomic_memory_order_release 4
462 #define c89atomic_memory_order_acq_rel 5
463 #define c89atomic_memory_order_seq_cst 6
465 typedef c89atomic_uint32 c89atomic_flag;
467 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_test_and_set_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
469 c89atomic_flag result = 0;
482 static C89ATOMIC_INLINE
void c89atomic_flag_clear_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
484 if (order == c89atomic_memory_order_relaxed) {
487 mov dword ptr [esi], 0
498 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_load_explicit(
volatile const c89atomic_flag* dst, c89atomic_memory_order order)
500 c89atomic_flag result = 0;
502 if (order == c89atomic_memory_order_relaxed) {
508 }
else if (order <= c89atomic_memory_order_release) {
512 lock add dword ptr [esp], 0
517 lock add dword ptr [esp], 0
521 lock add dword ptr [esp], 0
529#if defined(C89ATOMIC_MODERN_GCC
)
530 #define c89atomic_memory_order_relaxed __ATOMIC_RELAXED
531 #define c89atomic_memory_order_consume __ATOMIC_CONSUME
532 #define c89atomic_memory_order_acquire __ATOMIC_ACQUIRE
533 #define c89atomic_memory_order_release __ATOMIC_RELEASE
534 #define c89atomic_memory_order_acq_rel __ATOMIC_ACQ_REL
535 #define c89atomic_memory_order_seq_cst __ATOMIC_SEQ_CST
537 typedef c89atomic_uint32 c89atomic_flag;
539 #define c89atomic_flag_test_and_set_explicit(dst, order) __atomic_exchange_n(dst, 1
, order)
540 #define c89atomic_flag_clear_explicit(dst, order) __atomic_store_n(dst, 0
, order)
541 #define c89atomic_flag_load_explicit(dst, order) __atomic_load_n(dst, order)
544#if defined(C89ATOMIC_LEGACY_GCC)
545 #define c89atomic_memory_order_relaxed 1
546 #define c89atomic_memory_order_consume 2
547 #define c89atomic_memory_order_acquire 3
548 #define c89atomic_memory_order_release 4
549 #define c89atomic_memory_order_acq_rel 5
550 #define c89atomic_memory_order_seq_cst 6
552 typedef c89atomic_uint32 c89atomic_flag;
554 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_test_and_set_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
556 if (order > c89atomic_memory_order_acquire) {
557 __sync_synchronize();
560 return __sync_lock_test_and_set(dst, 1);
563 static C89ATOMIC_INLINE
void c89atomic_flag_clear_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
565 if (order > c89atomic_memory_order_release) {
566 __sync_synchronize();
569 __sync_lock_release(dst);
572 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_load_explicit(
volatile const c89atomic_flag* dst, c89atomic_memory_order order)
575 return __sync_val_compare_and_swap((c89atomic_flag*)dst, 0, 0);
579#if defined(C89ATOMIC_LEGACY_GCC_ASM)
580 #define c89atomic_memory_order_relaxed 1
581 #define c89atomic_memory_order_consume 2
582 #define c89atomic_memory_order_acquire 3
583 #define c89atomic_memory_order_release 4
584 #define c89atomic_memory_order_acq_rel 5
585 #define c89atomic_memory_order_seq_cst 6
588
589
590
591
592
593
594
595
596
597
598
599
600 #if defined(C89ATOMIC_X86)
601 #define c89atomic_thread_fence(order) __asm__ __volatile__("lock; addl $0, (%%esp)" ::: "memory")
602 #elif defined(C89ATOMIC_X64)
603 #define c89atomic_thread_fence(order) __asm__ __volatile__("lock; addq $0, (%%rsp)" ::: "memory")
605 #error Unsupported architecture.
609 #define C89ATOMIC_XCHG_GCC_X86(instructionSizeSuffix, result, dst, src)
610 __asm__ __volatile__(
611 "xchg"instructionSizeSuffix" %0, %1"
620 #define C89ATOMIC_LOAD_RELAXED_GCC_X86(instructionSizeSuffix, result, dst)
621 __asm__ __volatile__(
622 "mov"instructionSizeSuffix" %1, %0"
627 #define C89ATOMIC_LOAD_RELEASE_GCC_X86(instructionSizeSuffix, result, dst)
628 c89atomic_thread_fence(c89atomic_memory_order_release);
629 __asm__ __volatile__(
630 "mov"instructionSizeSuffix" %1, %0"
636 #define C89ATOMIC_LOAD_SEQ_CST_GCC_X86(instructionSizeSuffix, result, dst)
637 c89atomic_thread_fence(c89atomic_memory_order_seq_cst);
638 __asm__ __volatile__(
639 "mov"instructionSizeSuffix" %1, %0"
644 c89atomic_thread_fence(c89atomic_memory_order_seq_cst)
647 typedef c89atomic_uint32 c89atomic_flag;
649 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_test_and_set_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
651 c89atomic_flag result;
652 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
655 C89ATOMIC_XCHG_GCC_X86(
"l", result, dst, 1);
659 #error Unsupported architecture.
665 static C89ATOMIC_INLINE
void c89atomic_flag_clear_explicit(
volatile c89atomic_flag* dst, c89atomic_memory_order order)
667 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
670 if (order == c89atomic_memory_order_relaxed) {
671 __asm__ __volatile__(
675 }
else if (order == c89atomic_memory_order_release) {
676 __asm__ __volatile__(
683 c89atomic_flag tmp = 0;
684 __asm__ __volatile__(
696 #error Unsupported architecture.
701 static C89ATOMIC_INLINE c89atomic_flag c89atomic_flag_load_explicit(
volatile const c89atomic_flag* dst, c89atomic_memory_order order)
703 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
705 c89atomic_flag result;
707 if (order == c89atomic_memory_order_relaxed) {
708 C89ATOMIC_LOAD_RELAXED_GCC_X86(
"l", result, dst);
709 }
else if (order <= c89atomic_memory_order_release) {
710 C89ATOMIC_LOAD_RELEASE_GCC_X86(
"l", result, dst);
712 C89ATOMIC_LOAD_SEQ_CST_GCC_X86(
"l", result, dst);
719 #error Unsupported architecture.
731
732
733
734typedef c89atomic_flag c89atomic_spinlock;
736static C89ATOMIC_INLINE void c89atomic_spinlock_lock(
volatile c89atomic_spinlock* pSpinlock)
749static C89ATOMIC_INLINE void c89atomic_spinlock_unlock(
volatile c89atomic_spinlock* pSpinlock)
756extern c89atomic_spinlock c89atomic_global_lock;
762
763
764
765
766
767
768
769#if defined(C89ATOMIC_MODERN_MSVC) || defined(C89ATOMIC_LEGACY_MSVC) || defined(C89ATOMIC_LEGACY_MSVC_ASM) || defined(C89ATOMIC_LEGACY_GCC) || defined(C89ATOMIC_LEGACY_GCC_ASM)
770 #if defined(C89ATOMIC_X64) || (defined(C89ATOMIC_X86) && ((defined(__GNUC__) && defined(__i486__)) || (defined(_M_IX86) && _M_IX86 >= 400
)))
771 #if defined(C89ATOMIC_LEGACY_MSVC) && defined(C89ATOMIC_X64)
774 #define C89ATOMIC_IS_LOCK_FREE_8 1
775 #define C89ATOMIC_IS_LOCK_FREE_16 1
777 #define C89ATOMIC_IS_LOCK_FREE_32 1
778 #if defined(C89ATOMIC_X64) || (defined(C89ATOMIC_X86) && ((defined(__GNUC__) && defined(__i586__)) || (defined(_M_IX86) && _M_IX86 >= 500
)))
779 #define C89ATOMIC_IS_LOCK_FREE_64 1
787 #if defined(C89ATOMIC_ARM32) || defined(C89ATOMIC_ARM64)
788 #define C89ATOMIC_IS_LOCK_FREE_8 1
789 #define C89ATOMIC_IS_LOCK_FREE_16 1
790 #define C89ATOMIC_IS_LOCK_FREE_32 1
791 #if defined(C89ATOMIC_ARM64) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
792 #define C89ATOMIC_IS_LOCK_FREE_64 1
796 #if defined(C89ATOMIC_PPC32) || defined(C89ATOMIC_PPC64)
798
799
800
801
802
803
804
805
806 #if (defined(__GNUC__) && (__GNUC__ < 4
|| (__GNUC__ == 4
&& __GNUC_MINOR__ < 7
))) && !defined(__clang__)
809 #define C89ATOMIC_IS_LOCK_FREE_8 1
810 #define C89ATOMIC_IS_LOCK_FREE_16 1
812 #define C89ATOMIC_IS_LOCK_FREE_32 1
813 #if defined(C89ATOMIC_PPC64)
814 #define C89ATOMIC_IS_LOCK_FREE_64 1
818 static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_8(
volatile void* ptr)
821 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
828 static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_16(
volatile void* ptr)
831 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
838 static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_32(
volatile void* ptr)
841 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
848 static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_64(
volatile void* ptr)
851 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
860#define C89ATOMIC_COMPARE_AND_SWAP_LOCK(sizeInBits, dst, expected, replacement)
861 c89atomic_uint##sizeInBits result;
862 c89atomic_spinlock_lock(&c89atomic_global_lock);
865 if (result == expected) {
869 c89atomic_spinlock_unlock(&c89atomic_global_lock);
873#define C89ATOMIC_LOAD_EXPLICIT_LOCK(sizeInBits, ptr, order)
874 c89atomic_uint##sizeInBits result;
875 c89atomic_spinlock_lock(&c89atomic_global_lock);
880 c89atomic_spinlock_unlock(&c89atomic_global_lock);
884#define C89ATOMIC_STORE_EXPLICIT_LOCK(sizeInBits, dst, src, order)
885 c89atomic_spinlock_lock(&c89atomic_global_lock);
890 c89atomic_spinlock_unlock(&c89atomic_global_lock)
892#define C89ATOMIC_STORE_EXPLICIT_CAS(sizeInBits, dst, src, order)
893 c89atomic_uint##sizeInBits oldValue;
896 } while (c89atomic_compare_and_swap_##sizeInBits(dst, oldValue, src) != oldValue);
900#define C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(sizeInBits, dst, src, order)
901 c89atomic_uint##sizeInBits result;
902 c89atomic_spinlock_lock(&c89atomic_global_lock);
908 c89atomic_spinlock_unlock(&c89atomic_global_lock);
911#define C89ATOMIC_EXCHANGE_EXPLICIT_CAS(sizeInBits, dst, src, order)
912 c89atomic_uint##sizeInBits oldValue;
915 } while (c89atomic_compare_and_swap_##sizeInBits(dst, oldValue, src) != oldValue);
920#define C89ATOMIC_FETCH_ADD_LOCK(sizeInBits, dst, src, order)
921 c89atomic_uint##sizeInBits result;
922 c89atomic_spinlock_lock(&c89atomic_global_lock);
928 c89atomic_spinlock_unlock(&c89atomic_global_lock);
931#define C89ATOMIC_FETCH_ADD_CAS(sizeInBits, dst, src, order)
932 c89atomic_uint##sizeInBits oldValue;
933 c89atomic_uint##sizeInBits newValue;
936 newValue = oldValue + src;
937 } while (c89atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue);
942#define C89ATOMIC_FETCH_AND_CAS(sizeInBits, dst, src, order)
943 c89atomic_uint##sizeInBits oldValue;
944 c89atomic_uint##sizeInBits newValue;
947 newValue = (c89atomic_uint##sizeInBits)(oldValue & src);
948 } while (c89atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue);
953#define C89ATOMIC_FETCH_OR_CAS(sizeInBits, dst, src, order)
954 c89atomic_uint##sizeInBits oldValue;
955 c89atomic_uint##sizeInBits newValue;
958 newValue = (c89atomic_uint##sizeInBits)(oldValue | src);
959 } while (c89atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue);
964#define C89ATOMIC_FETCH_XOR_CAS(sizeInBits, dst, src, order)
965 c89atomic_uint##sizeInBits oldValue;
966 c89atomic_uint##sizeInBits newValue;
969 newValue = (c89atomic_uint##sizeInBits)(oldValue ^ src);
970 } while (c89atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue);
975#if defined(C89ATOMIC_MODERN_MSVC) || defined(C89ATOMIC_LEGACY_MSVC)
977
978
979
980 #define C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, expected, replacement, order, intrin, c89atomicType, msvcType)
981 c89atomicType result;
984 case c89atomic_memory_order_relaxed:
986 result = (c89atomicType)intrin##_nf((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement);
988 case c89atomic_memory_order_consume:
989 case c89atomic_memory_order_acquire:
991 result = (c89atomicType)intrin##_acq((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement);
993 case c89atomic_memory_order_release:
995 result = (c89atomicType)intrin##_rel((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement);
997 case c89atomic_memory_order_acq_rel:
998 case c89atomic_memory_order_seq_cst:
1001 result = (c89atomicType)intrin((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement);
1008 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1009 #define c89atomic_compare_and_swap_8( dst, expected, replacement) (c89atomic_uint8 )_InterlockedCompareExchange8((volatile char*)dst, (char)replacement, (char)expected)
1011 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_compare_and_swap_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 replacement)
1013 C89ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
1017 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1018 #define c89atomic_compare_and_swap_16(dst, expected, replacement) (c89atomic_uint16)_InterlockedCompareExchange16((volatile short*)dst, (short)replacement, (short)expected)
1020 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_compare_and_swap_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 replacement)
1022 C89ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
1026 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1027 #define c89atomic_compare_and_swap_32(dst, expected, replacement) (c89atomic_uint32)_InterlockedCompareExchange((volatile long*)dst, (long)replacement, (long)expected)
1029 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_compare_and_swap_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 replacement)
1031 C89ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
1035 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1036 #define c89atomic_compare_and_swap_64(dst, expected, replacement) (c89atomic_uint64)_InterlockedCompareExchange64((volatile c89atomic_int64*)dst, (c89atomic_int64)replacement, (c89atomic_int64)expected)
1038 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_compare_and_swap_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 replacement)
1040 C89ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
1046 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(
volatile const c89atomic_uint8* ptr, c89atomic_memory_order order)
1048 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1050 #if defined(C89ATOMIC_ARM)
1052 C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange8, c89atomic_uint8,
char);
1057 return c89atomic_compare_and_swap_8((
volatile c89atomic_uint8*)ptr, 0, 0);
1063 C89ATOMIC_LOAD_EXPLICIT_LOCK(8, ptr, order);
1068 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(
volatile const c89atomic_uint16* ptr, c89atomic_memory_order order)
1070 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1072 #if defined(C89ATOMIC_ARM)
1074 C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange16, c89atomic_uint16,
short);
1079 return c89atomic_compare_and_swap_16((
volatile c89atomic_uint16*)ptr, 0, 0);
1085 C89ATOMIC_LOAD_EXPLICIT_LOCK(16, ptr, order);
1090 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(
volatile const c89atomic_uint32* ptr, c89atomic_memory_order order)
1092 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1094 #if defined(C89ATOMIC_ARM)
1096 C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange, c89atomic_uint32,
long);
1101 return c89atomic_compare_and_swap_32((
volatile c89atomic_uint32*)ptr, 0, 0);
1107 C89ATOMIC_LOAD_EXPLICIT_LOCK(32, ptr, order);
1112 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(
volatile const c89atomic_uint64* ptr, c89atomic_memory_order order)
1114 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1116 #if defined(C89ATOMIC_ARM)
1118 C89ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange64, c89atomic_uint64,
long long);
1123 return c89atomic_compare_and_swap_64((
volatile c89atomic_uint64*)ptr, 0, 0);
1129 C89ATOMIC_LOAD_EXPLICIT_LOCK(64, ptr, order);
1136 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_exchange_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1138 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1140 #if defined(C89ATOMIC_ARM)
1142 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange8, c89atomic_uint8,
char);
1147 return (c89atomic_uint8)_InterlockedExchange8((
volatile char*)dst, (
char)src);
1153 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
1158 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_exchange_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1160 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1162 #if defined(C89ATOMIC_ARM)
1164 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange16, c89atomic_uint16,
short);
1169 return (c89atomic_uint16)_InterlockedExchange16((
volatile short*)dst, (
short)src);
1175 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
1180 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_exchange_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1182 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1184 #if defined(C89ATOMIC_ARM)
1186 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange, c89atomic_uint32,
long);
1191 return (c89atomic_uint32)_InterlockedExchange((
volatile long*)dst, (
long)src);
1197 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
1202 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_exchange_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1204 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
1207 #if defined(C89ATOMIC_32BIT)
1209 C89ATOMIC_EXCHANGE_EXPLICIT_CAS(64, dst, src, order);
1213 #if defined(C89ATOMIC_ARM)
1215 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange64, c89atomic_uint64,
long long);
1220 return (c89atomic_uint64)_InterlockedExchange64((
volatile long long*)dst, (
long long)src);
1228 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
1235 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_add_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1237 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1239 #if defined(C89ATOMIC_ARM)
1241 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd8, c89atomic_uint8,
char);
1246 return (c89atomic_uint8)_InterlockedExchangeAdd8((
volatile char*)dst, (
char)src);
1252 C89ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
1257 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_add_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1259 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1261 #if defined(C89ATOMIC_ARM)
1263 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd16, c89atomic_uint16,
short);
1268 return (c89atomic_uint16)_InterlockedExchangeAdd16((
volatile short*)dst, (
short)src);
1274 C89ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
1279 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_add_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1281 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1283 #if defined(C89ATOMIC_ARM)
1285 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd, c89atomic_uint32,
long);
1290 return (c89atomic_uint32)_InterlockedExchangeAdd((
volatile long*)dst, (
long)src);
1296 C89ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
1301 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_add_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1303 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
1306 #if defined(C89ATOMIC_32BIT)
1308 C89ATOMIC_FETCH_ADD_CAS(64, dst, src, order);
1312 #if defined(C89ATOMIC_ARM)
1314 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd64, c89atomic_uint64,
long long);
1319 return (c89atomic_uint64)_InterlockedExchangeAdd64((
volatile long long*)dst, (
long long)src);
1327 C89ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
1334 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_sub_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1336 return c89atomic_fetch_add_explicit_8(dst, (c89atomic_uint8)(-(c89atomic_int8)src), order);
1339 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_sub_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1341 return c89atomic_fetch_add_explicit_16(dst, (c89atomic_uint16)(-(c89atomic_int16)src), order);
1344 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_sub_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1346 return c89atomic_fetch_add_explicit_32(dst, (c89atomic_uint32)(-(c89atomic_int32)src), order);
1349 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_sub_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1351 return c89atomic_fetch_add_explicit_64(dst, (c89atomic_uint64)(-(c89atomic_int64)src), order);
1356 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_and_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1358 #if defined(C89ATOMIC_ARM)
1360 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd8, c89atomic_uint8,
char);
1364 C89ATOMIC_FETCH_AND_CAS(8, dst, src, order);
1369 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_and_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1371 #if defined(C89ATOMIC_ARM)
1373 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd16, c89atomic_uint16,
short);
1377 C89ATOMIC_FETCH_AND_CAS(16, dst, src, order);
1382 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_and_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1384 #if defined(C89ATOMIC_ARM)
1386 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd, c89atomic_uint32,
long);
1390 C89ATOMIC_FETCH_AND_CAS(32, dst, src, order);
1395 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_and_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1397 #if defined(C89ATOMIC_ARM)
1399 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd64, c89atomic_uint64,
long long);
1403 C89ATOMIC_FETCH_AND_CAS(64, dst, src, order);
1410 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_or_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1412 #if defined(C89ATOMIC_ARM)
1414 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr8, c89atomic_uint8,
char);
1418 C89ATOMIC_FETCH_OR_CAS(8, dst, src, order);
1423 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_or_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1425 #if defined(C89ATOMIC_ARM)
1427 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr16, c89atomic_uint16,
short);
1431 C89ATOMIC_FETCH_OR_CAS(16, dst, src, order);
1436 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_or_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1438 #if defined(C89ATOMIC_ARM)
1440 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr, c89atomic_uint32,
long);
1444 C89ATOMIC_FETCH_OR_CAS(32, dst, src, order);
1449 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_or_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1451 #if defined(C89ATOMIC_ARM)
1453 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr64, c89atomic_uint64,
long long);
1457 C89ATOMIC_FETCH_OR_CAS(64, dst, src, order);
1464 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_xor_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1466 #if defined(C89ATOMIC_ARM)
1468 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor8, c89atomic_uint8,
char);
1472 C89ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
1477 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_xor_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1479 #if defined(C89ATOMIC_ARM)
1481 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor16, c89atomic_uint16,
short);
1485 C89ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
1490 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_xor_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1492 #if defined(C89ATOMIC_ARM)
1494 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor, c89atomic_uint32,
long);
1498 C89ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
1503 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_xor_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1505 #if defined(C89ATOMIC_ARM)
1507 C89ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor64, c89atomic_uint64,
long long);
1511 C89ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
1518 #define c89atomic_store_explicit_8( dst, src, order) (void)c89atomic_exchange_explicit_8 (dst, src, order)
1519 #define c89atomic_store_explicit_16(dst, src, order) (void)c89atomic_exchange_explicit_16(dst, src, order)
1520 #define c89atomic_store_explicit_32(dst, src, order) (void)c89atomic_exchange_explicit_32(dst, src, order)
1521 #define c89atomic_store_explicit_64(dst, src, order) (void)c89atomic_exchange_explicit_64(dst, src, order)
1526 #if defined(C89ATOMIC_X64)
1527 #define c89atomic_thread_fence(order) __faststorefence(), (void)order
1528 #elif defined(C89ATOMIC_ARM64)
1529 #define c89atomic_thread_fence(order) __dmb(_ARM64_BARRIER_ISH), (void)order
1531 static C89ATOMIC_INLINE
void c89atomic_thread_fence(c89atomic_memory_order order)
1533 volatile c89atomic_uint32 barrier = 0;
1534 c89atomic_fetch_add_explicit_32(&barrier, 0, order);
1539 #define c89atomic_signal_fence(order) _ReadWriteBarrier(), (void)order
1543#if defined(C89ATOMIC_LEGACY_MSVC_ASM)
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1575 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_compare_and_swap_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 replacement)
1577 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1579 c89atomic_uint8 result = 0;
1585 lock cmpxchg [ecx], dl
1593 C89ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
1598 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_compare_and_swap_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 replacement)
1600 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1602 c89atomic_uint16 result = 0;
1608 lock cmpxchg [ecx], dx
1616 C89ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
1621 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_compare_and_swap_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 replacement)
1623 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1625 c89atomic_uint32 result = 0;
1630 mov edx, replacement
1631 lock cmpxchg [ecx], edx
1639 C89ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
1644 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_compare_and_swap_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 replacement)
1646 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
1648 c89atomic_uint32 resultEAX = 0;
1649 c89atomic_uint32 resultEDX = 0;
1653 mov eax, dword ptr expected
1654 mov edx, dword ptr expected + 4
1655 mov ebx, dword ptr replacement
1656 mov ecx, dword ptr replacement + 4
1657 lock cmpxchg8b qword ptr [esi]
1662 return ((c89atomic_uint64)resultEDX << 32) | resultEAX;
1666 C89ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
1673 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(
volatile const c89atomic_uint8* dst, c89atomic_memory_order order)
1675 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1677 c89atomic_uint8 result = 0;
1679 if (order == c89atomic_memory_order_relaxed) {
1685 }
else if (order <= c89atomic_memory_order_release) {
1689 lock add dword ptr [esp], 0
1694 lock add dword ptr [esp], 0
1698 lock add dword ptr [esp], 0
1706 C89ATOMIC_LOAD_EXPLICIT_LOCK(8, dst, order);
1711 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(
volatile const c89atomic_uint16* dst, c89atomic_memory_order order)
1713 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1715 c89atomic_uint16 result = 0;
1717 if (order == c89atomic_memory_order_relaxed) {
1723 }
else if (order <= c89atomic_memory_order_release) {
1727 lock add dword ptr [esp], 0
1732 lock add dword ptr [esp], 0
1736 lock add dword ptr [esp], 0
1744 C89ATOMIC_LOAD_EXPLICIT_LOCK(16, dst, order);
1749 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(
volatile const c89atomic_uint32* dst, c89atomic_memory_order order)
1751 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1753 c89atomic_uint32 result = 0;
1755 if (order == c89atomic_memory_order_relaxed) {
1761 }
else if (order <= c89atomic_memory_order_release) {
1765 lock add dword ptr [esp], 0
1770 lock add dword ptr [esp], 0
1774 lock add dword ptr [esp], 0
1782 C89ATOMIC_LOAD_EXPLICIT_LOCK(32, dst, order);
1787 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(
volatile const c89atomic_uint64* dst, c89atomic_memory_order order)
1790 return c89atomic_compare_and_swap_64((
volatile c89atomic_uint64*)dst, 0, 0);
1795 static C89ATOMIC_INLINE
void __stdcall c89atomic_store_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1798 if (order == c89atomic_memory_order_relaxed) {
1805 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1815 C89ATOMIC_STORE_EXPLICIT_LOCK(8, dst, src, order);
1821 static C89ATOMIC_INLINE
void __stdcall c89atomic_store_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1824 if (order == c89atomic_memory_order_relaxed) {
1831 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1841 C89ATOMIC_STORE_EXPLICIT_LOCK(16, dst, src, order);
1847 static C89ATOMIC_INLINE
void __stdcall c89atomic_store_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1850 if (order == c89atomic_memory_order_relaxed) {
1857 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1867 C89ATOMIC_STORE_EXPLICIT_LOCK(32, dst, src, order);
1873 static C89ATOMIC_INLINE
void __stdcall c89atomic_store_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1875 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
1877 C89ATOMIC_STORE_EXPLICIT_CAS(64, dst, src, order);
1881 C89ATOMIC_STORE_EXPLICIT_LOCK(64, dst, src, order);
1888 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_exchange_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1890 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1892 c89atomic_uint8 result = 0;
1906 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
1911 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_exchange_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1913 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1915 c89atomic_uint16 result = 0;
1929 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
1934 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_exchange_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
1936 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
1938 c89atomic_uint32 result = 0;
1952 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
1957 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_exchange_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
1959 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
1961 C89ATOMIC_EXCHANGE_EXPLICIT_CAS(64, dst, src, order);
1965 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
1972 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_add_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
1974 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
1976 c89atomic_uint8 result = 0;
1990 C89ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
1995 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_add_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
1997 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
1999 c89atomic_uint16 result = 0;
2013 C89ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
2018 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_add_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2020 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2022 c89atomic_uint32 result = 0;
2028 lock xadd [ecx], eax
2036 C89ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
2041 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_add_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2043 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2045 C89ATOMIC_FETCH_ADD_CAS(64, dst, src, order);
2049 C89ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
2056 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_sub_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2058 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2060 c89atomic_uint8 result = 0;
2075 C89ATOMIC_FETCH_ADD_LOCK(8, dst, (c89atomic_uint8)(-(c89atomic_int8)src), order);
2080 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_sub_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2082 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2084 c89atomic_uint16 result = 0;
2099 C89ATOMIC_FETCH_ADD_LOCK(16, dst, (c89atomic_uint16)(-(c89atomic_int16)src), order);
2104 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_sub_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2106 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2108 c89atomic_uint32 result = 0;
2115 lock xadd [ecx], eax
2123 C89ATOMIC_FETCH_ADD_LOCK(32, dst, (c89atomic_uint32)(-(c89atomic_int32)src), order);
2128 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_sub_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2130 C89ATOMIC_FETCH_ADD_CAS(64, dst, (c89atomic_uint64)(-(c89atomic_int64)src), order);
2134 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_and_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2136 C89ATOMIC_FETCH_AND_CAS(8, dst, src, order);
2139 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_and_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2141 C89ATOMIC_FETCH_AND_CAS(16, dst, src, order);
2144 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_and_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2146 C89ATOMIC_FETCH_AND_CAS(32, dst, src, order);
2149 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_and_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2151 C89ATOMIC_FETCH_AND_CAS(64, dst, src, order);
2155 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_or_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2157 C89ATOMIC_FETCH_OR_CAS(8, dst, src, order);
2160 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_or_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2162 C89ATOMIC_FETCH_OR_CAS(16, dst, src, order);
2165 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_or_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2167 C89ATOMIC_FETCH_OR_CAS(32, dst, src, order);
2170 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_or_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2172 C89ATOMIC_FETCH_OR_CAS(64, dst, src, order);
2176 static C89ATOMIC_INLINE c89atomic_uint8
__stdcall c89atomic_fetch_xor_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2178 C89ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
2181 static C89ATOMIC_INLINE c89atomic_uint16
__stdcall c89atomic_fetch_xor_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2183 C89ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
2186 static C89ATOMIC_INLINE c89atomic_uint32
__stdcall c89atomic_fetch_xor_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2188 C89ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
2191 static C89ATOMIC_INLINE c89atomic_uint64
__stdcall c89atomic_fetch_xor_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2193 C89ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
2198 static C89ATOMIC_INLINE
void __stdcall c89atomic_thread_fence(c89atomic_memory_order order)
2202 lock add dword ptr [esp], 0
2207 #define c89atomic_signal_fence(order) __asm {}; (void)order
2210#if defined(C89ATOMIC_MODERN_GCC
)
2211 #define C89ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE
2213 #define c89atomic_thread_fence(order) __atomic_thread_fence(order)
2214 #define c89atomic_signal_fence(order) __atomic_signal_fence(order)
2216 #define c89atomic_is_lock_free_8(ptr) __atomic_is_lock_free(1
, ptr)
2217 #define c89atomic_is_lock_free_16(ptr) __atomic_is_lock_free(2
, ptr)
2218 #define c89atomic_is_lock_free_32(ptr) __atomic_is_lock_free(4
, ptr)
2219 #define c89atomic_is_lock_free_64(ptr) __atomic_is_lock_free(8
, ptr)
2221 #define c89atomic_store_explicit_8( dst, src, order) __atomic_store_n(dst, src, order)
2222 #define c89atomic_store_explicit_16(dst, src, order) __atomic_store_n(dst, src, order)
2223 #define c89atomic_store_explicit_32(dst, src, order) __atomic_store_n(dst, src, order)
2224 #define c89atomic_store_explicit_64(dst, src, order) __atomic_store_n(dst, src, order)
2226 #define c89atomic_load_explicit_8( dst, order) __atomic_load_n(dst, order)
2227 #define c89atomic_load_explicit_16(dst, order) __atomic_load_n(dst, order)
2228 #define c89atomic_load_explicit_32(dst, order) __atomic_load_n(dst, order)
2229 #define c89atomic_load_explicit_64(dst, order) __atomic_load_n(dst, order)
2231 #define c89atomic_exchange_explicit_8( dst, src, order) __atomic_exchange_n(dst, src, order)
2232 #define c89atomic_exchange_explicit_16(dst, src, order) __atomic_exchange_n(dst, src, order)
2233 #define c89atomic_exchange_explicit_32(dst, src, order) __atomic_exchange_n(dst, src, order)
2234 #define c89atomic_exchange_explicit_64(dst, src, order) __atomic_exchange_n(dst, src, order)
2236 #define c89atomic_compare_exchange_strong_explicit_8( dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0
, successOrder, failureOrder)
2237 #define c89atomic_compare_exchange_strong_explicit_16(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0
, successOrder, failureOrder)
2238 #define c89atomic_compare_exchange_strong_explicit_32(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0
, successOrder, failureOrder)
2239 #define c89atomic_compare_exchange_strong_explicit_64(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0
, successOrder, failureOrder)
2241 #define c89atomic_compare_exchange_weak_explicit_8( dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1
, successOrder, failureOrder)
2242 #define c89atomic_compare_exchange_weak_explicit_16(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1
, successOrder, failureOrder)
2243 #define c89atomic_compare_exchange_weak_explicit_32(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1
, successOrder, failureOrder)
2244 #define c89atomic_compare_exchange_weak_explicit_64(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1
, successOrder, failureOrder)
2246 #define c89atomic_fetch_add_explicit_8( dst, src, order) __atomic_fetch_add(dst, src, order)
2247 #define c89atomic_fetch_add_explicit_16(dst, src, order) __atomic_fetch_add(dst, src, order)
2248 #define c89atomic_fetch_add_explicit_32(dst, src, order) __atomic_fetch_add(dst, src, order)
2249 #define c89atomic_fetch_add_explicit_64(dst, src, order) __atomic_fetch_add(dst, src, order)
2251 #define c89atomic_fetch_sub_explicit_8( dst, src, order) __atomic_fetch_sub(dst, src, order)
2252 #define c89atomic_fetch_sub_explicit_16(dst, src, order) __atomic_fetch_sub(dst, src, order)
2253 #define c89atomic_fetch_sub_explicit_32(dst, src, order) __atomic_fetch_sub(dst, src, order)
2254 #define c89atomic_fetch_sub_explicit_64(dst, src, order) __atomic_fetch_sub(dst, src, order)
2256 #define c89atomic_fetch_or_explicit_8( dst, src, order) __atomic_fetch_or(dst, src, order)
2257 #define c89atomic_fetch_or_explicit_16(dst, src, order) __atomic_fetch_or(dst, src, order)
2258 #define c89atomic_fetch_or_explicit_32(dst, src, order) __atomic_fetch_or(dst, src, order)
2259 #define c89atomic_fetch_or_explicit_64(dst, src, order) __atomic_fetch_or(dst, src, order)
2261 #define c89atomic_fetch_xor_explicit_8( dst, src, order) __atomic_fetch_xor(dst, src, order)
2262 #define c89atomic_fetch_xor_explicit_16(dst, src, order) __atomic_fetch_xor(dst, src, order)
2263 #define c89atomic_fetch_xor_explicit_32(dst, src, order) __atomic_fetch_xor(dst, src, order)
2264 #define c89atomic_fetch_xor_explicit_64(dst, src, order) __atomic_fetch_xor(dst, src, order)
2266 #define c89atomic_fetch_and_explicit_8( dst, src, order) __atomic_fetch_and(dst, src, order)
2267 #define c89atomic_fetch_and_explicit_16(dst, src, order) __atomic_fetch_and(dst, src, order)
2268 #define c89atomic_fetch_and_explicit_32(dst, src, order) __atomic_fetch_and(dst, src, order)
2269 #define c89atomic_fetch_and_explicit_64(dst, src, order) __atomic_fetch_and(dst, src, order)
2272 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_compare_and_swap_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 replacement)
2274 __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
2278 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_compare_and_swap_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 replacement)
2280 __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
2284 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_compare_and_swap_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 replacement)
2286 __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303 #if defined(__clang__
)
2304 #pragma clang diagnostic push
2305 #if __clang_major__
>= 8
2306 #pragma clang diagnostic ignored "-Watomic-alignment"
2309 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_compare_and_swap_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 replacement)
2311 __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
2314 #if defined(__clang__
)
2315 #pragma clang diagnostic pop
2319#if defined(C89ATOMIC_LEGACY_GCC) || defined(C89ATOMIC_LEGACY_GCC_ASM)
2320 #define c89atomic_signal_fence(order) __asm__ __volatile__("":::"memory")
2322 #if defined(C89ATOMIC_LEGACY_GCC)
2324 #define c89atomic_thread_fence(order) __sync_synchronize(), (void)order
2328 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_compare_and_swap_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 replacement)
2330 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2332 return __sync_val_compare_and_swap(dst, expected, replacement);
2336 C89ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
2341 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_compare_and_swap_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 replacement)
2343 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2345 return __sync_val_compare_and_swap(dst, expected, replacement);
2349 C89ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
2354 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_compare_and_swap_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 replacement)
2356 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2358 return __sync_val_compare_and_swap(dst, expected, replacement);
2362 C89ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
2367 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_compare_and_swap_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 replacement)
2369 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2371 return __sync_val_compare_and_swap(dst, expected, replacement);
2375 C89ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
2382 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(
volatile const c89atomic_uint8* ptr, c89atomic_memory_order order)
2384 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2387 return c89atomic_compare_and_swap_8((c89atomic_uint8*)ptr, 0, 0);
2391 C89ATOMIC_LOAD_EXPLICIT_LOCK(8, ptr, order);
2396 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(
volatile const c89atomic_uint16* ptr, c89atomic_memory_order order)
2398 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2401 return c89atomic_compare_and_swap_16((c89atomic_uint16*)ptr, 0, 0);
2405 C89ATOMIC_LOAD_EXPLICIT_LOCK(16, ptr, order);
2410 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(
volatile const c89atomic_uint32* ptr, c89atomic_memory_order order)
2412 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2415 return c89atomic_compare_and_swap_32((c89atomic_uint32*)ptr, 0, 0);
2419 C89ATOMIC_LOAD_EXPLICIT_LOCK(32, ptr, order);
2424 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(
volatile const c89atomic_uint64* ptr, c89atomic_memory_order order)
2426 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2429 return c89atomic_compare_and_swap_64((c89atomic_uint64*)ptr, 0, 0);
2433 C89ATOMIC_LOAD_EXPLICIT_LOCK(64, ptr, order);
2441 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_exchange_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2443 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2445 if (order > c89atomic_memory_order_acquire) {
2446 __sync_synchronize();
2449 return __sync_lock_test_and_set(dst, src);
2453 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
2458 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_exchange_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2460 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2462 if (order > c89atomic_memory_order_acquire) {
2463 __sync_synchronize();
2466 return __sync_lock_test_and_set(dst, src);
2470 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
2475 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_exchange_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2477 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2479 if (order > c89atomic_memory_order_acquire) {
2480 __sync_synchronize();
2483 return __sync_lock_test_and_set(dst, src);
2487 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
2492 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_exchange_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2494 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2496 if (order > c89atomic_memory_order_acquire) {
2497 __sync_synchronize();
2500 return __sync_lock_test_and_set(dst, src);
2504 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
2511 #define c89atomic_store_explicit_8( dst, src, order) (void)c89atomic_exchange_explicit_8 (dst, src, order)
2512 #define c89atomic_store_explicit_16(dst, src, order) (void)c89atomic_exchange_explicit_16(dst, src, order)
2513 #define c89atomic_store_explicit_32(dst, src, order) (void)c89atomic_exchange_explicit_32(dst, src, order)
2514 #define c89atomic_store_explicit_64(dst, src, order) (void)c89atomic_exchange_explicit_64(dst, src, order)
2518 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_add_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2520 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2523 return __sync_fetch_and_add(dst, src);
2527 C89ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
2532 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_add_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2534 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2537 return __sync_fetch_and_add(dst, src);
2541 C89ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
2546 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_add_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2548 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2551 return __sync_fetch_and_add(dst, src);
2555 C89ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
2560 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_add_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2562 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2565 return __sync_fetch_and_add(dst, src);
2569 C89ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
2576 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_sub_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2578 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2581 return __sync_fetch_and_sub(dst, src);
2585 C89ATOMIC_FETCH_ADD_LOCK(8, dst, (c89atomic_uint8)(-(c89atomic_int8)src), order);
2590 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_sub_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2592 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2595 return __sync_fetch_and_sub(dst, src);
2599 C89ATOMIC_FETCH_ADD_LOCK(16, dst, (c89atomic_uint16)(-(c89atomic_int16)src), order);
2604 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_sub_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2606 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2609 return __sync_fetch_and_sub(dst, src);
2613 C89ATOMIC_FETCH_ADD_LOCK(32, dst, (c89atomic_uint32)(-(c89atomic_int32)src), order);
2618 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_sub_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2620 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2623 return __sync_fetch_and_sub(dst, src);
2627 C89ATOMIC_FETCH_ADD_LOCK(64, dst, (c89atomic_uint64)(-(c89atomic_int64)src), order);
2634 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_and_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2636 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2639 return __sync_fetch_and_and(dst, src);
2643 C89ATOMIC_FETCH_AND_CAS(8, dst, src, order);
2648 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_and_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2650 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2653 return __sync_fetch_and_and(dst, src);
2657 C89ATOMIC_FETCH_AND_CAS(16, dst, src, order);
2662 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_and_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2664 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2667 return __sync_fetch_and_and(dst, src);
2671 C89ATOMIC_FETCH_AND_CAS(32, dst, src, order);
2676 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_and_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2678 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2681 return __sync_fetch_and_and(dst, src);
2685 C89ATOMIC_FETCH_AND_CAS(64, dst, src, order);
2692 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_or_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2694 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2697 return __sync_fetch_and_or(dst, src);
2701 C89ATOMIC_FETCH_OR_CAS(8, dst, src, order);
2706 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_or_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2708 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2711 return __sync_fetch_and_or(dst, src);
2715 C89ATOMIC_FETCH_OR_CAS(16, dst, src, order);
2720 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_or_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2722 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2725 return __sync_fetch_and_or(dst, src);
2729 C89ATOMIC_FETCH_OR_CAS(32, dst, src, order);
2734 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_or_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2736 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2739 return __sync_fetch_and_or(dst, src);
2743 C89ATOMIC_FETCH_OR_CAS(64, dst, src, order);
2750 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_xor_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
2752 #if defined(C89ATOMIC_IS_LOCK_FREE_8)
2755 return __sync_fetch_and_xor(dst, src);
2759 C89ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
2764 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_xor_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
2766 #if defined(C89ATOMIC_IS_LOCK_FREE_16)
2769 return __sync_fetch_and_xor(dst, src);
2773 C89ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
2778 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_xor_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
2780 #if defined(C89ATOMIC_IS_LOCK_FREE_32)
2783 return __sync_fetch_and_xor(dst, src);
2787 C89ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
2792 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_xor_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
2794 #if defined(C89ATOMIC_IS_LOCK_FREE_64)
2797 return __sync_fetch_and_xor(dst, src);
2801 C89ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
2805 #elif defined(C89ATOMIC_LEGACY_GCC_ASM)
2807 #define C89ATOMIC_CMPXCHG_GCC_X86(instructionSizeSuffix, result, dst, expected, replacement)
2808 __asm__ __volatile__(
2809 "lock; cmpxchg"instructionSizeSuffix" %2, %1"
2817 #define C89ATOMIC_XADD_GCC_X86(instructionSizeSuffix, result, dst, src)
2818 __asm__ __volatile__(
2819 "lock; xadd"instructionSizeSuffix" %0, %1"
2828 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_compare_and_swap_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 expected, c89atomic_uint8 replacement)
2830 #if defined(C89ATOMIC_IS_LOCK_FREE_8) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
2832 c89atomic_uint8 result;
2833 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
2835 C89ATOMIC_CMPXCHG_GCC_X86(
"b", result, dst, expected, replacement);
2839 #error Unsupported architecture.
2846 C89ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
2851 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_compare_and_swap_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 expected, c89atomic_uint16 replacement)
2853 #if defined(C89ATOMIC_IS_LOCK_FREE_16) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
2855 c89atomic_uint16 result;
2856 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
2858 C89ATOMIC_CMPXCHG_GCC_X86(
"w", result, dst, expected, replacement);
2862 #error Unsupported architecture.
2869 C89ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
2874 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_compare_and_swap_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 expected, c89atomic_uint32 replacement)
2876 #if defined(C89ATOMIC_IS_LOCK_FREE_32) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
2878 c89atomic_uint32 result;
2879 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
2881 C89ATOMIC_CMPXCHG_GCC_X86(
"l", result, dst, expected, replacement);
2885 #error Unsupported architecture.
2892 C89ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
2897 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_compare_and_swap_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 replacement)
2899 #if defined(C89ATOMIC_IS_LOCK_FREE_64) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
2901 c89atomic_uint64 result;
2902 #if defined(C89ATOMIC_X86)
2905
2906
2907
2908
2909
2910 c89atomic_uint32 resultEAX;
2911 c89atomic_uint32 resultEDX;
2912 __asm__ __volatile__(
2915 "lock cmpxchg8b (%%edi)\n"
2919 :
"a"((c89atomic_uint32)(expected & 0xFFFFFFFF)),
2920 "d"((c89atomic_uint32)(expected >> 32)),
2921 "r"((c89atomic_uint32)(replacement & 0xFFFFFFFF)),
2922 "c"((c89atomic_uint32)(replacement >> 32)),
2925 result = ((c89atomic_uint64)resultEDX << 32) | resultEAX;
2927 #elif defined(C89ATOMIC_X64)
2929 C89ATOMIC_CMPXCHG_GCC_X86(
"q", result, dst, expected, replacement);
2933 #error Unsupported architecture.
2940 C89ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
2947 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_load_explicit_8(
volatile const c89atomic_uint8* dst, c89atomic_memory_order order)
2949 #if defined(C89ATOMIC_IS_LOCK_FREE_8) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
2951 c89atomic_uint8 result;
2952 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
2954 if (order == c89atomic_memory_order_relaxed) {
2955 C89ATOMIC_LOAD_RELAXED_GCC_X86(
"b", result, dst);
2956 }
else if (order <= c89atomic_memory_order_release) {
2957 C89ATOMIC_LOAD_RELEASE_GCC_X86(
"b", result, dst);
2959 C89ATOMIC_LOAD_SEQ_CST_GCC_X86(
"b", result, dst);
2964 #error Unsupported architecture.
2971 C89ATOMIC_LOAD_EXPLICIT_LOCK(8, dst, order);
2976 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_load_explicit_16(
volatile const c89atomic_uint16* dst, c89atomic_memory_order order)
2978 #if defined(C89ATOMIC_IS_LOCK_FREE_16) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
2980 c89atomic_uint16 result;
2981 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
2983 if (order == c89atomic_memory_order_relaxed) {
2984 C89ATOMIC_LOAD_RELAXED_GCC_X86(
"w", result, dst);
2985 }
else if (order <= c89atomic_memory_order_release) {
2986 C89ATOMIC_LOAD_RELEASE_GCC_X86(
"w", result, dst);
2988 C89ATOMIC_LOAD_SEQ_CST_GCC_X86(
"w", result, dst);
2993 #error Unsupported architecture.
3000 C89ATOMIC_LOAD_EXPLICIT_LOCK(16, dst, order);
3005 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_load_explicit_32(
volatile const c89atomic_uint32* dst, c89atomic_memory_order order)
3007 #if defined(C89ATOMIC_IS_LOCK_FREE_32) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3009 c89atomic_uint32 result;
3010 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3012 if (order == c89atomic_memory_order_relaxed) {
3013 C89ATOMIC_LOAD_RELAXED_GCC_X86(
"l", result, dst);
3014 }
else if (order <= c89atomic_memory_order_release) {
3015 C89ATOMIC_LOAD_RELEASE_GCC_X86(
"l", result, dst);
3017 C89ATOMIC_LOAD_SEQ_CST_GCC_X86(
"l", result, dst);
3022 #error Unsupported architecture.
3029 C89ATOMIC_LOAD_EXPLICIT_LOCK(32, dst, order);
3034 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_load_explicit_64(
volatile const c89atomic_uint64* dst, c89atomic_memory_order order)
3036 #if defined(C89ATOMIC_IS_LOCK_FREE_64) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3038 c89atomic_uint64 result;
3039 #if defined(C89ATOMIC_X64)
3041 if (order == c89atomic_memory_order_relaxed) {
3042 C89ATOMIC_LOAD_RELAXED_GCC_X86(
"q", result, dst);
3043 }
else if (order <= c89atomic_memory_order_release) {
3044 C89ATOMIC_LOAD_RELEASE_GCC_X86(
"q", result, dst);
3046 C89ATOMIC_LOAD_SEQ_CST_GCC_X86(
"q", result, dst);
3049 #elif defined(C89ATOMIC_X86)
3052 return c89atomic_compare_and_swap_64((
volatile c89atomic_uint64*)dst, 0, 0);
3056 #error Unsupported architecture.
3063 C89ATOMIC_LOAD_EXPLICIT_LOCK(64, dst, order);
3070 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_exchange_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3072 #if defined(C89ATOMIC_IS_LOCK_FREE_8) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3074 c89atomic_uint8 result;
3076 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3078 C89ATOMIC_XCHG_GCC_X86(
"b", result, dst, src);
3082 #error Unsupported architecture.
3089 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
3094 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_exchange_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3096 #if defined(C89ATOMIC_IS_LOCK_FREE_16) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3098 c89atomic_uint16 result;
3100 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3102 C89ATOMIC_XCHG_GCC_X86(
"w", result, dst, src);
3106 #error Unsupported architecture.
3113 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
3118 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_exchange_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3120 #if defined(C89ATOMIC_IS_LOCK_FREE_32) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3122 c89atomic_uint32 result;
3124 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3126 C89ATOMIC_XCHG_GCC_X86(
"l", result, dst, src);
3130 #error Unsupported architecture.
3137 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
3142 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_exchange_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3144 #if defined(C89ATOMIC_IS_LOCK_FREE_64) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3146 c89atomic_uint64 result;
3148 #if defined(C89ATOMIC_X86)
3150 C89ATOMIC_EXCHANGE_EXPLICIT_CAS(64, dst, src, order);
3152 #elif defined(C89ATOMIC_X64)
3154 C89ATOMIC_XCHG_GCC_X86(
"q", result, dst, src);
3158 #error Unsupported architecture.
3165 C89ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
3172 static C89ATOMIC_INLINE
void c89atomic_store_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3174 #if defined(C89ATOMIC_IS_LOCK_FREE_8) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3176 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3178 if (order == c89atomic_memory_order_relaxed) {
3179 __asm__ __volatile__ (
3185 __asm__ __volatile__ (
3195 #error Unsupported architecture.
3201 C89ATOMIC_STORE_EXPLICIT_LOCK(8, dst, src, order);
3206 static C89ATOMIC_INLINE
void c89atomic_store_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3208 #if defined(C89ATOMIC_IS_LOCK_FREE_16) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3210 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3212 if (order == c89atomic_memory_order_relaxed) {
3213 __asm__ __volatile__ (
3219 __asm__ __volatile__ (
3229 #error Unsupported architecture.
3235 C89ATOMIC_STORE_EXPLICIT_LOCK(16, dst, src, order);
3240 static C89ATOMIC_INLINE
void c89atomic_store_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3242 #if defined(C89ATOMIC_IS_LOCK_FREE_32) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3244 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3246 if (order == c89atomic_memory_order_relaxed) {
3247 __asm__ __volatile__ (
3253 __asm__ __volatile__ (
3263 #error Unsupported architecture.
3269 C89ATOMIC_STORE_EXPLICIT_LOCK(32, dst, src, order);
3274 static C89ATOMIC_INLINE
void c89atomic_store_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3276 #if defined(C89ATOMIC_IS_LOCK_FREE_64) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3278 #if defined(C89ATOMIC_X64)
3280 if (order == c89atomic_memory_order_relaxed) {
3281 __asm__ __volatile__ (
3287 __asm__ __volatile__ (
3297 C89ATOMIC_STORE_EXPLICIT_CAS(64, dst, src, order);
3303 C89ATOMIC_STORE_EXPLICIT_LOCK(64, dst, src, order);
3310 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_add_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3312 #if defined(C89ATOMIC_IS_LOCK_FREE_8) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3314 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3316 c89atomic_uint8 result;
3319 C89ATOMIC_XADD_GCC_X86(
"b", result, dst, src);
3325 #error Unsupported architecture.
3331 C89ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
3336 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_add_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3338 #if defined(C89ATOMIC_IS_LOCK_FREE_16) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3340 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3342 c89atomic_uint16 result;
3345 C89ATOMIC_XADD_GCC_X86(
"w", result, dst, src);
3351 #error Unsupported architecture.
3357 C89ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
3362 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_add_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3364 #if defined(C89ATOMIC_IS_LOCK_FREE_32) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3366 #if defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64)
3368 c89atomic_uint32 result;
3371 C89ATOMIC_XADD_GCC_X86(
"l", result, dst, src);
3377 #error Unsupported architecture.
3383 C89ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
3388 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_add_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3390 #if defined(C89ATOMIC_IS_LOCK_FREE_64) && (defined(C89ATOMIC_X86) || defined(C89ATOMIC_X64))
3392 #if defined(C89ATOMIC_X86)
3394 C89ATOMIC_FETCH_ADD_CAS(64, dst, src, order);
3396 #elif defined(C89ATOMIC_X64)
3398 c89atomic_uint64 result;
3400 C89ATOMIC_XADD_GCC_X86(
"q", result, dst, src);
3407 #error Unsupported architecture.
3413 C89ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
3420 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_sub_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3422 return c89atomic_fetch_add_explicit_8(dst, (c89atomic_uint8)(-(c89atomic_int8)src), order);
3425 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_sub_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3427 return c89atomic_fetch_add_explicit_16(dst, (c89atomic_uint16)(-(c89atomic_int16)src), order);
3430 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_sub_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3432 return c89atomic_fetch_add_explicit_32(dst, (c89atomic_uint32)(-(c89atomic_int32)src), order);
3435 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_sub_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3437 return c89atomic_fetch_add_explicit_64(dst, (c89atomic_uint64)(-(c89atomic_int64)src), order);
3442 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_and_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3444 C89ATOMIC_FETCH_AND_CAS(8, dst, src, order);
3447 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_and_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3449 C89ATOMIC_FETCH_AND_CAS(16, dst, src, order);
3452 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_and_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3454 C89ATOMIC_FETCH_AND_CAS(32, dst, src, order);
3457 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_and_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3459 C89ATOMIC_FETCH_AND_CAS(64, dst, src, order);
3464 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_or_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3466 C89ATOMIC_FETCH_OR_CAS(8, dst, src, order);
3469 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_or_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3471 C89ATOMIC_FETCH_OR_CAS(16, dst, src, order);
3474 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_or_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3476 C89ATOMIC_FETCH_OR_CAS(32, dst, src, order);
3479 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_or_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3481 C89ATOMIC_FETCH_OR_CAS(64, dst, src, order);
3486 static C89ATOMIC_INLINE c89atomic_uint8 c89atomic_fetch_xor_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8 src, c89atomic_memory_order order)
3488 C89ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
3491 static C89ATOMIC_INLINE c89atomic_uint16 c89atomic_fetch_xor_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16 src, c89atomic_memory_order order)
3493 C89ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
3496 static C89ATOMIC_INLINE c89atomic_uint32 c89atomic_fetch_xor_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32 src, c89atomic_memory_order order)
3498 C89ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
3501 static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_fetch_xor_explicit_64(
volatile c89atomic_uint64* dst, c89atomic_uint64 src, c89atomic_memory_order order)
3503 C89ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
3506 #error Unsupported compiler.
3512
3513
3516#if !defined(C89ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE
)
3517 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_8(
volatile c89atomic_uint8* dst, c89atomic_uint8* expected, c89atomic_uint8 replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3519 c89atomic_uint8 result;
3524 result = c89atomic_compare_and_swap_8(dst, *expected, replacement);
3525 if (result == *expected) {
3533 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_16(
volatile c89atomic_uint16* dst, c89atomic_uint16* expected, c89atomic_uint16 replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3535 c89atomic_uint16 result;
3540 result = c89atomic_compare_and_swap_16(dst, *expected, replacement);
3541 if (result == *expected) {
3549 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_32(
volatile c89atomic_uint32* dst, c89atomic_uint32* expected, c89atomic_uint32 replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3551 c89atomic_uint32 result;
3556 result = c89atomic_compare_and_swap_32(dst, *expected, replacement);
3557 if (result == *expected) {
3565 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_64(
volatile c89atomic_uint64* dst,
volatile c89atomic_uint64* expected, c89atomic_uint64 replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3567 c89atomic_uint64 result;
3572 result = c89atomic_compare_and_swap_64(dst, *expected, replacement);
3573 if (result == *expected) {
3581 #define c89atomic_compare_exchange_weak_explicit_8( dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_8 (dst, expected, replacement, successOrder, failureOrder)
3582 #define c89atomic_compare_exchange_weak_explicit_16(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_16(dst, expected, replacement, successOrder, failureOrder)
3583 #define c89atomic_compare_exchange_weak_explicit_32(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_32(dst, expected, replacement, successOrder, failureOrder)
3584 #define c89atomic_compare_exchange_weak_explicit_64(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_64(dst, expected, replacement, successOrder, failureOrder)
3590
3591
3592
3593
3595 static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_ptr(
volatile void** ptr)
3597 return c89atomic_is_lock_free_64((
volatile c89atomic_uint64*)ptr);
3600 static C89ATOMIC_INLINE void* c89atomic_load_explicit_ptr(
volatile void** ptr, c89atomic_memory_order order)
3602 return (
void*)c89atomic_load_explicit_64((
volatile c89atomic_uint64*)ptr, order);
3605 static C89ATOMIC_INLINE void c89atomic_store_explicit_ptr(
volatile void** dst,
void* src, c89atomic_memory_order order)
3607 c89atomic_store_explicit_64((
volatile c89atomic_uint64*)dst, (c89atomic_uint64)src, order);
3610 static C89ATOMIC_INLINE void* c89atomic_exchange_explicit_ptr(
volatile void** dst,
void* src, c89atomic_memory_order order)
3612 return (
void*)c89atomic_exchange_explicit_64((
volatile c89atomic_uint64*)dst, (c89atomic_uint64)src, order);
3615 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_ptr(
volatile void** dst,
void** expected,
void* replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3617 return c89atomic_compare_exchange_strong_explicit_64((
volatile c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)replacement, successOrder, failureOrder);
3620 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_weak_explicit_ptr(
volatile void** dst,
void** expected,
void* replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3625 static C89ATOMIC_INLINE void* c89atomic_compare_and_swap_ptr(
volatile void** dst,
void* expected,
void* replacement)
3627 return (
void*)c89atomic_compare_and_swap_64((
volatile c89atomic_uint64*)dst, (c89atomic_uint64)expected, (c89atomic_uint64)replacement);
3629#elif defined(C89ATOMIC_32BIT)
3630 static C89ATOMIC_INLINE c89atomic_bool c89atomic_is_lock_free_ptr(
volatile void** ptr)
3632 return c89atomic_is_lock_free_32((
volatile c89atomic_uint32*)ptr);
3635 static C89ATOMIC_INLINE
void* c89atomic_load_explicit_ptr(
volatile void** ptr, c89atomic_memory_order order)
3637 return (
void*)c89atomic_load_explicit_32((
volatile c89atomic_uint32*)ptr, order);
3640 static C89ATOMIC_INLINE
void c89atomic_store_explicit_ptr(
volatile void** dst,
void* src, c89atomic_memory_order order)
3642 c89atomic_store_explicit_32((
volatile c89atomic_uint32*)dst, (c89atomic_uint32)src, order);
3645 static C89ATOMIC_INLINE
void* c89atomic_exchange_explicit_ptr(
volatile void** dst,
void* src, c89atomic_memory_order order)
3647 return (
void*)c89atomic_exchange_explicit_32((
volatile c89atomic_uint32*)dst, (c89atomic_uint32)src, order);
3650 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_ptr(
volatile void** dst,
void** expected,
void* replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3652 return c89atomic_compare_exchange_strong_explicit_32((
volatile c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)replacement, successOrder, failureOrder);
3655 static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_weak_explicit_ptr(
volatile void** dst,
void** expected,
void* replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3657 return c89atomic_compare_exchange_weak_explicit_32((
volatile c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)replacement, successOrder, failureOrder);
3660 static C89ATOMIC_INLINE
void* c89atomic_compare_and_swap_ptr(
volatile void** dst,
void* expected,
void* replacement)
3662 return (
void*)c89atomic_compare_and_swap_32((
volatile c89atomic_uint32*)dst, (c89atomic_uint32)expected, (c89atomic_uint32)replacement);
3665 #error Unsupported architecture.
3732#define c89atomic_store_explicit_i8( dst, src, order) c89atomic_store_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3733#define c89atomic_store_explicit_i16(dst, src, order) c89atomic_store_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3734#define c89atomic_store_explicit_i32(dst, src, order) c89atomic_store_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3735#define c89atomic_store_explicit_i64(dst, src, order) c89atomic_store_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3737#define c89atomic_load_explicit_i8( ptr, order) (c89atomic_int8 )c89atomic_load_explicit_8
( (c89atomic_uint8* )ptr, order)
3738#define c89atomic_load_explicit_i16(ptr, order) (c89atomic_int16)c89atomic_load_explicit_16
((c89atomic_uint16*)ptr, order)
3739#define c89atomic_load_explicit_i32(ptr, order) (c89atomic_int32)c89atomic_load_explicit_32
((c89atomic_uint32*)ptr, order)
3740#define c89atomic_load_explicit_i64(ptr, order) (c89atomic_int64)c89atomic_load_explicit_64
((c89atomic_uint64*)ptr, order)
3742#define c89atomic_exchange_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_exchange_explicit_8
((c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3743#define c89atomic_exchange_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_exchange_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3744#define c89atomic_exchange_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_exchange_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3745#define c89atomic_exchange_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_exchange_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3747#define c89atomic_compare_exchange_strong_explicit_i8( dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8* )expected, (c89atomic_uint8 )replacement, successOrder, failureOrder)
3748#define c89atomic_compare_exchange_strong_explicit_i16(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16*)expected, (c89atomic_uint16)replacement, successOrder, failureOrder)
3749#define c89atomic_compare_exchange_strong_explicit_i32(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)replacement, successOrder, failureOrder)
3750#define c89atomic_compare_exchange_strong_explicit_i64(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_strong_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)replacement, successOrder, failureOrder)
3752#define c89atomic_compare_exchange_weak_explicit_i8( dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_8( (c89atomic_uint8* )dst, (c89atomic_uint8* )expected, (c89atomic_uint8 )replacement, successOrder, failureOrder)
3753#define c89atomic_compare_exchange_weak_explicit_i16(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_16((c89atomic_uint16*)dst, (c89atomic_uint16*)expected, (c89atomic_uint16)replacement, successOrder, failureOrder)
3754#define c89atomic_compare_exchange_weak_explicit_i32(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_32((c89atomic_uint32*)dst, (c89atomic_uint32*)expected, (c89atomic_uint32)replacement, successOrder, failureOrder)
3755#define c89atomic_compare_exchange_weak_explicit_i64(dst, expected, replacement, successOrder, failureOrder) c89atomic_compare_exchange_weak_explicit_64((c89atomic_uint64*)dst, (c89atomic_uint64*)expected, (c89atomic_uint64)replacement, successOrder, failureOrder)
3757#define c89atomic_fetch_add_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_add_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3758#define c89atomic_fetch_add_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_add_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3759#define c89atomic_fetch_add_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_add_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3760#define c89atomic_fetch_add_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_add_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3762#define c89atomic_fetch_sub_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_sub_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3763#define c89atomic_fetch_sub_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_sub_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3764#define c89atomic_fetch_sub_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_sub_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3765#define c89atomic_fetch_sub_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_sub_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3767#define c89atomic_fetch_or_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_or_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3768#define c89atomic_fetch_or_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_or_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3769#define c89atomic_fetch_or_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_or_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3770#define c89atomic_fetch_or_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_or_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3772#define c89atomic_fetch_xor_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_xor_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3773#define c89atomic_fetch_xor_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_xor_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3774#define c89atomic_fetch_xor_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_xor_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3775#define c89atomic_fetch_xor_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_xor_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3777#define c89atomic_fetch_and_explicit_i8( dst, src, order) (c89atomic_int8 )c89atomic_fetch_and_explicit_8
( (c89atomic_uint8* )dst, (c89atomic_uint8 )src, order)
3778#define c89atomic_fetch_and_explicit_i16(dst, src, order) (c89atomic_int16)c89atomic_fetch_and_explicit_16
((c89atomic_uint16*)dst, (c89atomic_uint16)src, order)
3779#define c89atomic_fetch_and_explicit_i32(dst, src, order) (c89atomic_int32)c89atomic_fetch_and_explicit_32
((c89atomic_uint32*)dst, (c89atomic_uint32)src, order)
3780#define c89atomic_fetch_and_explicit_i64(dst, src, order) (c89atomic_int64)c89atomic_fetch_and_explicit_64
((c89atomic_uint64*)dst, (c89atomic_uint64)src, order)
3834#define c89atomic_compare_and_swap_i8( dst, expected, dedsired) (c89atomic_int8 )c89atomic_compare_and_swap_8( (c89atomic_uint8* )dst, (c89atomic_uint8 )expected, (c89atomic_uint8 )dedsired)
3835#define c89atomic_compare_and_swap_i16(dst, expected, dedsired) (c89atomic_int16)c89atomic_compare_and_swap_16((c89atomic_uint16*)dst, (c89atomic_uint16)expected, (c89atomic_uint16)dedsired)
3836#define c89atomic_compare_and_swap_i32(dst, expected, dedsired) (c89atomic_int32)c89atomic_compare_and_swap_32((c89atomic_uint32*)dst, (c89atomic_uint32)expected, (c89atomic_uint32)dedsired)
3837#define c89atomic_compare_and_swap_i64(dst, expected, dedsired) (c89atomic_int64)c89atomic_compare_and_swap_64((c89atomic_uint64*)dst, (c89atomic_uint64)expected, (c89atomic_uint64)dedsired)
3855#define c89atomic_clear_explicit_f32(ptr, order) c89atomic_clear_explicit_32((c89atomic_uint32*)ptr, order)
3856#define c89atomic_clear_explicit_f64(ptr, order) c89atomic_clear_explicit_64((c89atomic_uint64*)ptr, order)
3858static C89ATOMIC_INLINE void c89atomic_store_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
3862 c89atomic_store_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
3865static C89ATOMIC_INLINE void c89atomic_store_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
3869 c89atomic_store_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
3873static C89ATOMIC_INLINE float c89atomic_load_explicit_f32(
volatile const float* ptr, c89atomic_memory_order order)
3876 r.i = c89atomic_load_explicit_32((
volatile const c89atomic_uint32*)ptr, order);
3880static C89ATOMIC_INLINE double c89atomic_load_explicit_f64(
volatile const double* ptr, c89atomic_memory_order order)
3883 r.i = c89atomic_load_explicit_64((
volatile const c89atomic_uint64*)ptr, order);
3888static C89ATOMIC_INLINE float c89atomic_exchange_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
3893 r.i = c89atomic_exchange_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
3897static C89ATOMIC_INLINE double c89atomic_exchange_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
3902 r.i = c89atomic_exchange_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
3907static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_f32(
volatile float* dst,
float* expected,
float replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3911 return c89atomic_compare_exchange_strong_explicit_32((
volatile c89atomic_uint32*)dst, (c89atomic_uint32*)expected, d.i, successOrder, failureOrder);
3914static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_strong_explicit_f64(
volatile double* dst,
double* expected,
double replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3918 return c89atomic_compare_exchange_strong_explicit_64((
volatile c89atomic_uint64*)dst, (c89atomic_uint64*)expected, d.i, successOrder, failureOrder);
3922static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_weak_explicit_f32(
volatile float* dst,
float* expected,
float replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3929static C89ATOMIC_INLINE c89atomic_bool c89atomic_compare_exchange_weak_explicit_f64(
volatile double* dst,
double* expected,
double replacement, c89atomic_memory_order successOrder, c89atomic_memory_order failureOrder)
3937static C89ATOMIC_INLINE float c89atomic_fetch_add_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
3942 r.i = c89atomic_fetch_add_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
3946static C89ATOMIC_INLINE double c89atomic_fetch_add_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
3951 r.i = c89atomic_fetch_add_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
3956static C89ATOMIC_INLINE float c89atomic_fetch_sub_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
3961 r.i = c89atomic_fetch_sub_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
3965static C89ATOMIC_INLINE double c89atomic_fetch_sub_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
3970 r.i = c89atomic_fetch_sub_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
3975static C89ATOMIC_INLINE float c89atomic_fetch_or_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
3980 r.i = c89atomic_fetch_or_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
3984static C89ATOMIC_INLINE double c89atomic_fetch_or_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
3989 r.i = c89atomic_fetch_or_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
3994static C89ATOMIC_INLINE float c89atomic_fetch_xor_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
3999 r.i = c89atomic_fetch_xor_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
4003static C89ATOMIC_INLINE double c89atomic_fetch_xor_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
4008 r.i = c89atomic_fetch_xor_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
4013static C89ATOMIC_INLINE float c89atomic_fetch_and_explicit_f32(
volatile float* dst,
float src, c89atomic_memory_order order)
4018 r.i = c89atomic_fetch_and_explicit_32((
volatile c89atomic_uint32*)dst, x.i, order);
4022static C89ATOMIC_INLINE double c89atomic_fetch_and_explicit_f64(
volatile double* dst,
double src, c89atomic_memory_order order)
4027 r.i = c89atomic_fetch_and_explicit_64((
volatile c89atomic_uint64*)dst, x.i, order);
4067static C89ATOMIC_INLINE float c89atomic_compare_and_swap_f32(
volatile float* dst,
float expected,
float replacement)
4070 c89atomic_if32 e, d;
4073 r.i = c89atomic_compare_and_swap_32((
volatile c89atomic_uint32*)dst, e.i, d.i);
4077static C89ATOMIC_INLINE double c89atomic_compare_and_swap_f64(
volatile double* dst,
double expected,
double replacement)
4080 c89atomic_if64 e, d;
4083 r.i = c89atomic_compare_and_swap_64((
volatile c89atomic_uint64*)dst, e.i, d.i);
4089#if defined(__clang__
) || (defined(__GNUC__
) && (__GNUC__
> 4
|| (__GNUC__
== 4
&& __GNUC_MINOR__
>= 6
)))
4090 #pragma GCC diagnostic pop
4093#if defined(__cplusplus
)
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
#define c89atomic_fetch_xor_explicit_i64(dst, src, order)
#define c89atomic_memory_order_release
#define c89atomic_memory_order_seq_cst
#define c89atomic_fetch_add_explicit_i32(dst, src, order)
#define c89atomic_clear_explicit_f64(ptr, order)
#define c89atomic_memory_order_acquire
#define c89atomic_fetch_sub_explicit_i32(dst, src, order)
#define c89atomic_compare_exchange_weak_explicit_i16(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_xor_explicit_i32(dst, src, order)
#define c89atomic_exchange_explicit_i16(dst, src, order)
#define c89atomic_load_explicit_i16(ptr, order)
#define c89atomic_compare_exchange_weak_explicit_64(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_load_explicit_i32(ptr, order)
#define c89atomic_fetch_add_explicit_i8(dst, src, order)
#define c89atomic_compare_exchange_weak_explicit_i8(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_or_explicit_i8(dst, src, order)
#define c89atomic_exchange_explicit_i64(dst, src, order)
#define c89atomic_fetch_and_explicit_i32(dst, src, order)
#define c89atomic_compare_exchange_weak_explicit_16(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_or_explicit_i32(dst, src, order)
#define c89atomic_fetch_and_explicit_i16(dst, src, order)
#define c89atomic_memory_order_relaxed
#define c89atomic_compare_exchange_weak_explicit_i32(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_add_explicit_i16(dst, src, order)
#define c89atomic_load_explicit_i64(ptr, order)
#define c89atomic_exchange_explicit_i8(dst, src, order)
#define c89atomic_fetch_xor_explicit_i8(dst, src, order)
#define c89atomic_compare_exchange_strong_explicit_i64(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_compare_exchange_strong_explicit_i8(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_sub_explicit_i16(dst, src, order)
#define c89atomic_load_explicit_i8(ptr, order)
#define c89atomic_fetch_sub_explicit_i8(dst, src, order)
#define c89atomic_fetch_xor_explicit_i16(dst, src, order)
#define c89atomic_clear_explicit_f32(ptr, order)
#define c89atomic_compare_exchange_strong_explicit_i16(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_store_explicit_i64(dst, src, order)
#define c89atomic_compare_exchange_strong_explicit_i32(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_add_explicit_i64(dst, src, order)
#define c89atomic_store_explicit_i16(dst, src, order)
#define c89atomic_store_explicit_i32(dst, src, order)
#define c89atomic_fetch_and_explicit_i64(dst, src, order)
#define c89atomic_compare_exchange_weak_explicit_i64(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_compare_exchange_weak_explicit_8(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_fetch_sub_explicit_i64(dst, src, order)
#define c89atomic_fetch_and_explicit_i8(dst, src, order)
#define c89atomic_compare_exchange_weak_explicit_32(dst, expected, replacement, successOrder, failureOrder)
#define c89atomic_exchange_explicit_i32(dst, src, order)
#define c89atomic_fetch_or_explicit_i64(dst, src, order)
#define c89atomic_store_explicit_i8(dst, src, order)
#define c89atomic_fetch_or_explicit_i16(dst, src, order)