[commit: ghc] master: Work around lack of __sync_fetch_and_nand in clang (04dd7cb)

git at git.haskell.org git at git.haskell.org
Thu Jun 26 06:41:51 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/04dd7cb3423f1940242fdfe2ea2e3b8abd68a177/ghc

>---------------------------------------------------------------

commit 04dd7cb3423f1940242fdfe2ea2e3b8abd68a177
Author: Johan Tibell <johan.tibell at gmail.com>
Date:   Thu Jun 26 08:39:53 2014 +0200

    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


>---------------------------------------------------------------

04dd7cb3423f1940242fdfe2ea2e3b8abd68a177
 libraries/ghc-prim/cbits/atomic.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/libraries/ghc-prim/cbits/atomic.c b/libraries/ghc-prim/cbits/atomic.c
index a2e64af..e3d6cc1 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



More information about the ghc-commits mailing list