diff options
author | Sergiy Kuryata <sergeyk@microsoft.com> | 2017-06-22 02:17:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-22 02:17:03 +0300 |
commit | b2f2c1ee217361240c08c7c26403f6f33cc99841 (patch) | |
tree | d2337160705598b4caf4585b67a7847a225cbb3a /src/Native/Runtime/RWLock.cpp | |
parent | 98015d079804c686c5b0ae70c639ca22ab5dccfc (diff) |
Block the attaching/detaching threads if GC is in progress (#3956)
Currently, the threads that are detaching from or attaching to the runtime
can end up spinning for a long time in the ThreadStore lock for the entire
duration of a GC because the lock is held while GC is in progress. This
problem becomes quite visible when Windows thread pool injects a couple
hundreds of worker threads into a process.
This change fixes the problem by adding an option to the lock to block
spinning threads on the GC event if GC is in progress.
With this change, I see a couple percent improvement on micro-benchmarks.
Diffstat (limited to 'src/Native/Runtime/RWLock.cpp')
-rw-r--r-- | src/Native/Runtime/RWLock.cpp | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/Native/Runtime/RWLock.cpp b/src/Native/Runtime/RWLock.cpp index 39d4c61ad..aae8de69f 100644 --- a/src/Native/Runtime/RWLock.cpp +++ b/src/Native/Runtime/RWLock.cpp @@ -23,6 +23,7 @@ #include "event.h" #include "RWLock.h" #include "threadstore.h" +#include "threadstore.inl" #include "RuntimeInstance.h" // Configurable constants used across our spin locks @@ -81,7 +82,7 @@ ReaderWriterLock::WriteHolder::~WriteHolder() #endif // !DACCESS_COMPILE } -ReaderWriterLock::ReaderWriterLock() : +ReaderWriterLock::ReaderWriterLock(bool fBlockOnGc) : m_RWLock(0) #if 0 , m_WriterWaiting(false) @@ -92,6 +93,7 @@ ReaderWriterLock::ReaderWriterLock() : (PalGetProcessCpuCount() == 1) ? 0 : #endif 4000); + m_fBlockOnGc = fBlockOnGc; } @@ -247,6 +249,13 @@ void ReaderWriterLock::AcquireWriteLock() if (TryAcquireWriteLock()) return; + // Do not spin if GC is in progress because the lock will not + // be released until GC is finished. + if (m_fBlockOnGc && ThreadStore::IsTrapThreadsRequested()) + { + RedhawkGCInterface::WaitForGCCompletion(); + } + if (g_SystemInfo.dwNumberOfProcessors <= 1) { break; |