… | |
… | |
173 | |
173 | |
174 | #ifndef ECB_MEMORY_FENCE |
174 | #ifndef ECB_MEMORY_FENCE |
175 | #if ECB_GCC_VERSION(4,7) |
175 | #if ECB_GCC_VERSION(4,7) |
176 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
176 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
177 | #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) |
177 | #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) |
|
|
178 | #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE) |
|
|
179 | #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE) |
178 | |
180 | |
179 | /* The __has_feature syntax from clang is so misdesigned that we cannot use it |
181 | /* The __has_feature syntax from clang is so misdesigned that we cannot use it |
180 | * without risking compile time errors with other compilers. We *could* |
182 | * without risking compile time errors with other compilers. We *could* |
181 | * define our own ecb_clang_has_feature, but I just can't be bothered to work |
183 | * define our own ecb_clang_has_feature, but I just can't be bothered to work |
182 | * around this shit time and again. |
184 | * around this shit time and again. |
183 | * #elif defined __clang && __has_feature (cxx_atomic) |
185 | * #elif defined __clang && __has_feature (cxx_atomic) |
184 | * // see comment below (stdatomic.h) about the C11 memory model. |
186 | * // see comment below (stdatomic.h) about the C11 memory model. |
185 | * #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) |
187 | * #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) |
|
|
188 | * #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE) |
|
|
189 | * #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE) |
186 | */ |
190 | */ |
187 | |
191 | |
188 | #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ |
192 | #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ |
189 | #define ECB_MEMORY_FENCE __sync_synchronize () |
193 | #define ECB_MEMORY_FENCE __sync_synchronize () |
190 | #elif _MSC_VER >= 1500 /* VC++ 2008 */ |
194 | #elif _MSC_VER >= 1500 /* VC++ 2008 */ |
… | |
… | |
220 | /* any fence other than seq_cst, which isn't very efficient for us. */ |
224 | /* any fence other than seq_cst, which isn't very efficient for us. */ |
221 | /* Why that is, we don't know - either the C11 memory model is quite useless */ |
225 | /* Why that is, we don't know - either the C11 memory model is quite useless */ |
222 | /* for most usages, or gcc and clang have a bug */ |
226 | /* for most usages, or gcc and clang have a bug */ |
223 | /* I *currently* lean towards the latter, and inefficiently implement */ |
227 | /* I *currently* lean towards the latter, and inefficiently implement */ |
224 | /* all three of ecb's fences as a seq_cst fence */ |
228 | /* all three of ecb's fences as a seq_cst fence */ |
|
|
229 | /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */ |
|
|
230 | /* for all __atomic_thread_fence's except seq_cst */ |
225 | #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) |
231 | #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) |
226 | #endif |
232 | #endif |
227 | #endif |
233 | #endif |
228 | |
234 | |
229 | #ifndef ECB_MEMORY_FENCE |
235 | #ifndef ECB_MEMORY_FENCE |