Merge pull request #6898 from benaadams/semaphore-timeout-0
authorStephen Toub <stoub@microsoft.com>
Thu, 25 Aug 2016 11:29:39 +0000 (07:29 -0400)
committerGitHub <noreply@github.com>
Thu, 25 Aug 2016 11:29:39 +0000 (07:29 -0400)
Semaphoreslim, fail faster for timeout 0

src/mscorlib/src/System/Threading/SemaphoreSlim.cs

index 0bc175b..c2dcbb3 100644 (file)
@@ -76,6 +76,9 @@ namespace System.Threading
         // A pre-completed task with Result==true
         private readonly static Task<bool> s_trueTask =
             new Task<bool>(false, true, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default(CancellationToken));
+        // A pre-completed task with Result==false
+        private readonly static Task<bool> s_falseTask =
+            new Task<bool>(false, false, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default(CancellationToken));
 
         // No maximum constant
         private const int NO_MAXIMUM = Int32.MaxValue;
@@ -320,6 +323,13 @@ namespace System.Threading
 
             cancellationToken.ThrowIfCancellationRequested();
 
+            // Perf: Check the stack timeout parameter before checking the volatile count
+            if (millisecondsTimeout == 0 && m_currentCount == 0)
+            {
+                // Pessimistic fail fast, check volatile count outside lock (only when timeout is zero!)
+                return false;
+            }
+
             uint startTime = 0;
             if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout > 0)
             {
@@ -618,6 +628,11 @@ namespace System.Threading
                     if (m_waitHandle != null && m_currentCount == 0) m_waitHandle.Reset();
                     return s_trueTask;
                 }
+                else if (millisecondsTimeout == 0)
+                {
+                    // No counts, if timeout is zero fail fast
+                    return s_falseTask;
+                }
                     // If there aren't, create and return a task to the caller.
                     // The task will be completed either when they've successfully acquired
                     // the semaphore or when the timeout expired or cancellation was requested.