Let GCs run while the watchdog sleeps (Julia 1.12+) - #123
Merged
Merged
Conversation
The watchdog thread polled with `Libc.systemsleep`, a plain `ccall`, so it stayed GC-unsafe for the whole 50 ms sleep and every stop-the-world GC in the test process waited for it to wake up: 25-50 ms of extra time-to-safepoint per GC on Windows, 50-190 ms on GitHub macOS runners, none of it counted in the GC time reported for test items. `_watchdog_loop` now sleeps through `_watchdog_sleep`, which on Julia >= 1.12 uses `@ccall gc_safe=true`: `usleep` on Unix and libuv's `uv_sleep` on Windows. `@ccall` cannot express `stdcall`, which Win32 `Sleep` needs on 32-bit Windows; `uv_sleep` is a cdecl wrapper around `Sleep` exported by the Julia runtime. Older Julia keeps `Libc.systemsleep`, behind `@static` so the new macro form is never expanded there. The explicit `GC.safepoint()` stays. Measured with a 200 MB heap and 5x GC.gc(true): time-to-safepoint per GC drops from ~23 ms mean to 0 on 1.12.7 and 1.13.0 (x64) and on 1.12.7 (x86); 1.11 is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On Julia 1.12 and later, the test server's watchdog thread now sleeps in a GC-safe region. Stop-the-world collections in a test process no longer have to wait for it to wake up.
Why
_watchdog_loopsleeps withLibc.systemsleep(0.05), which is a plainccall. The thread therefore stays GC-unsafe for the whole sleep. Every collection in the test process, including the frequent young ones during an item, waits until the watchdog wakes and reaches itsGC.safepoint().total_timeexcludes time-to-safepoint.Changes
_watchdog_sleep(seconds):@ccall gc_safe=truetousleepon Unix and to libuv'suv_sleepon Windows.Libc.systemsleep, unchanged.@staticensures older versions never expand the new form. The file loads and sleeps correctly on Julia 1.0 through 1.13.uv_sleepon Windows:@ccallcan't expressstdcall, and calling Win32Sleepas cdecl would corrupt the stack on 32-bit Windows.uv_sleepis a cdecl function exported by the Julia runtime, and on Windows it is exactlySleep(msec). It doesn't touch the event loop.GC.safepoint()in the loop stays, because older Julia still depends on it. Comments are updated.Measurements
Base.gc_num().total_time_to_safepointperGC.gc(true), averaged over 5 collections. Setup:--threads=1,2, a 200 MB heap, the realwatchdog.jlloop running.The Unix
usleeppath was not run locally, since I only have Windows. It's the same callLibc.systemsleepmakes, withgc_safe=trueadded, and CI runs it on Linux and macOS.Testing
test_worker_lifecycle.jl,test_timeout.jlandtest_shutdown.jlpass on Julia 1.12 (89/89). They include "GC between test items does not deadlock the test process" and the hang-diagnostics timeout item. The Julia 1.0/1.6/1.11/1.12 platform items also pass.Related
Found during the arm64 GC investigation, alongside #121 and #122.
🤖 Generated with Claude Code