From 8512f16d9c5b08dd88425cf9c9ddb926e72fb11f Mon Sep 17 00:00:00 2001 From: krynju Date: Mon, 9 Aug 2021 19:23:33 +0200 Subject: [PATCH 1/2] remove wait() usage --- stdlib/Distributed/src/remotecall.jl | 75 ++++++++++++++++++---------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/stdlib/Distributed/src/remotecall.jl b/stdlib/Distributed/src/remotecall.jl index 088b7416f4488..590d4802a2b6c 100644 --- a/stdlib/Distributed/src/remotecall.jl +++ b/stdlib/Distributed/src/remotecall.jl @@ -84,20 +84,28 @@ end function finalize_ref(r::AbstractRemoteRef) if r.where > 0 # Handle the case of the finalizer having been called manually - if islocked(client_refs) - # delay finalizer for later, when it's not already locked - finalizer(finalize_ref, r) - return nothing - end - delete!(client_refs, r) - if isa(r, RemoteChannel) - send_del_client(r) - else - # send_del_client only if the reference has not been set - r.v === nothing && send_del_client(r) - r.v = nothing + if trylock(client_refs.lock) # trylock doesn't call wait which causes yields + try + delete!(client_refs.ht, r) # direct removal avoiding locks + + if isa(r, RemoteChannel) + send_del_client_no_lock(r) + else + # send_del_client only if the reference has not been set + r.v === nothing && send_del_client_no_lock(r) + r.v = nothing + end + r.where = 0 + + catch + unlock(client_refs.lock) + finalizer(finalize_ref, r) + return nothing + finally + unlock(client_refs.lock) + end end - r.where = 0 + end nothing end @@ -229,18 +237,22 @@ del_client(rr::AbstractRemoteRef) = del_client(remoteref_id(rr), myid()) del_client(id, client) = del_client(PGRP, id, client) function del_client(pg, id, client) lock(client_refs) do - rv = get(pg.refs, id, false) - if rv !== false - delete!(rv.clientset, client) - if isempty(rv.clientset) - delete!(pg.refs, id) - #print("$(myid()) collected $id\n") - end - end + _del_client(pg, id, client) end nothing end +function _del_client(pg, id, client) + rv = get(pg.refs, id, false) + if rv !== false + delete!(rv.clientset, client) + if isempty(rv.clientset) + delete!(pg.refs, id) + #print("$(myid()) collected $id\n") + end + end +end + function del_clients(pairs::Vector) for p in pairs del_client(p[1], p[2]) @@ -259,13 +271,26 @@ function send_del_client(rr) if rr.where == myid() del_client(rr) elseif id_in_procs(rr.where) # process only if a valid worker - w = worker_from_id(rr.where)::Worker - push!(w.del_msgs, (remoteref_id(rr), myid())) - w.gcflag = true - notify(any_gc_flag) + process_worker(rr) + end +end + +function send_del_client_no_lock(rr) + # for gc context to avoid yields + if rr.where == myid() + _del_client(PGRP, remoteref_id(rr), myid()) + elseif id_in_procs(rr.where) # process only if a valid worker + process_worker(rr) end end +function process_worker(rr) + w = worker_from_id(rr.where)::Worker + push!(w.del_msgs, (remoteref_id(rr), myid())) + w.gcflag = true + notify(any_gc_flag) +end + function add_client(id, client) lock(client_refs) do rv = lookup_ref(id) From 63f8178941b013e49778269c25f10227c4cae9d3 Mon Sep 17 00:00:00 2001 From: krynju Date: Mon, 9 Aug 2021 20:08:29 +0200 Subject: [PATCH 2/2] fix trylock/finalizer retry flow --- stdlib/Distributed/src/remotecall.jl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/stdlib/Distributed/src/remotecall.jl b/stdlib/Distributed/src/remotecall.jl index 590d4802a2b6c..fabcf10686068 100644 --- a/stdlib/Distributed/src/remotecall.jl +++ b/stdlib/Distributed/src/remotecall.jl @@ -87,7 +87,6 @@ function finalize_ref(r::AbstractRemoteRef) if trylock(client_refs.lock) # trylock doesn't call wait which causes yields try delete!(client_refs.ht, r) # direct removal avoiding locks - if isa(r, RemoteChannel) send_del_client_no_lock(r) else @@ -96,16 +95,13 @@ function finalize_ref(r::AbstractRemoteRef) r.v = nothing end r.where = 0 - - catch - unlock(client_refs.lock) - finalizer(finalize_ref, r) - return nothing finally unlock(client_refs.lock) end + else + finalizer(finalize_ref, r) + return nothing end - end nothing end @@ -251,6 +247,7 @@ function _del_client(pg, id, client) #print("$(myid()) collected $id\n") end end + nothing end function del_clients(pairs::Vector)