Suppress wake-up preemption on Linux in LowLevelLifoSemaphore (parallel to Windows SetThreadPriorityBoost)#129395
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @VSadov |
There was a problem hiding this comment.
Pull request overview
This PR extends LowLevelLifoSemaphore.Block to suppress OS “wakeup advantage” during the blocking wait window, generalizing the existing Windows behavior (priority-boost suppression) and adding a Unix/Linux-native mechanism via System.Native.
Changes:
- Added
SystemNative_SuppressWakePreemption/SystemNative_RestoreWakePreemptiontoSystem.Nativeand wired them intoentrypoints.c. - Introduced Unix interop (
Interop.WakePreemption.cs) and a managed wrapper (LowLevelLifoSemaphore.WakePreemption.cs) to scope suppression/restoration. - Updated
LowLevelLifoSemaphore.Blockto use the new platform-agnostic suppression helpers instead of Windows-onlySetThreadPriorityBoostdirectly.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/libs/System.Native/pal_threading.h | Declares new wake-preemption suppression/restoration exports. |
| src/native/libs/System.Native/pal_threading.c | Implements suppression/restoration (Linux uses sched_*; other targets are stubbed). |
| src/native/libs/System.Native/entrypoints.c | Registers new exports in the System.Native entrypoint table. |
| src/libraries/Common/src/Interop/Unix/System.Native/Interop.WakePreemption.cs | Adds LibraryImport declarations for the new System.Native APIs. |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.WakePreemption.cs | Adds managed WakePreemptionScope + suppress/restore helpers (Windows/Linux/no-op). |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs | Uses the new suppression scope around _blocker.TimedWait(...) and updates the explanatory comment. |
| src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems | Wires the new interop + managed helper file into the build. |
5a789aa to
ffb920a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/native/libs/System.Native/entrypoints.c:262
SystemNative_SuppressWakePreemption/SystemNative_RestoreWakePreemptionare added to thes_sysNativeentrypoint table unconditionally, butpal_threading_wasi.c(used for WASI per System.Native/CMakeLists.txt) does not define these functions. BecauseDllImportEntrytakes the address of the symbol, this will cause a link failure for WASI static builds. The simplest fix is to put these entries under the existing#if !defined(TARGET_WASI)guard with the futex entries.
DllImportEntry(SystemNative_LowLevelFutex_WakeByAddressSingle)
#endif
DllImportEntry(SystemNative_SuppressWakePreemption)
DllImportEntry(SystemNative_RestoreWakePreemption)
DllImportEntry(SystemNative_LoadLibrary)
|
@copilot there are failures on musl. Can that be fixed? |
Fixed in The musl failures were due to debug assert aborts when |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/native/libs/System.Native/entrypoints.c:262
- These new
DllImportEntry(SystemNative_SuppressWakePreemption)/...RestoreWakePreemptionentries are unconditionally taking the address of the symbols (seeminipal/entrypoints.h), but the WASI build usespal_threading_wasi.c(CMakeLists.txt) which does not define these functions. This will cause undefined-symbol link failures for WASI static builds unless the entries are guarded out (similar to the futex entries) or WASI stubs are added.
#if !defined(TARGET_WASI)
DllImportEntry(SystemNative_LowLevelFutex_WaitOnAddress)
DllImportEntry(SystemNative_LowLevelFutex_WaitOnAddressTimeout)
DllImportEntry(SystemNative_LowLevelFutex_WakeByAddressSingle)
#endif
DllImportEntry(SystemNative_SuppressWakePreemption)
DllImportEntry(SystemNative_RestoreWakePreemption)
DllImportEntry(SystemNative_LoadLibrary)
|
@copilot i think we do not want to exclude musl. Can we bypass libc and do syscall directly? |
Yes — done in musl deliberately stubs With that, musl behaves the same as glibc, so I removed the Verified locally: the direct syscall succeeds for both Note This comment was generated by GitHub Copilot. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/native/libs/System.Native/entrypoints.c:261
SystemNative_SuppressWakePreemption/SystemNative_RestoreWakePreemptionare exported unconditionally, butSystem.Nativeusespal_threading_wasi.cfor WASI builds (seesrc/native/libs/System.Native/CMakeLists.txt), and that file does not define these symbols. This will cause a WASI link failure similar to why futex exports are guarded out forTARGET_WASI.
DllImportEntry(SystemNative_LowLevelFutex_WakeByAddressSingle)
#endif
DllImportEntry(SystemNative_SuppressWakePreemption)
DllImportEntry(SystemNative_RestoreWakePreemption)
47a711e to
905e516
Compare
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
905e516 to
1dcc5c8
Compare
Note
AI-generated draft.
This change implements the Linux counterpart to the existing Windows wake-preemption suppression used around
LowLevelLifoSemaphore.Block. The goal is the same on both platforms: a worker waking from park should rejoin queue processing without receiving a transient wake-up scheduling advantage over already-running workers.LowLevelLifoSemaphore integration
SetThreadPriorityBoostblock inBlockwith platform-agnosticSuppressWakePreemption()/RestoreWakePreemption(...)helpers._blocker.TimedWait(...)window.Linux wake-preemption mechanism (System.Native)
SystemNative_SuppressWakePreemption()— sets the calling thread toSCHED_BATCHbefore the wait.SystemNative_RestoreWakePreemption()— restores the thread to the defaultSCHED_OTHER(priority 0) after the wait.Managed interop and wrapper
Interop.WakePreemption.cs.LowLevelLifoSemaphore.WakePreemption.cswithWakePreemptionScope:SetThreadPriorityBoost(true/false).SCHED_BATCHon suppress and restoresSCHED_OTHERon restore;WakePreemptionScopecarries a singlebool Suppressedfield.Debug.Asserton the return values of bothSuppressWakePreemptionandRestoreWakePreemptioninterop calls to catch unexpected syscall failures in debug builds. Failures are otherwise ignored as benign.Entry point and project plumbing
entrypoints.c(unconditional).System.Private.CoreLib.Shared.projitems.