Line data Source code
1 : #ifndef CFD_THREADING_INTERNAL_H
2 : #define CFD_THREADING_INTERNAL_H
3 :
4 : #ifdef _WIN32
5 : #include <windows.h>
6 :
7 : typedef volatile LONG cfd_atomic_int;
8 :
9 : static inline int cfd_atomic_load(const cfd_atomic_int* ptr) {
10 : return *ptr;
11 : }
12 :
13 : /**
14 : * @brief Compare and Swap
15 : * @return 1 if swap occurred (success), 0 otherwise
16 : */
17 : static inline int cfd_atomic_cas(cfd_atomic_int* ptr, int expected, int desired) {
18 : // InterlockedCompareExchange(dest, exchange, comparand)
19 : // Returns the initial value of dest.
20 : // If return value == comparand (expected), then success.
21 : return (InterlockedCompareExchange(ptr, desired, expected) == expected);
22 : }
23 :
24 : static inline void cfd_atomic_store(cfd_atomic_int* ptr, int value) {
25 : InterlockedExchange(ptr, value);
26 : }
27 :
28 : /* Atomic pointer operations (for function pointer globals) */
29 : typedef void* volatile cfd_atomic_ptr;
30 :
31 : static inline void* cfd_atomic_ptr_load(const cfd_atomic_ptr* ptr) {
32 : return InterlockedCompareExchangePointer((volatile PVOID*)ptr, NULL, NULL);
33 : }
34 :
35 : static inline void cfd_atomic_ptr_store(cfd_atomic_ptr* ptr, void* value) {
36 : InterlockedExchangePointer(ptr, value);
37 : }
38 :
39 : #else
40 : #include <stdatomic.h>
41 :
42 : typedef atomic_int cfd_atomic_int;
43 :
44 389 : static inline int cfd_atomic_load(cfd_atomic_int* ptr) {
45 302 : return atomic_load(ptr);
46 : }
47 :
48 451 : static inline int cfd_atomic_cas(cfd_atomic_int* ptr, int expected, int desired) {
49 : // atomic_compare_exchange_strong takes &expected
50 451 : int exp = expected;
51 451 : return atomic_compare_exchange_strong(ptr, &exp, desired);
52 : }
53 :
54 36 : static inline void cfd_atomic_store(cfd_atomic_int* ptr, int value) {
55 36 : atomic_store(ptr, value);
56 : }
57 :
58 : /* Atomic pointer operations (for function pointer globals).
59 : * Uses uintptr_t to avoid _Atomic(void*) which can cause TSan issues. */
60 : #include <stdint.h>
61 :
62 : typedef _Atomic(uintptr_t) cfd_atomic_ptr;
63 :
64 34 : static inline void* cfd_atomic_ptr_load(cfd_atomic_ptr* ptr) {
65 34 : return (void*)atomic_load(ptr);
66 : }
67 :
68 34 : static inline void cfd_atomic_ptr_store(cfd_atomic_ptr* ptr, void* value) {
69 34 : atomic_store(ptr, (uintptr_t)value);
70 : }
71 :
72 : #endif
73 :
74 : #endif // CFD_THREADING_INTERNAL_H
|