… | |
… | |
137 | #endif |
137 | #endif |
138 | #endif |
138 | #endif |
139 | |
139 | |
140 | #ifndef ECB_MEMORY_FENCE |
140 | #ifndef ECB_MEMORY_FENCE |
141 | #if ECB_GCC_VERSION(4,7) |
141 | #if ECB_GCC_VERSION(4,7) |
142 | /* see comment below about the C11 memory model. in short - avoid */ |
142 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
143 | #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) |
143 | #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) |
144 | #elif defined __clang && __has_feature (cxx_atomic) |
144 | #elif defined __clang && __has_feature (cxx_atomic) |
145 | /* see above */ |
145 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
146 | #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) |
146 | #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) |
147 | #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ |
147 | #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ |
148 | #define ECB_MEMORY_FENCE __sync_synchronize () |
148 | #define ECB_MEMORY_FENCE __sync_synchronize () |
149 | #elif _MSC_VER >= 1400 /* VC++ 2005 */ |
149 | #elif _MSC_VER >= 1400 /* VC++ 2005 */ |
150 | #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) |
150 | #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) |
… | |
… | |
167 | #ifndef ECB_MEMORY_FENCE |
167 | #ifndef ECB_MEMORY_FENCE |
168 | #if ECB_C11 && !defined __STDC_NO_ATOMICS__ |
168 | #if ECB_C11 && !defined __STDC_NO_ATOMICS__ |
169 | /* we assume that these memory fences work on all variables/all memory accesses, */ |
169 | /* we assume that these memory fences work on all variables/all memory accesses, */ |
170 | /* not just C11 atomics and atomic accesses */ |
170 | /* not just C11 atomics and atomic accesses */ |
171 | #include <stdatomic.h> |
171 | #include <stdatomic.h> |
172 | /* unfortunately, the C11 memory model seems to be very limited, and unable to express */ |
172 | /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */ |
173 | /* simple barrier semantics. That means we need to take out thor's hammer. */ |
173 | /* any fence other than seq_cst, which isn't very efficient for us. */ |
|
|
174 | /* Why that is, we don't know - either the C11 memory model is quite useless */ |
|
|
175 | /* for most usages, or gcc and clang have a bug */ |
|
|
176 | /* I *currently* lean towards the latter, and inefficiently implement */ |
|
|
177 | /* all three of ecb's fences as a seq_cst fence */ |
174 | #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) |
178 | #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) |
175 | #endif |
179 | #endif |
176 | #endif |
180 | #endif |
177 | |
181 | |
178 | #ifndef ECB_MEMORY_FENCE |
182 | #ifndef ECB_MEMORY_FENCE |