// 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;
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)
{
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.