Skip to content

Commit

Permalink
Limit the supported atomic types per platform (#35497)
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy authored Apr 20, 2020
1 parent 881fee9 commit 8d8f46d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
19 changes: 15 additions & 4 deletions base/atomics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ export
atomic_and!, atomic_nand!, atomic_or!, atomic_xor!,
atomic_max!, atomic_min!,
atomic_fence

# 128-bit atomics do not exist on AArch32.
if startswith(string(ARCH), "arm")
##
# Filter out unsupported atomic types on platforms
# - 128-bit atomics do not exist on AArch32.
# - Omitting 128-bit types on 32bit x86 and ppc64
# - LLVM doesn't currently support atomics on floats for ppc64
# C++20 is adding limited support for atomics on float, but as of
# now Clang does not support that yet.
if Sys.ARCH == :i686 || startswith(string(Sys.ARCH), "arm") ||
Sys.ARCH === :powerpc64le || Sys.ARCH === :ppc64le
const inttypes = (Int8, Int16, Int32, Int64,
UInt8, UInt16, UInt32, UInt64)
else
Expand All @@ -25,7 +31,12 @@ end
const floattypes = (Float16, Float32, Float64)
const arithmetictypes = (inttypes..., floattypes...)
# TODO: Support Ptr
const atomictypes = (arithmetictypes..., Bool)
if Sys.ARCH === :powerpc64le || Sys.ARCH === :ppc64le
const atomictypes = (inttypes..., Bool)
else
const atomictypes = (arithmetictypes..., Bool)
end

const IntTypes = Union{inttypes...}
const FloatTypes = Union{floattypes...}
const ArithmeticTypes = Union{arithmetictypes...}
Expand Down
36 changes: 21 additions & 15 deletions test/threads_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,19 @@ end
@test_throws TypeError Atomic{BigInt}
@test_throws TypeError Atomic{ComplexF64}

if Sys.ARCH == :i686 || startswith(string(Sys.ARCH), "arm") ||
Sys.ARCH === :powerpc64le || Sys.ARCH === :ppc64le

@test_throws TypeError Atomic{Int128}()
@test_throws TypeError Atomic{UInt128}()
end

if Sys.ARCH === :powerpc64le || Sys.ARCH === :ppc64le
@test_throws TypeError Atomic{Float16}()
@test_throws TypeError Atomic{Float32}()
@test_throws TypeError Atomic{Float64}()
end

function test_atomic_bools()
x = Atomic{Bool}(false)
# Arithmetic functions are not defined.
Expand Down Expand Up @@ -344,18 +357,11 @@ end
test_fence()

# Test load / store with various types
let atomic_types = [Int8, Int16, Int32, Int64, Int128,
UInt8, UInt16, UInt32, UInt64, UInt128,
Float16, Float32, Float64]
# Temporarily omit 128-bit types on 32bit x86
# 128-bit atomics do not exist on AArch32.
# And we don't support them yet on power, because they are lowered
# to `__sync_lock_test_and_set_16`.
if Sys.ARCH === :i686 || startswith(string(Sys.ARCH), "arm") ||
Sys.ARCH === :powerpc64le || Sys.ARCH === :ppc64le
filter!(T -> sizeof(T)<=8, atomic_types)
end
for T in atomic_types
let atomictypes = intersect((Int8, Int16, Int32, Int64, Int128,
UInt8, UInt16, UInt32, UInt64, UInt128,
Float16, Float32, Float64),
Base.Threads.atomictypes)
for T in atomictypes
var = Atomic{T}()
var[] = 42
@test var[] === T(42)
Expand All @@ -382,7 +388,7 @@ function test_atomic_cas!(var::Atomic{T}, range::StepRange{Int,Int}) where T
end
end
end
for T in (Int32, Int64, Float32, Float64)
for T in intersect((Int32, Int64, Float32, Float64), Base.Threads.atomictypes)
var = Atomic{T}()
nloops = 1000
di = nthreads()
Expand All @@ -396,7 +402,7 @@ function test_atomic_xchg!(var::Atomic{T}, i::Int, accum::Atomic{Int}) where T
old = atomic_xchg!(var, T(i))
atomic_add!(accum, Int(old))
end
for T in (Int32, Int64, Float32, Float64)
for T in intersect((Int32, Int64, Float32, Float64), Base.Threads.atomictypes)
accum = Atomic{Int}()
var = Atomic{T}()
nloops = 1000
Expand All @@ -411,7 +417,7 @@ function test_atomic_float(varadd::Atomic{T}, varmax::Atomic{T}, varmin::Atomic{
atomic_max!(varmax, T(i))
atomic_min!(varmin, T(i))
end
for T in (Int32, Int64, Float16, Float32, Float64)
for T in intersect((Int32, Int64, Float16, Float32, Float64), Base.Threads.atomictypes)
varadd = Atomic{T}()
varmax = Atomic{T}()
varmin = Atomic{T}()
Expand Down

0 comments on commit 8d8f46d

Please sign in to comment.