From 6e19359d1eb44ed98c90c9283098a82bbdf05dff Mon Sep 17 00:00:00 2001 From: Chengyu HAN Date: Thu, 2 Jan 2025 18:38:18 +0800 Subject: [PATCH 1/4] atomics: update llvmcall for `load,store,cmpxchg` --- src/atomics.jl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/atomics.jl b/src/atomics.jl index 462366c..8e9e88b 100644 --- a/src/atomics.jl +++ b/src/atomics.jl @@ -1,23 +1,21 @@ + for (ityp,jtyp) ∈ [("i8", UInt8), ("i16", UInt16), ("i32", UInt32), ("i64", UInt64), ("i128", UInt128)] @eval begin @inline function _atomic_load(ptr::Ptr{$jtyp}) Base.llvmcall($(""" - %p = inttoptr i$(8sizeof(Int)) %0 to $(ityp)* - %v = load atomic $(ityp), $(ityp)* %p acquire, align $(Base.gc_alignment(jtyp)) + %v = load atomic $(ityp), ptr %0 acquire, align $(Base.gc_alignment(jtyp)) ret $(ityp) %v """), $jtyp, Tuple{Ptr{$jtyp}}, ptr) end @inline function _atomic_store!(ptr::Ptr{$jtyp}, x::$jtyp) Base.llvmcall($(""" - %p = inttoptr i$(8sizeof(Int)) %0 to $(ityp)* - store atomic $(ityp) %1, $(ityp)* %p release, align $(Base.gc_alignment(jtyp)) + store atomic $(ityp) %1, ptr %0 release, align $(Base.gc_alignment(jtyp)) ret void """), Cvoid, Tuple{Ptr{$jtyp}, $jtyp}, ptr, x) end @inline function _atomic_cas_cmp!(ptr::Ptr{$jtyp}, cmp::$jtyp, newval::$jtyp) Base.llvmcall($(""" - %p = inttoptr i$(8sizeof(Int)) %0 to $(ityp)* - %c = cmpxchg $(ityp)* %p, $(ityp) %1, $(ityp) %2 acq_rel acquire + %c = cmpxchg ptr %0, $(ityp) %1, $(ityp) %2 acq_rel acquire %bit = extractvalue { $ityp, i1 } %c, 1 %bool = zext i1 %bit to i8 ret i8 %bool From a702d36e81ac8ad034cedc6872a19965b2ee8497 Mon Sep 17 00:00:00 2001 From: Chengyu HAN Date: Thu, 2 Jan 2025 18:38:54 +0800 Subject: [PATCH 2/4] atomics: update llvmcall for `atomicrmw_ops` --- src/atomics.jl | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/atomics.jl b/src/atomics.jl index 8e9e88b..e57bca7 100644 --- a/src/atomics.jl +++ b/src/atomics.jl @@ -23,14 +23,28 @@ for (ityp,jtyp) ∈ [("i8", UInt8), ("i16", UInt16), ("i32", UInt32), ("i64", UI end end end -for op ∈ ["xchg", "add", "sub", "and", "nand", "or", "xor", "max", "min", "umax", "umin"] # "fadd", "fsub" + +""" +Operations supported by `atomicrmw`. + +- Julia v1.11 use [libLLVM-16](https://releases.llvm.org/16.0.0/docs/LangRef.html#atomicrmw-instruction) +""" +const atomicrmw_ops = [ + "xchg", "add", "sub", + "and", "nand", "or", "xor", + "max", "min", "umax", "umin", + # "fadd", "fsub", + # "fmax", "fmin", + # "uinc_wrap", "udec_wrap", # Need LLVM 16: VERSION >= v"1.11" +] +for op ∈ atomicrmw_ops f = Symbol("_atomic_", op, '!') for (ityp,jtyp) ∈ [("i8", UInt8), ("i16", UInt16), ("i32", UInt32), ("i64", UInt64), ("i128", UInt128)] @eval begin + # Do inplace `$(op)` for `*ptr` and `x` atomically, return the old value of `*ptr`. @inline function $f(ptr::Ptr{$jtyp}, x::$jtyp) Base.llvmcall($(""" - %p = inttoptr i$(8sizeof(Int)) %0 to $(ityp)* - %v = atomicrmw $op $(ityp)* %p, $(ityp) %1 acq_rel + %v = atomicrmw $(op) ptr %0, $(ityp) %1 acq_rel ret $(ityp) %v """), $jtyp, Tuple{Ptr{$jtyp}, $jtyp}, ptr, x) end @@ -42,9 +56,9 @@ for op ∈ ["xchg", "add", "sub", "and", "nand", "or", "xor", "max", "min", "uma end end end + @inline _atomic_state(ptr::Ptr{UInt}) = reinterpret(ThreadState, _atomic_load(reinterpret(Ptr{UInt32}, ptr))) @inline _atomic_store!(ptr::Ptr{UInt}, x::ThreadState) = _atomic_store!(reinterpret(Ptr{UInt32}, ptr), reinterpret(UInt32, x)) @inline function _atomic_cas_cmp!(ptr::Ptr{UInt}, cmp::ThreadState, newval::ThreadState) _atomic_cas_cmp!(reinterpret(Ptr{UInt32}, ptr), reinterpret(UInt32, cmp), reinterpret(UInt32, newval)) end - From 6d42394e64e8a275376f872f3faf8879672603e9 Mon Sep 17 00:00:00 2001 From: Chengyu HAN Date: Thu, 2 Jan 2025 18:44:15 +0800 Subject: [PATCH 3/4] compat: need julia 1.11+ --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e2f7e97..5f5dcaa 100644 --- a/Project.toml +++ b/Project.toml @@ -9,7 +9,7 @@ ManualMemory = "d125e4d3-2237-4719-b19c-fa641b8a4667" [compat] Aqua = "0.5" ManualMemory = "0.1.1" -julia = "1.5" +julia = "1.11" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" From 2dc946e989ea778acf9a777d9b8bf66fbc5e89bf Mon Sep 17 00:00:00 2001 From: Chengyu HAN Date: Thu, 2 Jan 2025 23:01:27 +0800 Subject: [PATCH 4/4] ci: update github actions --- .github/workflows/ci-julia-nightly.yml | 39 ++++++++------------------ .github/workflows/ci.yml | 38 +++++++++++-------------- 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/.github/workflows/ci-julia-nightly.yml b/.github/workflows/ci-julia-nightly.yml index 691793d..1256b81 100644 --- a/.github/workflows/ci-julia-nightly.yml +++ b/.github/workflows/ci-julia-nightly.yml @@ -2,7 +2,7 @@ name: CI (Julia nightly) on: pull_request: branches: - - master + - main paths-ignore: - 'LICENSE.md' - 'README.md' @@ -10,7 +10,7 @@ on: push: tags: '*' branches: - - master + - main paths-ignore: - 'LICENSE.md' - 'README.md' @@ -18,51 +18,36 @@ on: jobs: test-julia-nightly: timeout-minutes: 30 - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - arch: - - x64 - - x86 + # use default arch exclusive: - '0' os: - ubuntu-latest - - macOS-latest + - macOS-latest # arm - windows-latest threads: - '5' version: - - '1.5' - - '1' + # Runs on Julia nightly only. - 'nightly' - exclude: - - os: macOS-latest - arch: x86 # 32-bit Julia binaries are not available on macOS include: - - exclusive: '1' - threads: '2' - arch: x64 + # (exclusive=1, threads=2) + - arch: x64 + exclusive: '1' os: ubuntu-latest - version: '1' + threads: '2' + version: '1.11' steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: actions/cache@v4 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbae290..8477edd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: pull_request: branches: - - master + - main paths-ignore: - 'LICENSE.md' - 'README.md' @@ -10,7 +10,7 @@ on: push: tags: '*' branches: - - master + - main paths-ignore: - 'LICENSE.md' - 'README.md' @@ -30,39 +30,35 @@ jobs: - '0' os: - ubuntu-latest - - macOS-latest - windows-latest + - macos-13 # Intel threads: - '5' version: - - '1.5' - - '1' - - 'nightly' + - '1.11' + # - '1' # Use this when julia +1 > 1.11 exclude: - - os: macOS-latest + - os: macos-13 arch: x86 # 32-bit Julia binaries are not available on macOS include: - - exclusive: '1' - threads: '2' - arch: x64 + - arch: aarch64 + exclusive: '0' + os: macOS-latest # Arm + threads: '5' + version: '1.11' + # (exclusive=1, threads=2) + - arch: x64 + exclusive: '1' os: ubuntu-latest - version: '1' + threads: '2' + version: '1.11' steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v4 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: