From b0990103fef610d7a0c0ede1bf5ec64cda48ad6c Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 3 Dec 2024 13:42:23 +0100 Subject: [PATCH] Add UnsafeAtomics.fence (#19) --- src/UnsafeAtomics.jl | 2 ++ src/core.jl | 22 ++++++++++++++++++++++ test/UnsafeAtomicsTests/src/test_core.jl | 8 +++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/UnsafeAtomics.jl b/src/UnsafeAtomics.jl index dc94878..a83b8d2 100644 --- a/src/UnsafeAtomics.jl +++ b/src/UnsafeAtomics.jl @@ -6,6 +6,7 @@ function load end function store! end function cas! end function modify! end +function fence end function add! end function sub! end @@ -17,6 +18,7 @@ function xor! end function max! end function min! end +# => right(_, x) = x module Internal diff --git a/src/core.jl b/src/core.jl index 881152b..aff57f8 100644 --- a/src/core.jl +++ b/src/core.jl @@ -2,6 +2,7 @@ @inline UnsafeAtomics.store!(x, v) = UnsafeAtomics.store!(x, v, seq_cst) @inline UnsafeAtomics.cas!(x, cmp, new) = UnsafeAtomics.cas!(x, cmp, new, seq_cst, seq_cst) @inline UnsafeAtomics.modify!(ptr, op, x) = UnsafeAtomics.modify!(ptr, op, x, seq_cst) +@inline UnsafeAtomics.fence() = UnsafeAtomics.fence(seq_cst) #! format: off # https://github.com/JuliaLang/julia/blob/v1.6.3/base/atomics.jl#L23-L30 @@ -218,7 +219,28 @@ for typ in (inttypes..., floattypes...) end end end +end +# Core.Intrinsics.atomic_fence was introduced in 1.10 +function UnsafeAtomics.fence(ord::Ordering) + Core.Intrinsics.atomic_fence(base_ordering(ord)) + return nothing +end +if Sys.ARCH == :x86_64 + # FIXME: Disable this once on LLVM 19 + # This is unfortunatly required for good-performance on AMD + # https://github.com/llvm/llvm-project/pull/106555 + function UnsafeAtomics.fence(::typeof(seq_cst)) + Base.llvmcall( + (raw""" + define void @fence() #0 { + entry: + tail call void asm sideeffect "lock orq $$0 , (%rsp)", ""(); should this have ~{memory} + ret void + } + attributes #0 = { alwaysinline } + """, "fence"), Nothing, Tuple{}) + end end as_native_uint(::Type{T}) where {T} = diff --git a/test/UnsafeAtomicsTests/src/test_core.jl b/test/UnsafeAtomicsTests/src/test_core.jl index 69ef953..4d4b1cf 100644 --- a/test/UnsafeAtomicsTests/src/test_core.jl +++ b/test/UnsafeAtomicsTests/src/test_core.jl @@ -1,6 +1,6 @@ module TestCore -using UnsafeAtomics: UnsafeAtomics, acquire, release, acq_rel, right +using UnsafeAtomics: UnsafeAtomics, monotonic, acquire, release, acq_rel, seq_cst, right using UnsafeAtomics.Internal: OP_RMW_TABLE, inttypes, floattypes using Test @@ -16,6 +16,7 @@ function test_default_ordering() @testset for T in (asbits(T) for T in inttypes if T <: Unsigned) test_default_ordering(T) end + UnsafeAtomics.fence() end rmw_table_for(@nospecialize T) = @@ -58,6 +59,11 @@ function test_explicit_ordering() @testset for T in [UInt, Float64] test_explicit_ordering(T) end + UnsafeAtomics.fence(monotonic) + UnsafeAtomics.fence(acquire) + UnsafeAtomics.fence(release) + UnsafeAtomics.fence(acq_rel) + UnsafeAtomics.fence(seq_cst) end function test_explicit_ordering(T::Type)