diff options
author | Johan Tibell <johan.tibell@gmail.com> | 2014-06-26 08:39:53 +0200 |
---|---|---|
committer | Johan Tibell <johan.tibell@gmail.com> | 2014-06-26 08:39:53 +0200 |
commit | 04dd7cb3423f1940242fdfe2ea2e3b8abd68a177 (patch) | |
tree | dc7ce7f22f061e3e36187a23c92e4d995bf2c6dc /libraries | |
parent | bcccadd9719d89c1e51619bc01c3d655ddf0e5f1 (diff) | |
download | haskell-04dd7cb3423f1940242fdfe2ea2e3b8abd68a177.tar.gz |
Work around lack of __sync_fetch_and_nand in clang
clang chose to not implement this function. See
http://llvm.org/bugs/show_bug.cgi?id=8842
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/ghc-prim/cbits/atomic.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/libraries/ghc-prim/cbits/atomic.c b/libraries/ghc-prim/cbits/atomic.c index a2e64afd32..e3d6cc1e95 100644 --- a/libraries/ghc-prim/cbits/atomic.c +++ b/libraries/ghc-prim/cbits/atomic.c @@ -101,32 +101,58 @@ hs_atomic_and64(volatile StgWord64 *x, StgWord64 val) // FetchNandByteArrayOp_Int +// Workaround for http://llvm.org/bugs/show_bug.cgi?id=8842 +#define CAS_NAND(x, val) \ + { \ + __typeof__ (*(x)) tmp = *(x); \ + while (!__sync_bool_compare_and_swap(x, tmp, ~(tmp & (val)))) { \ + tmp = *(x); \ + } \ + return tmp; \ + } + extern StgWord hs_atomic_nand8(volatile StgWord8 *x, StgWord val); StgWord hs_atomic_nand8(volatile StgWord8 *x, StgWord val) { +#ifdef __clang__ + CAS_NAND(x, (StgWord8) val) +#else return __sync_fetch_and_nand(x, (StgWord8) val); +#endif } extern StgWord hs_atomic_nand16(volatile StgWord16 *x, StgWord val); StgWord hs_atomic_nand16(volatile StgWord16 *x, StgWord val) { +#ifdef __clang__ + CAS_NAND(x, (StgWord16) val); +#else return __sync_fetch_and_nand(x, (StgWord16) val); +#endif } extern StgWord hs_atomic_nand32(volatile StgWord32 *x, StgWord val); StgWord hs_atomic_nand32(volatile StgWord32 *x, StgWord val) { +#ifdef __clang__ + CAS_NAND(x, (StgWord32) val); +#else return __sync_fetch_and_nand(x, (StgWord32) val); +#endif } extern StgWord64 hs_atomic_nand64(volatile StgWord64 *x, StgWord64 val); StgWord64 hs_atomic_nand64(volatile StgWord64 *x, StgWord64 val) { +#ifdef __clang__ + CAS_NAND(x, val); +#else return __sync_fetch_and_nand(x, val); +#endif } // FetchOrByteArrayOp_Int |