Skip to content

Commit b4c12f4

Browse files
authored
Random.DSFMT: thread-safe access to globals (#58120)
1 parent d9fafab commit b4c12f4

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

stdlib/Random/src/DSFMT.jl

+17-16
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,17 @@ function mulxmod!(f::GF2X, m::GF2X, deg=degree(m))::GF2X
126126
end
127127

128128
# cache for X^(2i) mod m
129-
const _squares = Dict{GF2X, Vector{GF2X}}()
129+
const _squares = Base.Lockable(Dict{GF2X, Vector{GF2X}}())
130130

131131
# compute f^2 mod m
132132
function sqrmod!(f::GF2X, m::GF2X)::GF2X
133133
d = degree(m)-1
134134
0 <= degree(f) <= d || throw(DomainError("f must satisfy 0 <= degree(f) <= degree(m)-1"))
135-
sqrs = get!(_squares, m) do
135+
sqrs = @lock _squares get(_squares[], m, nothing)
136+
if sqrs === nothing
136137
x2i = GF2X(1)
137-
GF2X[copy(mulxmod!(mulxmod!(x2i, m, d+1), m, d+1)) for i=1:d]
138+
sqrs = GF2X[copy(mulxmod!(mulxmod!(x2i, m, d+1), m, d+1)) for i=1:d]
139+
@lock _squares get!(_squares[], m, sqrs)
138140
end
139141
foldl(filter(i->coeff(f, i), 0:degree(f)); init=GF2X(0)) do g, i
140142
i <= d÷2 ? # optimization for "simple" squares
@@ -154,16 +156,10 @@ function powxmod(e::BigInt, m::GF2X)::GF2X
154156
end
155157

156158
"Cached jump polynomials for `MersenneTwister`."
157-
const JumpPolys = Dict{BigInt,GF2X}()
159+
const JumpPolys = Base.Lockable(Dict{BigInt,GF2X}())
158160

159-
const CharPoly_ref = Ref{GF2X}()
160-
# Ref because it can not be initialized at load time
161-
function CharPoly()
162-
if !isassigned(CharPoly_ref)
163-
CharPoly_ref[] = GF2X(Poly19937)
164-
end
165-
return CharPoly_ref[]
166-
end
161+
# OncePerProcess because it can not be initialized at load time
162+
const CharPoly = OncePerProcess{GF2X}(() -> GF2X(Poly19937))
167163

168164
"""
169165
calc_jump(steps::Integer)
@@ -175,12 +171,17 @@ less than the period (e.g. ``steps ≪ 2^19937-1``).
175171
function calc_jump(steps::Integer,
176172
charpoly::GF2X=CharPoly())::GF2X
177173
steps < 0 && throw(DomainError("jump steps must be >= 0 (got $steps)"))
178-
if isempty(JumpPolys)
179-
JumpPolys[big(10)^20] = GF2X(JPOLY1e20)
174+
poly = @lock JumpPolys begin
175+
if isempty(JumpPolys[])
176+
JumpPolys[][big(10)^20] = GF2X(JPOLY1e20)
177+
end
178+
get(JumpPolys[], steps, nothing)
180179
end
181-
get!(JumpPolys, steps) do
182-
powxmod(big(steps), charpoly)
180+
if poly === nothing
181+
poly = powxmod(big(steps), charpoly)
182+
@lock JumpPolys get!(JumpPolys[], steps, poly)
183183
end
184+
poly
184185
end
185186

186187

0 commit comments

Comments
 (0)