1
+
1
2
for (ityp,jtyp) ∈ [(" i8" , UInt8), (" i16" , UInt16), (" i32" , UInt32), (" i64" , UInt64), (" i128" , UInt128)]
2
3
@eval begin
3
4
@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)
9
20
end
10
21
@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)
16
36
end
17
37
@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)
25
56
end
26
57
end
27
58
end
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
29
74
f = Symbol (" _atomic_" , op, ' !' )
30
75
for (ityp,jtyp) ∈ [(" i8" , UInt8), (" i16" , UInt16), (" i32" , UInt32), (" i64" , UInt64), (" i128" , UInt128)]
31
76
@eval begin
77
+ # Do inplace `$(op)` for `*ptr` and `x` atomically, return the old value of `*ptr`.
32
78
@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)
38
93
end
39
94
end
40
95
end
@@ -44,9 +99,9 @@ for op ∈ ["xchg", "add", "sub", "and", "nand", "or", "xor", "max", "min", "uma
44
99
end
45
100
end
46
101
end
102
+
47
103
@inline _atomic_state (ptr:: Ptr{UInt} ) = reinterpret (ThreadState, _atomic_load (reinterpret (Ptr{UInt32}, ptr)))
48
104
@inline _atomic_store! (ptr:: Ptr{UInt} , x:: ThreadState ) = _atomic_store! (reinterpret (Ptr{UInt32}, ptr), reinterpret (UInt32, x))
49
105
@inline function _atomic_cas_cmp! (ptr:: Ptr{UInt} , cmp:: ThreadState , newval:: ThreadState )
50
106
_atomic_cas_cmp! (reinterpret (Ptr{UInt32}, ptr), reinterpret (UInt32, cmp), reinterpret (UInt32, newval))
51
107
end
52
-
0 commit comments