Skip to content

Commit

Permalink
Address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
kouvel committed Aug 8, 2017
1 parent d614819 commit f6bb711
Showing 1 changed file with 26 additions and 8 deletions.
34 changes: 26 additions & 8 deletions src/mscorlib/shared/System/Threading/ReaderWriterLockSlim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,15 @@ private bool TryEnterReadLockCore(TimeoutTracker timeout)
break;
}

if (timeout.IsExpired)
{
ExitMyLock();
return false;
}

if (spinCount < MaxSpinCount && ShouldSpinForEnterAnyRead())
{
ExitMyLock();
if (timeout.IsExpired)
return false;
spinCount++;
SpinWait(spinCount);
EnterMyLockForEnterAnyRead();
Expand Down Expand Up @@ -550,11 +554,15 @@ private bool TryEnterWriteLockCore(TimeoutTracker timeout)
}
}

if (timeout.IsExpired)
{
ExitMyLock();
return false;
}

if (spinCount < MaxSpinCount && ShouldSpinForEnterAnyWrite(upgradingToWrite))
{
ExitMyLock();
if (timeout.IsExpired)
return false;
spinCount++;
SpinWait(spinCount);
if (upgradingToWrite)
Expand Down Expand Up @@ -714,11 +722,15 @@ private bool TryEnterUpgradeableReadLockCore(TimeoutTracker timeout)
break;
}

if (timeout.IsExpired)
{
ExitMyLock();
return false;
}

if (spinCount < MaxSpinCount && ShouldSpinForEnterAnyRead())
{
ExitMyLock();
if (timeout.IsExpired)
return false;
spinCount++;
SpinWait(spinCount);
EnterMyLockForEnterAnyRead();
Expand Down Expand Up @@ -1125,13 +1137,18 @@ private bool ShouldSpinForEnterAnyRead()
{
// If there is a write waiter or write upgrade waiter, the waiter would block a reader from acquiring the RW lock
// because the waiter takes precedence. In that case, the reader is not likely to make progress by spinning.
return _fNoWaiters || _numWriteWaiters == 0 && _numWriteUpgradeWaiters == 0;
// Although another thread holding a write lock would prevent this thread from acquiring a read lock, it is by
// itself not a good enough reason to skip spinning.
return _fNoWaiters || (_numWriteWaiters == 0 && _numWriteUpgradeWaiters == 0);
}

private bool ShouldSpinForEnterAnyWrite(bool isUpgradeToWrite)
{
// If there is a write upgrade waiter, the waiter would block a writer from acquiring the RW lock because the waiter
// holds a read lock. In that case, the writer is not likely to make progress by spinning.
// holds a read lock. In that case, the writer is not likely to make progress by spinning. Regarding upgrading to a
// write lock, there is no type of waiter that would block the upgrade from happening. Although another thread
// holding a read or write lock would prevent this thread from acquiring the write lock, it is by itself not a good
// enough reason to skip spinning.
return isUpgradeToWrite || _numWriteUpgradeWaiters == 0;
}

Expand Down Expand Up @@ -1215,6 +1232,7 @@ private void EnterMyLockSpinForExitAnyRead()
{
// A read lock is held until this thread is able to exit it, so deprioritize enter-write threads as they will not be
// able to make progress
Debug.Assert(DeprioritizeEnterWriteIncrement == 1);
Interlocked.Increment(ref _enterMyLockDeprioritizationState);

int pc = ProcessorCount;
Expand Down

0 comments on commit f6bb711

Please sign in to comment.