Uh oh!
There was an error while loading. Please reload this page.
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. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
5a789aa to
ffb920aCompareThere 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)
VSadov
commented
Aug 6, 2026
@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)
VSadov
commented
Aug 7, 2026
@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
905e516CompareCo-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
1dcc5c8Compare
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.