Skip to content

Commit b099010

Browse files
authored
Add UnsafeAtomics.fence (#19)
1 parent 2c4e5de commit b099010

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

src/UnsafeAtomics.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ function load end
66
function store! end
77
function cas! end
88
function modify! end
9+
function fence end
910

1011
function add! end
1112
function sub! end
@@ -17,6 +18,7 @@ function xor! end
1718
function max! end
1819
function min! end
1920

21+
# =>
2022
right(_, x) = x
2123

2224
module Internal

src/core.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
@inline UnsafeAtomics.store!(x, v) = UnsafeAtomics.store!(x, v, seq_cst)
33
@inline UnsafeAtomics.cas!(x, cmp, new) = UnsafeAtomics.cas!(x, cmp, new, seq_cst, seq_cst)
44
@inline UnsafeAtomics.modify!(ptr, op, x) = UnsafeAtomics.modify!(ptr, op, x, seq_cst)
5+
@inline UnsafeAtomics.fence() = UnsafeAtomics.fence(seq_cst)
56

67
#! format: off
78
# https://github.com/JuliaLang/julia/blob/v1.6.3/base/atomics.jl#L23-L30
@@ -218,7 +219,28 @@ for typ in (inttypes..., floattypes...)
218219
end
219220
end
220221
end
222+
end
221223

224+
# Core.Intrinsics.atomic_fence was introduced in 1.10
225+
function UnsafeAtomics.fence(ord::Ordering)
226+
Core.Intrinsics.atomic_fence(base_ordering(ord))
227+
return nothing
228+
end
229+
if Sys.ARCH == :x86_64
230+
# FIXME: Disable this once on LLVM 19
231+
# This is unfortunatly required for good-performance on AMD
232+
# https://github.com/llvm/llvm-project/pull/106555
233+
function UnsafeAtomics.fence(::typeof(seq_cst))
234+
Base.llvmcall(
235+
(raw"""
236+
define void @fence() #0 {
237+
entry:
238+
tail call void asm sideeffect "lock orq $$0 , (%rsp)", ""(); should this have ~{memory}
239+
ret void
240+
}
241+
attributes #0 = { alwaysinline }
242+
""", "fence"), Nothing, Tuple{})
243+
end
222244
end
223245

224246
as_native_uint(::Type{T}) where {T} =

test/UnsafeAtomicsTests/src/test_core.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module TestCore
22

3-
using UnsafeAtomics: UnsafeAtomics, acquire, release, acq_rel, right
3+
using UnsafeAtomics: UnsafeAtomics, monotonic, acquire, release, acq_rel, seq_cst, right
44
using UnsafeAtomics.Internal: OP_RMW_TABLE, inttypes, floattypes
55
using Test
66

@@ -16,6 +16,7 @@ function test_default_ordering()
1616
@testset for T in (asbits(T) for T in inttypes if T <: Unsigned)
1717
test_default_ordering(T)
1818
end
19+
UnsafeAtomics.fence()
1920
end
2021

2122
rmw_table_for(@nospecialize T) =
@@ -58,6 +59,11 @@ function test_explicit_ordering()
5859
@testset for T in [UInt, Float64]
5960
test_explicit_ordering(T)
6061
end
62+
UnsafeAtomics.fence(monotonic)
63+
UnsafeAtomics.fence(acquire)
64+
UnsafeAtomics.fence(release)
65+
UnsafeAtomics.fence(acq_rel)
66+
UnsafeAtomics.fence(seq_cst)
6167
end
6268

6369
function test_explicit_ordering(T::Type)

0 commit comments

Comments
 (0)