diff options
author | Peter Trommler <ptrommler@acm.org> | 2017-11-02 13:34:41 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-11-02 14:32:57 -0400 |
commit | bd765f4b1332b3d2a7908de3f9ff1d50da0e0b1d (patch) | |
tree | 7e2c829a2a4eeb046f0268deeb92950dcad44c6d /libraries/ghc-prim | |
parent | cbd6a4d05bf382641b108347218dfd534dc57558 (diff) | |
download | haskell-bd765f4b1332b3d2a7908de3f9ff1d50da0e0b1d.tar.gz |
Fix atomicread/write operations
In `libraries/ghc-prim/cbits/atomic.c` no barriers were issued for
atomic read and write operations. Starting with gcc 4.7 compiler
intrinsics are offered. The atomic intrinisics are also available in
clang. Use these to implement `hs_atomicread*` and `hs_atomicwrite`.
Test Plan: validate on OSX and Windows
Reviewers: austin, bgamari, simonmar, hvr, erikd, dfeuer
Reviewed By: bgamari
Subscribers: dfeuer, rwbarton, thomie
GHC Trac Issues: #14244
Differential Revision: https://phabricator.haskell.org/D4009
Diffstat (limited to 'libraries/ghc-prim')
-rw-r--r-- | libraries/ghc-prim/cbits/atomic.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/libraries/ghc-prim/cbits/atomic.c b/libraries/ghc-prim/cbits/atomic.c index 2ecbf3461a..b091d22b58 100644 --- a/libraries/ghc-prim/cbits/atomic.c +++ b/libraries/ghc-prim/cbits/atomic.c @@ -260,61 +260,67 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) #endif // AtomicReadByteArrayOp_Int +// Implies a full memory barrier (see compiler/prelude/primops.txt.pp) +// __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking +// of code) and synchronizes with acquire loads and release stores in +// all threads. extern StgWord hs_atomicread8(StgWord x); StgWord hs_atomicread8(StgWord x) { - return *(volatile StgWord8 *) x; + return __atomic_load_n((StgWord8 *) x, __ATOMIC_SEQ_CST); } extern StgWord hs_atomicread16(StgWord x); StgWord hs_atomicread16(StgWord x) { - return *(volatile StgWord16 *) x; + return __atomic_load_n((StgWord16 *) x, __ATOMIC_SEQ_CST); } extern StgWord hs_atomicread32(StgWord x); StgWord hs_atomicread32(StgWord x) { - return *(volatile StgWord32 *) x; + return __atomic_load_n((StgWord32 *) x, __ATOMIC_SEQ_CST); } extern StgWord64 hs_atomicread64(StgWord x); StgWord64 hs_atomicread64(StgWord x) { - return *(volatile StgWord64 *) x; + return __atomic_load_n((StgWord64 *) x, __ATOMIC_SEQ_CST); } // AtomicWriteByteArrayOp_Int +// Implies a full memory barrier (see compiler/prelude/primops.txt.pp) +// __ATOMIC_SEQ_CST: Full barrier (see hs_atomicread8 above). extern void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite8(StgWord x, StgWord val) { - *(volatile StgWord8 *) x = (StgWord8) val; + __atomic_store_n((StgWord8 *) x, (StgWord8) val, __ATOMIC_SEQ_CST); } extern void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val) { - *(volatile StgWord16 *) x = (StgWord16) val; + __atomic_store_n((StgWord16 *) x, (StgWord16) val, __ATOMIC_SEQ_CST); } extern void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val) { - *(volatile StgWord32 *) x = (StgWord32) val; + __atomic_store_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST); } extern void hs_atomicwrite64(StgWord x, StgWord64 val); void hs_atomicwrite64(StgWord x, StgWord64 val) { - *(volatile StgWord64 *) x = (StgWord64) val; + __atomic_store_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); } |