Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions base/lock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ end


# share a lock/condition, since we just need it briefly, so some contention is okay
const PerThreadLock = ThreadSynchronizer()
const PerThreadLock = Threads.SpinLock()
"""
OncePerThread{T}(init::Function)() -> T

Expand Down Expand Up @@ -901,7 +901,15 @@ OncePerThread(initializer) = OncePerThread{Base.promote_op(initializer), typeof(
state = @atomic :monotonic ss[tid]
while state == PerStateConcurrent
# lost race, wait for notification this is done running elsewhere
wait(PerThreadLock) # wait for initializer to finish without releasing this thread
# without releasing this thread
unlock(PerThreadLock)
while state == PerStateConcurrent
# spin loop until ready
ss = @atomic :acquire once.ss
state = @atomic :monotonic ss[tid]
GC.safepoint()
end
lock(PerThreadLock)
ss = @atomic :monotonic once.ss
state = @atomic :monotonic ss[tid]
end
Expand All @@ -915,7 +923,6 @@ OncePerThread(initializer) = OncePerThread{Base.promote_op(initializer), typeof(
lock(PerThreadLock)
ss = @atomic :monotonic once.ss
@atomic :release ss[tid] = PerStateErrored
notify(PerThreadLock)
rethrow()
end
# store result and notify waiters
Expand All @@ -924,7 +931,6 @@ OncePerThread(initializer) = OncePerThread{Base.promote_op(initializer), typeof(
@atomic :release xs[tid] = result
ss = @atomic :monotonic once.ss
@atomic :release ss[tid] = PerStateHasrun
notify(PerThreadLock)
elseif state == PerStateErrored
error("OncePerThread initializer failed previously")
elseif state != PerStateHasrun
Expand Down