Skip to content

Commit b258524

Browse files
authored
Merge pull request #455 from JuliaParallel/jps/errormonitor-spin-lock
errormonitor_tracked: Use spin lock
2 parents 304888d + 0b695bc commit b258524

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

Diff for: src/sch/Sch.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Base: @invokelatest
1111
import ..Dagger
1212
import ..Dagger: Context, Processor, Thunk, WeakThunk, ThunkFuture, ThunkFailedException, Chunk, WeakChunk, OSProc, AnyScope, DefaultScope, LockedObject
1313
import ..Dagger: order, dependents, noffspring, istask, inputs, unwrap_weak_checked, affinity, tochunk, timespan_start, timespan_finish, procs, move, chunktype, processor, default_enabled, get_processors, get_parent, execute!, rmprocs!, addprocs!, thunk_processor, constrain, cputhreadtime
14-
import ..Dagger: @dagdebug
14+
import ..Dagger: @dagdebug, @safe_lock_spin1
1515
import DataStructures: PriorityQueue, enqueue!, dequeue_pair!, peek
1616

1717
import ..Dagger

Diff for: src/sch/util.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"Like `errormonitor`, but tracks how many outstanding tasks are running."
22
function errormonitor_tracked(t::Task)
33
errormonitor(t)
4-
lock(ERRORMONITOR_TRACKED) do tracked
4+
@safe_lock_spin1 ERRORMONITOR_TRACKED tracked begin
55
push!(tracked, t)
66
end
77
errormonitor(Threads.@spawn begin

Diff for: src/utils/locked-object.jl

+26
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,29 @@ function Base.lock(f, x::LockedObject)
1414
unlock(x.lock)
1515
end
1616
end
17+
Base.trylock(x::LockedObject) = trylock(x.lock)
18+
Base.unlock(x::LockedObject) = unlock(x.lock)
19+
payload(x::LockedObject) = x.payload
20+
21+
# TODO: Move this back to MemPool
22+
# If we actually want to acquire a lock from a finalizer, we can't cause a task
23+
# switch. As a NonReentrantLock can only be taken by another thread that should
24+
# be running, and not a concurrent task we'd need to switch to, we can safely
25+
# spin.
26+
macro safe_lock_spin1(l, o, ex)
27+
quote
28+
temp = $(esc(l))
29+
while !trylock(temp)
30+
# we can't yield here
31+
GC.safepoint()
32+
end
33+
MemPool.enable_finalizers(false) # retains compatibility with non-finalizer callers
34+
try
35+
$(esc(o)) = $payload(temp)
36+
$(esc(ex))
37+
finally
38+
unlock(temp)
39+
MemPool.enable_finalizers(true)
40+
end
41+
end
42+
end

0 commit comments

Comments
 (0)