summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorJohan Tibell <johan.tibell@gmail.com>2014-06-26 08:39:53 +0200
committerJohan Tibell <johan.tibell@gmail.com>2014-06-26 08:39:53 +0200
commit04dd7cb3423f1940242fdfe2ea2e3b8abd68a177 (patch)
treedc7ce7f22f061e3e36187a23c92e4d995bf2c6dc /libraries
parentbcccadd9719d89c1e51619bc01c3d655ddf0e5f1 (diff)
downloadhaskell-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.c26
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