summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorViktor Dukhovni <ietf-dane@dukhovni.org>2020-10-05 01:43:26 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-11-05 00:50:23 -0500
commit17d5c51834d64f1762320b7abaa40c5686564f4d (patch)
tree0b7c681aa2968eb8611890868f69e57dde89ffd7 /compiler
parent81560981fd9af7ea21b2592c405e9e22af838aab (diff)
downloadhaskell-17d5c51834d64f1762320b7abaa40c5686564f4d.tar.gz
Naming, value types and tests for Addr# atomics
The atomic Exchange and CAS operations on integral types are updated to take and return more natural `Word#` rather than `Int#` values. These are bit-block not arithmetic operations, and the sign bit plays no special role. Standardises the names to `atomic<OpType><ValType>Addr#`, where `OpType` is one of `Cas` or `Exchange` and `ValType` is presently either `Word` or `Addr`. Eventually, variants for `Word32` and `Word64` can and should be added, once #11953 and related issues (e.g. #13825) are resolved. Adds tests for `Addr#` CAS that mirror existing tests for `MutableByteArray#`.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/GHC/Builtin/primops.txt.pp32
-rw-r--r--compiler/GHC/StgToCmm/Prim.hs6
2 files changed, 23 insertions, 15 deletions
diff --git a/compiler/GHC/Builtin/primops.txt.pp b/compiler/GHC/Builtin/primops.txt.pp
index 2ee69382dc..c292b9ecdc 100644
--- a/compiler/GHC/Builtin/primops.txt.pp
+++ b/compiler/GHC/Builtin/primops.txt.pp
@@ -2079,39 +2079,47 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp
with has_side_effects = True
can_fail = True
-primop InterlockedExchange_Addr "atomicExchangeAddr#" GenPrimOp
+primop InterlockedExchange_Addr "atomicExchangeAddrAddr#" GenPrimOp
Addr# -> Addr# -> State# s -> (# State# s, Addr# #)
{The atomic exchange operation. Atomically exchanges the value at the first address
with the Addr# given as second argument. Implies a read barrier.}
with has_side_effects = True
+ can_fail = True
-primop InterlockedExchange_Int "atomicExchangeInt#" GenPrimOp
- Addr# -> Int# -> State# s -> (# State# s, Int# #)
+primop InterlockedExchange_Word "atomicExchangeWordAddr#" GenPrimOp
+ Addr# -> Word# -> State# s -> (# State# s, Word# #)
{The atomic exchange operation. Atomically exchanges the value at the address
with the given value. Returns the old value. Implies a read barrier.}
with has_side_effects = True
+ can_fail = True
-primop AtomicCompareExchange_Int "atomicCasInt#" GenPrimOp
- Addr# -> Int# -> Int# -> State# s -> (# State# s, Int# #)
+primop CasAddrOp_Addr "atomicCasAddrAddr#" GenPrimOp
+ Addr# -> Addr# -> Addr# -> State# s -> (# State# s, Addr# #)
{ Compare and swap on a word-sized memory location.
- Use as atomicCasInt# location expected desired
+ Use as: \s -> atomicCasAddrAddr# location expected desired s
- This version always returns the old value read. This follows the normal protocol for CAS operations (and matches the underlying instruction on most architectures).
+ This version always returns the old value read. This follows the normal
+ protocol for CAS operations (and matches the underlying instruction on
+ most architectures).
Implies a full memory barrier.}
with has_side_effects = True
+ can_fail = True
-primop AtomicCompareExchange_Addr "atomicCasAddr#" GenPrimOp
- Addr# -> Addr# -> Addr# -> State# s -> (# State# s, Addr# #)
- { Compare and swap on a word-sized memory location.
+primop CasAddrOp_Word "atomicCasWordAddr#" GenPrimOp
+ Addr# -> Word# -> Word# -> State# s -> (# State# s, Word# #)
+ { Compare and swap on a word-sized and aligned memory location.
- Use as atomicCasAddr# location expected desired
+ Use as: \s -> atomicCasWordAddr# location expected desired s
- This version always returns the old value read. This follows the normal protocol for CAS operations (and matches the underlying instruction on most architectures).
+ This version always returns the old value read. This follows the normal
+ protocol for CAS operations (and matches the underlying instruction on
+ most architectures).
Implies a full memory barrier.}
with has_side_effects = True
+ can_fail = True
------------------------------------------------------------------------
section "Mutable variables"
diff --git a/compiler/GHC/StgToCmm/Prim.hs b/compiler/GHC/StgToCmm/Prim.hs
index a6f2dcb6da..099a3850dc 100644
--- a/compiler/GHC/StgToCmm/Prim.hs
+++ b/compiler/GHC/StgToCmm/Prim.hs
@@ -848,11 +848,11 @@ emitPrimOp dflags primop = case primop of
-- Atomic operations
InterlockedExchange_Addr -> \[src, value] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value]
- InterlockedExchange_Int -> \[src, value] -> opIntoRegs $ \[res] ->
+ InterlockedExchange_Word -> \[src, value] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value]
- AtomicCompareExchange_Int -> \[dst, expected, new] -> opIntoRegs $ \[res] ->
+ CasAddrOp_Addr -> \[dst, expected, new] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Cmpxchg (wordWidth platform)) [dst, expected, new]
- AtomicCompareExchange_Addr -> \[dst, expected, new] -> opIntoRegs $ \[res] ->
+ CasAddrOp_Word -> \[dst, expected, new] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Cmpxchg (wordWidth platform)) [dst, expected, new]
-- SIMD primops