Skip to content

Commit

Permalink
precompileplkgs: release parallel limiter when waiting for another pr…
Browse files Browse the repository at this point in the history
…ocess (#56844)

(cherry picked from commit 3774014)
  • Loading branch information
IanButterworth authored and KristofferC committed Jan 2, 2025
1 parent c9e523b commit ce7242c
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions base/precompilation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ function _precompilepkgs(pkgs::Vector{String},
try
# allows processes to wait if another process is precompiling a given package to
# a functionally identical package cache (except for preferences, which may differ)
t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor) do
t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter) do
Base.with_logger(Base.NullLogger()) do
# The false here means we ignore loaded modules, so precompile for a fresh session
keep_loaded_modules = false
Expand Down Expand Up @@ -1101,7 +1101,7 @@ function _color_string(cstr::String, col::Union{Int64, Symbol}, hascolor)
end

# Can be merged with `maybe_cachefile_lock` in loading?
function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor)
function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor, parallel_limiter::Base.Semaphore)
pkg, config = pkg_config
flags, cacheflags = config
FileWatching = Base.loaded_modules[Base.PkgId(Base.UUID("7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"), "FileWatching")]
Expand All @@ -1122,15 +1122,21 @@ function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLo
!fancyprint && lock(print_lock) do
println(io, " ", pkg.name, _color_string(" Being precompiled by $(pkgspidlocked[pkg_config])", Base.info_color(), hascolor))
end
# wait until the lock is available
FileWatching.mkpidlock(pidfile; stale_age) do
# double-check in case the other process crashed or the lock expired
if Base.isprecompiled(pkg; ignore_loaded=true, flags=cacheflags) # don't use caches for this as the env state will have changed
return nothing # returning nothing indicates a process waited for another
else
delete!(pkgspidlocked, pkg_config)
return f() # precompile
end
Base.release(parallel_limiter) # release so other work can be done while waiting
try
# wait until the lock is available
@invokelatest Base.mkpidlock_hook(() -> begin
# double-check in case the other process crashed or the lock expired
if Base.isprecompiled(pkg; ignore_loaded=true, flags=cacheflags) # don't use caches for this as the env state will have changed
return nothing # returning nothing indicates a process waited for another
else
delete!(pkgspidlocked, pkg_config)
Base.acquire(f, parallel_limiter) # precompile
end
end,
pidfile; stale_age)
finally
Base.acquire(parallel_limiter) # re-acquire so the outer release is balanced
end
end
return cachefile
Expand Down

0 comments on commit ce7242c

Please sign in to comment.