Improve ReaderWriterLockSlim scalability (#13243)
authorKoundinya Veluri <kouvel@users.noreply.github.com>
Thu, 14 Sep 2017 21:48:33 +0000 (14:48 -0700)
committerGitHub <noreply@github.com>
Thu, 14 Sep 2017 21:48:33 +0000 (14:48 -0700)
commit7f2b64a2e53d69f9605b056a745a80ca21fd27c7
tree1988ffd7e19cfec5199639b99bbff8ba032ed2f7
parent2516a47479c5c8a458b3b70d9d63d424c7ed8ca3
Improve ReaderWriterLockSlim scalability (#13243)

Improve ReaderWriterLockSlim scalability

Fixes #12780

The _myLock spin lock runs into some bad scalability issues. For example:
- Readers can starve writers for an unreasonable amount of time. Typically there would be more readers than writers, and it doesn't take many readers to starve a writer. On my machine with 6 cores (12 logical processors with hyperthreading), 6 to 16 reader threads attempting to acquire the spin lock to acquire or release a read lock can starve one writer thread from acquiring the spin lock for several or many seconds. The issue magnifies with more reader threads.
- Readers and especially writers that hold the RW lock can be starved from even releasing their lock. Releasing an RW lock requires acquiring the spin lock, so releasers are easliy starved by acquirers. How badly they are starved depends on how many acquirers there are, and it doesn't take many to show a very noticeable scalability issue. Often, these acquirers are those that would not be able to acquire the RW lock until one or more releasers release their lock, so the acquirers effectively starve themselves.

Took some suggestions from @vancem and landed on the following after some experiments:
- Introduced some fairness to _myLock acquisition by deprioritizing attempts to acquire _myLock that are not likely to make progress on the RW lock
- Limited spinning in some cases where it is very unlikely that spinning would help
src/mscorlib/shared/System/Threading/ReaderWriterLockSlim.cs