1+
12for (ityp,jtyp) ∈ [(" i8" , UInt8), (" i16" , UInt16), (" i32" , UInt32), (" i64" , UInt64), (" i128" , UInt128)]
23 @eval begin
34 @inline function _atomic_load (ptr:: Ptr{$jtyp} )
4- Base. llvmcall ($ ("""
5- %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
6- %v = load atomic $(ityp) , $(ityp) * %p acquire, align $(Base. gc_alignment (jtyp))
7- ret $(ityp) %v
8- """ ), $ jtyp, Tuple{Ptr{$ jtyp}}, ptr)
5+ Base. llvmcall ($ (
6+ @static if VERSION >= v " 1.12-DEV"
7+ # use opaque pointers #53
8+ """
9+ %v = load atomic $(ityp) , ptr %0 acquire, align $(Base. gc_alignment (jtyp))
10+ ret $(ityp) %v
11+ """
12+ else
13+ """
14+ %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
15+ %v = load atomic $(ityp) , $(ityp) * %p acquire, align $(Base. gc_alignment (jtyp))
16+ ret $(ityp) %v
17+ """
18+ end
19+ ), $ jtyp, Tuple{Ptr{$ jtyp}}, ptr)
920 end
1021 @inline function _atomic_store! (ptr:: Ptr{$jtyp} , x:: $jtyp )
11- Base. llvmcall ($ ("""
12- %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
13- store atomic $(ityp) %1, $(ityp) * %p release, align $(Base. gc_alignment (jtyp))
14- ret void
15- """ ), Cvoid, Tuple{Ptr{$ jtyp}, $ jtyp}, ptr, x)
22+ Base. llvmcall ($ (
23+ @static if VERSION >= v " 1.12-DEV"
24+ """
25+ store atomic $(ityp) %1, ptr %0 release, align $(Base. gc_alignment (jtyp))
26+ ret void
27+ """
28+ else
29+ """
30+ %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
31+ store atomic $(ityp) %1, $(ityp) * %p release, align $(Base. gc_alignment (jtyp))
32+ ret void
33+ """
34+ end
35+ ), Cvoid, Tuple{Ptr{$ jtyp}, $ jtyp}, ptr, x)
1636 end
1737 @inline function _atomic_cas_cmp! (ptr:: Ptr{$jtyp} , cmp:: $jtyp , newval:: $jtyp )
18- Base. llvmcall ($ ("""
19- %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
20- %c = cmpxchg $(ityp) * %p, $(ityp) %1, $(ityp) %2 acq_rel acquire
21- %bit = extractvalue { $ityp , i1 } %c, 1
22- %bool = zext i1 %bit to i8
23- ret i8 %bool
24- """ ), Bool, Tuple{Ptr{$ jtyp}, $ jtyp, $ jtyp}, ptr, cmp, newval)
38+ Base. llvmcall ($ (
39+ @static if VERSION >= v " 1.12-DEV"
40+ """
41+ %c = cmpxchg ptr %0, $(ityp) %1, $(ityp) %2 acq_rel acquire
42+ %bit = extractvalue { $ityp , i1 } %c, 1
43+ %bool = zext i1 %bit to i8
44+ ret i8 %bool
45+ """
46+ else
47+ """
48+ %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
49+ %c = cmpxchg $(ityp) * %p, $(ityp) %1, $(ityp) %2 acq_rel acquire
50+ %bit = extractvalue { $ityp , i1 } %c, 1
51+ %bool = zext i1 %bit to i8
52+ ret i8 %bool
53+ """
54+ end
55+ ), Bool, Tuple{Ptr{$ jtyp}, $ jtyp, $ jtyp}, ptr, cmp, newval)
2556 end
2657 end
2758end
28- for op ∈ [" xchg" , " add" , " sub" , " and" , " nand" , " or" , " xor" , " max" , " min" , " umax" , " umin" ] # "fadd", "fsub"
59+
60+ """
61+ Operations supported by `atomicrmw`.
62+
63+ - Julia v1.11 use [libLLVM-16](https://releases.llvm.org/16.0.0/docs/LangRef.html#atomicrmw-instruction)
64+ """
65+ const atomicrmw_ops = [
66+ " xchg" , " add" , " sub" ,
67+ " and" , " nand" , " or" , " xor" ,
68+ " max" , " min" , " umax" , " umin" ,
69+ # "fadd", "fsub",
70+ # "fmax", "fmin",
71+ # "uinc_wrap", "udec_wrap", # Need LLVM 16: VERSION >= v"1.11"
72+ ]
73+ for op ∈ atomicrmw_ops
2974 f = Symbol (" _atomic_" , op, ' !' )
3075 for (ityp,jtyp) ∈ [(" i8" , UInt8), (" i16" , UInt16), (" i32" , UInt32), (" i64" , UInt64), (" i128" , UInt128)]
3176 @eval begin
77+ # Do inplace `$(op)` for `*ptr` and `x` atomically, return the old value of `*ptr`.
3278 @inline function $f (ptr:: Ptr{$jtyp} , x:: $jtyp )
33- Base. llvmcall ($ ("""
34- %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
35- %v = atomicrmw $op $(ityp) * %p, $(ityp) %1 acq_rel
36- ret $(ityp) %v
37- """ ), $ jtyp, Tuple{Ptr{$ jtyp}, $ jtyp}, ptr, x)
79+ Base. llvmcall ($ (
80+ @static if VERSION >= v " 1.12-DEV"
81+ """
82+ %v = atomicrmw $(op) ptr %0, $(ityp) %1 acq_rel
83+ ret $(ityp) %v
84+ """
85+ else
86+ """
87+ %p = inttoptr i$(8 sizeof (Int)) %0 to $(ityp) *
88+ %v = atomicrmw $op $(ityp) * %p, $(ityp) %1 acq_rel
89+ ret $(ityp) %v
90+ """
91+ end
92+ ), $ jtyp, Tuple{Ptr{$ jtyp}, $ jtyp}, ptr, x)
3893 end
3994 end
4095 end
@@ -44,9 +99,9 @@ for op ∈ ["xchg", "add", "sub", "and", "nand", "or", "xor", "max", "min", "uma
4499 end
45100 end
46101end
102+
47103@inline _atomic_state (ptr:: Ptr{UInt} ) = reinterpret (ThreadState, _atomic_load (reinterpret (Ptr{UInt32}, ptr)))
48104@inline _atomic_store! (ptr:: Ptr{UInt} , x:: ThreadState ) = _atomic_store! (reinterpret (Ptr{UInt32}, ptr), reinterpret (UInt32, x))
49105@inline function _atomic_cas_cmp! (ptr:: Ptr{UInt} , cmp:: ThreadState , newval:: ThreadState )
50106 _atomic_cas_cmp! (reinterpret (Ptr{UInt32}, ptr), reinterpret (UInt32, cmp), reinterpret (UInt32, newval))
51107end
52-
0 commit comments