Skip to content

Commit

Permalink
Add UnsafeAtomics.fence (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy authored Dec 3, 2024
1 parent 2c4e5de commit b099010
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/UnsafeAtomics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,6 +18,7 @@ function xor! end
function max! end
function min! end

# =>
right(_, x) = x

module Internal
Expand Down
22 changes: 22 additions & 0 deletions src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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} =
Expand Down
8 changes: 7 additions & 1 deletion test/UnsafeAtomicsTests/src/test_core.jl
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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) =
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit b099010

Please sign in to comment.