@@ -23,14 +23,28 @@ for (ityp,jtyp) ∈ [("i8", UInt8), ("i16", UInt16), ("i32", UInt32), ("i64", UI
2323 end
2424 end
2525end
26- for op ∈ [" xchg" , " add" , " sub" , " and" , " nand" , " or" , " xor" , " max" , " min" , " umax" , " umin" ] # "fadd", "fsub"
26+
27+ """
28+ Operations supported by `atomicrmw`.
29+
30+ - Julia v1.11 use [libLLVM-16](https://releases.llvm.org/16.0.0/docs/LangRef.html#atomicrmw-instruction)
31+ """
32+ const atomicrmw_ops = [
33+ " xchg" , " add" , " sub" ,
34+ " and" , " nand" , " or" , " xor" ,
35+ " max" , " min" , " umax" , " umin" ,
36+ # "fadd", "fsub",
37+ # "fmax", "fmin",
38+ # "uinc_wrap", "udec_wrap", # Need LLVM 16: VERSION >= v"1.11"
39+ ]
40+ for op ∈ atomicrmw_ops
2741 f = Symbol (" _atomic_" , op, ' !' )
2842 for (ityp,jtyp) ∈ [(" i8" , UInt8), (" i16" , UInt16), (" i32" , UInt32), (" i64" , UInt64), (" i128" , UInt128)]
2943 @eval begin
44+ # Do inplace `$(op)` for `*ptr` and `x` atomically, return the old value of `*ptr`.
3045 @inline function $f (ptr:: Ptr{$jtyp} , x:: $jtyp )
3146 Base. llvmcall ($ ("""
32- %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
33- %v = atomicrmw $op $(ityp) * %p, $(ityp) %1 acq_rel
47+ %v = atomicrmw $(op) ptr %0, $(ityp) %1 acq_rel
3448 ret $(ityp) %v
3549 """ ), $ jtyp, Tuple{Ptr{$ jtyp}, $ jtyp}, ptr, x)
3650 end
@@ -42,9 +56,9 @@ for op ∈ ["xchg", "add", "sub", "and", "nand", "or", "xor", "max", "min", "uma
4256 end
4357 end
4458end
59+
4560@inline _atomic_state (ptr:: Ptr{UInt} ) = reinterpret (ThreadState, _atomic_load (reinterpret (Ptr{UInt32}, ptr)))
4661@inline _atomic_store! (ptr:: Ptr{UInt} , x:: ThreadState ) = _atomic_store! (reinterpret (Ptr{UInt32}, ptr), reinterpret (UInt32, x))
4762@inline function _atomic_cas_cmp! (ptr:: Ptr{UInt} , cmp:: ThreadState , newval:: ThreadState )
4863 _atomic_cas_cmp! (reinterpret (Ptr{UInt32}, ptr), reinterpret (UInt32, cmp), reinterpret (UInt32, newval))
4964end
50-
0 commit comments