try using atomic{int} for growinglist length

This commit is contained in:
Jutho Haegeman 2021-06-15 01:18:49 +02:00
parent 38e5f809f2
commit a04c500646
2 changed files with 9 additions and 14 deletions

View file

@ -366,17 +366,12 @@ function compute6jseries(β₁, β₂, β₃, α₁, α₂, α₃, α₄)
end end
function _precompile_() function _precompile_()
@assert precompile(prime, (Int,))
@assert precompile(primefactor, (Int,))
@assert precompile(primefactorial, (Int,))
@assert precompile(wigner3j, (Type{Float64}, Int, Int, Int, Int, Int, Int)) @assert precompile(wigner3j, (Type{Float64}, Int, Int, Int, Int, Int, Int))
@assert precompile(wigner6j, (Type{Float64}, Int, Int, Int, Int, Int, Int)) @assert precompile(wigner6j, (Type{Float64}, Int, Int, Int, Int, Int, Int))
@assert precompile(wigner3j, (Type{BigFloat}, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt)) @assert precompile(wigner3j, (Type{BigFloat}, Rational{Int}, Rational{Int}, Rational{Int}, Rational{Int}, Rational{Int}, Rational{Int}))
@assert precompile(wigner6j, (Type{BigFloat}, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt)) @assert precompile(wigner6j, (Type{BigFloat}, Rational{Int}, Rational{Int}, Rational{Int}, Rational{Int}, Rational{Int}, Rational{Int}))
@assert precompile(getindex, (GrowingList{Int}, Int)) @assert precompile(wigner3j, (Type{RRBig}, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt))
@assert precompile(getindex, (GrowingList{BigInt}, Int)) @assert precompile(wigner6j, (Type{RRBig}, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt, HalfInt))
@assert precompile(get!, (GrowingList{Int}, Int, Int))
@assert precompile(get!, (GrowingList{BigInt}, Int, BigInt))
end end
_precompile_() _precompile_()

View file

@ -1,4 +1,4 @@
using Base.Threads: Atomic, SpinLock using Base.Threads: Atomic, SpinLock, atomic_add!
# ListSegment represents a segment from a GrowingList; it has a list `data` to hold the elements, filled up to `currentlength`, and possibly a reference to the next segment, if it is not the final segment. # ListSegment represents a segment from a GrowingList; it has a list `data` to hold the elements, filled up to `currentlength`, and possibly a reference to the next segment, if it is not the final segment.
mutable struct ListSegment{T} mutable struct ListSegment{T}
@ -66,7 +66,7 @@ The list is grown by adding new segments using a linked list data structure. Thi
""" """
mutable struct GrowingList{T} <: AbstractVector{T} mutable struct GrowingList{T} <: AbstractVector{T}
first::ListSegment{T} first::ListSegment{T}
totallength::Int totallength::Atomic{Int}
growthfactor::Float64 growthfactor::Float64
lock::SpinLock lock::SpinLock
function GrowingList{T}(iter; function GrowingList{T}(iter;
@ -88,7 +88,7 @@ mutable struct GrowingList{T} <: AbstractVector{T}
_unsafe_getindex(first, i, val, ceil(Int, (i-1)*growthfactor)) _unsafe_getindex(first, i, val, ceil(Int, (i-1)*growthfactor))
next = iterate(iter, state) next = iterate(iter, state)
end end
return new{T}(first, i, growthfactor, SpinLock()) return new{T}(first, Atomic{Int}(i), growthfactor, SpinLock())
end end
end end
GrowingList(v::Vector{T}; sizehint = max(16, length(v)), growthfactor = 2.) where {T} = GrowingList(v::Vector{T}; sizehint = max(16, length(v)), growthfactor = 2.) where {T} =
@ -100,9 +100,9 @@ GrowingList{T}(; sizehint = 16, growthfactor = 2.) where {T} =
GrowingList(; sizehint = 16, growthfactor = 2.) = GrowingList(; sizehint = 16, growthfactor = 2.) =
GrowingList{Any}((); sizehint = sizehint, growthfactor = growthfactor) GrowingList{Any}((); sizehint = sizehint, growthfactor = growthfactor)
Base.length(l::GrowingList) = l.totallength Base.length(l::GrowingList) = l.totallength[]
function _raise_length!(l::GrowingList) function _raise_length!(l::GrowingList)
l.totallength += 1 atomic_add!(l.totallength, 1)
end end
Base.size(l::GrowingList) = (length(l),) Base.size(l::GrowingList) = (length(l),)