Reapply "A few fixes in the threadpool semaphore. Unify Windows/Unix implementation of LIFO policy." (#125193)#125596
Draft
VSadov wants to merge 2 commits intodotnet:mainfrom
Draft
Reapply "A few fixes in the threadpool semaphore. Unify Windows/Unix implementation of LIFO policy." (#125193)#125596VSadov wants to merge 2 commits intodotnet:mainfrom
VSadov wants to merge 2 commits intodotnet:mainfrom
Conversation
…implementation of LIFO policy." (dotnet#125193) This reverts commit 51b1e92.
Contributor
|
Tagging subscribers to this area: @agocke, @VSadov |
Contributor
There was a problem hiding this comment.
Pull request overview
Reapplies and reworks the ThreadPool LIFO semaphore changes (previously reverted due to NuGet restore regressions) by unifying the blocking/wake implementation across Windows and Unix using OS compare-and-wait primitives (WaitOnAddress / futex) with a monitor fallback.
Changes:
- Adds low-level compare-and-wait interop for Windows (WaitOnAddress) and Linux (futex) and wires them through System.Native/CoreLib.
- Replaces the prior per-OS
LowLevelLifoSemaphoreimplementations with a unified managed implementation using a LIFO stack of per-thread blockers plus updated spin/backoff behavior. - Adjusts worker dispatch heuristics (missed-steal handling) and configuration plumbing (cooperative blocking env var alias).
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/libs/System.Native/pal_threading.h | Adds exported futex-related entrypoints to the System.Native PAL surface. |
| src/native/libs/System.Native/pal_threading.c | Implements Linux futex wait/wake wrappers; provides non-Linux stubs. |
| src/native/libs/System.Native/entrypoints.c | Registers the new futex entrypoints for managed interop. |
| src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs | Adds a 1ms sleep before requesting workers when a steal was missed. |
| src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs | Switches the worker wait to the new LowLevelLifoSemaphore.Wait(timeout, activeThreadCount) signature; removes old spin-limit wiring at the call site. |
| src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Blocking.cs | Adds the DOTNET_ThreadPool_CooperativeBlocking env var alias for cooperative blocking. |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelThreadBlocker.cs | Introduces a portable blocker abstraction (futex/WaitOnAddress or LowLevelMonitor fallback). |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs | Replaces OS-specific semaphore core with a unified managed LIFO implementation + updated spin heuristic and wake accounting. |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs | Removes the prior Windows IOCP-based LIFO semaphore implementation. |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs | Removes the prior Unix WaitSubsystem-based semaphore implementation. |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelFutex.Windows.cs | Adds Windows WaitOnAddress-based compare-and-wait wrapper. |
| src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelFutex.Unix.cs | Adds Unix futex wrapper (currently Linux-only per comments). |
| src/libraries/System.Private.CoreLib/src/System/Threading/Backoff.cs | Updates exponential backoff to return spin count and reduces max backoff. |
| src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems | Wires new threading and interop files into CoreLib build (adds/removes Compile items). |
| src/libraries/Common/src/Interop/Windows/Mincore/Interop.WaitOnAddress.cs | Adds LibraryImport declarations for WaitOnAddress/WakeByAddressSingle. |
| src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CriticalSection.cs | Adds SuppressGCTransition on LeaveCriticalSection. |
| src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs | Adds the Synch API-set library constant for WaitOnAddress imports. |
| src/libraries/Common/src/Interop/Unix/System.Native/Interop.LowLevelMonitor.cs | Adds SuppressGCTransition on LowLevelMonitor_Release. |
| src/libraries/Common/src/Interop/Unix/System.Native/Interop.Futex.cs | Adds LibraryImport declarations for futex wait/wake entrypoints. |
| src/coreclr/tools/aot/ILCompiler/reproNative/reproNative.vcxproj | Adds Synchronization.lib to link set for NativeAOT repro project. |
| src/coreclr/nativeaot/BuildIntegration/WindowsAPIs.txt | Allows WaitOnAddress/WakeByAddressSingle through the NativeAOT Windows API allowlist. |
| src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets | Adds Synchronization.lib to NativeAOT SDK library list. |
| docs/coding-guidelines/interop-guidelines.md | Updates interop guideline examples to match casing/structure and adds Synch library mention. |
You can also share your feedback on Copilot code review. Take the survey.
| { | ||
| // Spinning in the threadpool semaphore is not always useful and benefits vary greatly by scenario. | ||
| // | ||
| // Example1: An app periodically with rough time span T runs a task and waits for task`s completion. |
Comment on lines
+203
to
+207
| // if consumed a wake, decrement the count | ||
| if (waitResult == WaitResult.Woken) | ||
| { | ||
| Debug.Assert(counts.CountOfWaitersSignaledToWake != 0); | ||
| newCounts.DecrementCountOfWaitersSignaledToWake(); |
src/libraries/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.cs
Show resolved
Hide resolved
Comment on lines
+864
to
866
| Thread.Sleep(1); | ||
| ThreadPool.EnsureWorkerRequested(); | ||
| } |
| // | ||
| if (missedSteal) | ||
| { | ||
| Thread.Sleep(1); |
| <Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelLifoSemaphore.Unix.cs" Condition="'$(TargetsUnix)' == 'true' or '$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true'" /> | ||
| <Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelThreadBlocker.cs" /> | ||
| <Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelFutex.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" /> | ||
| <Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelFutex.Unix.cs" Condition="'$(TargetsUnix)' == 'true'" /> |
This was referenced Mar 16, 2026
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.
Re: #125193
TODO: need to confirm that NuGet restore performance is ok with the updated change.