diff options
author | Viktor Dukhovni <ietf-dane@dukhovni.org> | 2020-10-05 01:43:26 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-11-05 00:50:23 -0500 |
commit | 17d5c51834d64f1762320b7abaa40c5686564f4d (patch) | |
tree | 0b7c681aa2968eb8611890868f69e57dde89ffd7 /compiler | |
parent | 81560981fd9af7ea21b2592c405e9e22af838aab (diff) | |
download | haskell-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.pp | 32 | ||||
-rw-r--r-- | compiler/GHC/StgToCmm/Prim.hs | 6 |
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 |