Skip to content

Commit 028f64f

Browse files
authored
atomics: update llvmcall to use opaque pointers (#53)
* atomics: update llvmcall for `load,store,cmpxchg` * atomics: update llvmcall for `atomicrmw_ops` * compat: need julia 1.11+ * ci: update github actions * Revert "compat: need julia 1.11+" This reverts commit 6ad1ecd. * atomics: fix compat with julia <= v1.11 * ci: test with v1.5 * ci: macos-latest need julia v1.8+ * ci: Update codecov-action
1 parent db36597 commit 028f64f

File tree

3 files changed

+105
-69
lines changed

3 files changed

+105
-69
lines changed

.github/workflows/ci-julia-nightly.yml

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,57 +18,42 @@ on:
1818
jobs:
1919
test-julia-nightly:
2020
timeout-minutes: 30
21-
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
21+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}
2222
runs-on: ${{ matrix.os }}
2323
strategy:
2424
fail-fast: false
2525
matrix:
26-
arch:
27-
- x64
28-
- x86
26+
# use default arch
2927
exclusive:
3028
- '0'
3129
os:
3230
- ubuntu-latest
33-
- macOS-latest
31+
- macOS-latest # arm
3432
- windows-latest
3533
threads:
3634
- '5'
3735
version:
38-
- '1.5'
39-
- '1'
36+
# Runs on Julia nightly only.
4037
- 'nightly'
41-
exclude:
42-
- os: macOS-latest
43-
arch: x86 # 32-bit Julia binaries are not available on macOS
4438
include:
45-
- exclusive: '1'
46-
threads: '2'
47-
arch: x64
39+
# (exclusive=1, threads=2)
40+
- arch: x64
41+
exclusive: '1'
4842
os: ubuntu-latest
49-
version: '1'
43+
threads: '2'
44+
version: 'nightly'
5045
steps:
5146
- uses: actions/checkout@v4
5247
- uses: julia-actions/setup-julia@v2
5348
with:
5449
version: ${{ matrix.version }}
55-
arch: ${{ matrix.arch }}
56-
- uses: actions/cache@v4
57-
env:
58-
cache-name: cache-artifacts
59-
with:
60-
path: ~/.julia/artifacts
61-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
62-
restore-keys: |
63-
${{ runner.os }}-test-${{ env.cache-name }}-
64-
${{ runner.os }}-test-
65-
${{ runner.os }}-
50+
- uses: julia-actions/cache@v2
6651
- uses: julia-actions/julia-buildpkg@v1
6752
- uses: julia-actions/julia-runtest@v1
6853
env:
6954
JULIA_EXCLUSIVE: ${{ matrix.exclusive }}
7055
JULIA_NUM_THREADS: ${{ matrix.threads }}
7156
- uses: julia-actions/julia-processcoverage@v1
72-
- uses: codecov/codecov-action@v3
57+
- uses: codecov/codecov-action@v5
7358
with:
74-
file: lcov.info
59+
files: lcov.info

.github/workflows/ci.yml

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,48 +30,44 @@ jobs:
3030
- '0'
3131
os:
3232
- ubuntu-latest
33-
- macOS-latest
3433
- windows-latest
34+
- macos-13 # Intel
3535
threads:
3636
- '5'
3737
version:
3838
- '1.5'
3939
- '1'
40-
- 'nightly'
4140
exclude:
42-
- os: macOS-latest
41+
- os: macos-13
4342
arch: x86 # 32-bit Julia binaries are not available on macOS
4443
include:
45-
- exclusive: '1'
46-
threads: '2'
47-
arch: x64
44+
- arch: aarch64
45+
exclusive: '0'
46+
os: macos-latest # Arm
47+
threads: '5'
48+
version: '1' # macos-latest (aarch64) need Julia >= v1.8+
49+
# (exclusive=1, threads=2)
50+
- arch: x64
51+
exclusive: '1'
4852
os: ubuntu-latest
53+
threads: '2'
4954
version: '1'
5055
steps:
5156
- uses: actions/checkout@v4
5257
- uses: julia-actions/setup-julia@v2
5358
with:
5459
version: ${{ matrix.version }}
5560
arch: ${{ matrix.arch }}
56-
- uses: actions/cache@v4
57-
env:
58-
cache-name: cache-artifacts
59-
with:
60-
path: ~/.julia/artifacts
61-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
62-
restore-keys: |
63-
${{ runner.os }}-test-${{ env.cache-name }}-
64-
${{ runner.os }}-test-
65-
${{ runner.os }}-
61+
- uses: julia-actions/cache@v2
6662
- uses: julia-actions/julia-buildpkg@v1
6763
- uses: julia-actions/julia-runtest@v1
6864
env:
6965
JULIA_EXCLUSIVE: ${{ matrix.exclusive }}
7066
JULIA_NUM_THREADS: ${{ matrix.threads }}
7167
- uses: julia-actions/julia-processcoverage@v1
72-
- uses: codecov/codecov-action@v3
68+
- uses: codecov/codecov-action@v5
7369
with:
74-
file: lcov.info
70+
files: lcov.info
7571
docs:
7672
name: Documentation
7773
runs-on: ubuntu-latest

src/atomics.jl

Lines changed: 79 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,95 @@
1+
12
for (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$(8sizeof(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$(8sizeof(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$(8sizeof(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$(8sizeof(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$(8sizeof(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$(8sizeof(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
2758
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
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$(8sizeof(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$(8sizeof(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
46101
end
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))
51107
end
52-

0 commit comments

Comments
 (0)