|
23 | 23 |
|
24 | 24 | /// C++11 compatibility macros. |
25 | 25 | /// |
26 | | -/// Atomic support, due to incompatibilities between C++ and C11 atomic syntax. |
27 | | -/// - `CWISS_ATOMIC_T(Type)` names an atomic version of `Type`. We must use this |
28 | | -/// instead of `_Atomic(Type)` to name an atomic type. |
29 | | -/// - `CWISS_ATOMIC_INC(value)` will atomically increment `value` without |
30 | | -/// performing synchronization. This is used as a weak entropy source |
31 | | -/// elsewhere. |
32 | | -/// |
33 | 26 | /// `extern "C"` support via `CWISS_END_EXTERN` and `CWISS_END_EXTERN`, |
34 | 27 | /// which open and close an `extern "C"` block in C++ mode. |
35 | 28 | #ifdef __cplusplus |
36 | | - #include <atomic> |
37 | | - #define CWISS_ATOMIC_T(Type_) std::atomic<Type_> |
38 | | - #define CWISS_ATOMIC_INC(val_) (val_).fetch_add(1, std::memory_order_relaxed) |
39 | | - |
40 | 29 | #define CWISS_BEGIN_EXTERN extern "C" { |
41 | 30 | #define CWISS_END_EXTERN } |
42 | 31 | #else |
43 | | - #include <stdatomic.h> |
44 | | - #define CWISS_ATOMIC_T(Type_) _Atomic(Type_) |
45 | | - #define CWISS_ATOMIC_INC(val_) \ |
46 | | - atomic_fetch_add_explicit(&(val_), 1, memory_order_relaxed) |
47 | | - |
48 | 32 | #define CWISS_BEGIN_EXTERN |
49 | 33 | #define CWISS_END_EXTERN |
50 | 34 | #endif |
|
87 | 71 | #define CWISS_GCC_POP |
88 | 72 | #endif |
89 | 73 |
|
| 74 | +/// Atomic support, due to incompatibilities between C++ and C11 atomic syntax. |
| 75 | +/// - `CWISS_ATOMIC_T(Type)` names an atomic version of `Type`. We must use this |
| 76 | +/// instead of `_Atomic(Type)` to name an atomic type. |
| 77 | +/// - `CWISS_ATOMIC_INC(value)` will atomically increment `value` without |
| 78 | +/// performing synchronization. This is used as a weak entropy source |
| 79 | +/// elsewhere. |
| 80 | +/// |
| 81 | +/// MSVC, of course, being that it does not support _Atomic in C mode, so we |
| 82 | +/// use `volatile`. This is *wrong*, but MSVC certainly won't miscompile it any |
| 83 | +/// worse than it would a relaxed atomic. It doesn't matter for our use of |
| 84 | +/// atomics. |
| 85 | +#ifdef __cplusplus |
| 86 | + #include <atomic> |
| 87 | + #define CWISS_ATOMIC_T(Type_) std::atomic<Type_> |
| 88 | + #define CWISS_ATOMIC_INC(val_) (val_).fetch_add(1, std::memory_order_relaxed) |
| 89 | +#elif CWISS_IS_MSVC |
| 90 | + #define CWISS_ATOMIC_T(Type_) volatile Type_ |
| 91 | + #define CWISS_ATOMIC_INC(val_) (val_ += 1) |
| 92 | +#else |
| 93 | + #include <stdatomic.h> |
| 94 | + #define CWISS_ATOMIC_T(Type_) _Atomic(Type_) |
| 95 | + #define CWISS_ATOMIC_INC(val_) \ |
| 96 | + atomic_fetch_add_explicit(&(val_), 1, memory_order_relaxed) |
| 97 | + |
| 98 | + #define CWISS_BEGIN_EXTERN |
| 99 | + #define CWISS_END_EXTERN |
| 100 | +#endif |
| 101 | + |
90 | 102 | /// Warning control around `CWISS` symbol definitions. These macros will |
91 | 103 | /// disable certain false-positive warnings that `CWISS` definitions tend to |
92 | 104 | /// emit. |
|
0 commit comments