From d32314361ce35c20b846e402f898f920851e59db Mon Sep 17 00:00:00 2001 From: Alex Covington Date: Wed, 4 Nov 2020 13:29:07 -0800 Subject: [PATCH 1/3] Allow threads to sleep when ConcurrentQueue has many enqueuers/dequeuers. --- .../Collections/Concurrent/ConcurrentQueueSegment.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs index 1cd82352ae1754..af7c170464f4fe 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs @@ -37,6 +37,9 @@ internal sealed class ConcurrentQueueSegment internal ConcurrentQueueSegment? _nextSegment; // SOS's ThreadPool command depends on this name #pragma warning restore 0649 + /// Threshold to spin before allowing threads to sleep when there is contention. + internal const int _sleep1Threshold = 8; + /// Creates the segment. /// /// The maximum number of elements the segment can contain. Must be a power of 2. @@ -183,7 +186,7 @@ public bool TryDequeue([MaybeNullWhen(false)] out T item) } // Lost a race. Spin a bit, then try again. - spinner.SpinOnce(sleep1Threshold: -1); + spinner.SpinOnce(sleep1Threshold: _sleep1Threshold); } } @@ -244,7 +247,7 @@ public bool TryPeek([MaybeNullWhen(false)] out T result, bool resultUsed) } // Lost a race. Spin a bit, then try again. - spinner.SpinOnce(sleep1Threshold: -1); + spinner.SpinOnce(sleep1Threshold: _sleep1Threshold); } } @@ -301,7 +304,7 @@ public bool TryEnqueue(T item) } // Lost a race. Spin a bit, then try again. - spinner.SpinOnce(sleep1Threshold: -1); + spinner.SpinOnce(sleep1Threshold: _sleep1Threshold); } } From 14fb73d88931e583164f0a5252980f746292b317 Mon Sep 17 00:00:00 2001 From: Alex Covington <68252706+alexcovington@users.noreply.github.com> Date: Thu, 5 Nov 2020 09:52:01 -0800 Subject: [PATCH 2/3] Update src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs Co-authored-by: Stephen Toub --- .../src/System/Collections/Concurrent/ConcurrentQueueSegment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs index af7c170464f4fe..8ecc01432fa94a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs @@ -186,7 +186,7 @@ public bool TryDequeue([MaybeNullWhen(false)] out T item) } // Lost a race. Spin a bit, then try again. - spinner.SpinOnce(sleep1Threshold: _sleep1Threshold); + spinner.SpinOnce(Sleep1Threshold); } } From 729d6468e97eeecdf752290ed47ac85f518cbdc1 Mon Sep 17 00:00:00 2001 From: Alex Covington <68252706+alexcovington@users.noreply.github.com> Date: Thu, 5 Nov 2020 09:52:43 -0800 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Stephen Toub --- .../System/Collections/Concurrent/ConcurrentQueueSegment.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs index 8ecc01432fa94a..e238c5b8d834c5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueueSegment.cs @@ -38,7 +38,7 @@ internal sealed class ConcurrentQueueSegment #pragma warning restore 0649 /// Threshold to spin before allowing threads to sleep when there is contention. - internal const int _sleep1Threshold = 8; + private const int Sleep1Threshold = 8; /// Creates the segment. /// @@ -247,7 +247,7 @@ public bool TryPeek([MaybeNullWhen(false)] out T result, bool resultUsed) } // Lost a race. Spin a bit, then try again. - spinner.SpinOnce(sleep1Threshold: _sleep1Threshold); + spinner.SpinOnce(Sleep1Threshold); } } @@ -304,7 +304,7 @@ public bool TryEnqueue(T item) } // Lost a race. Spin a bit, then try again. - spinner.SpinOnce(sleep1Threshold: _sleep1Threshold); + spinner.SpinOnce(Sleep1Threshold); } }