diff options
author | Koundinya Veluri <kouvel@users.noreply.github.com> | 2019-04-19 19:22:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-19 19:22:53 -0700 |
commit | 0410c3e4fe54590eea34aead28f550539d814b98 (patch) | |
tree | 0a7d9b8ee2df4e672024ed410ee04e267f8e5bbe /src/vm/threads.cpp | |
parent | 924d4fcc6961a76881a42a5a4a80479352708ace (diff) | |
download | coreclr-0410c3e4fe54590eea34aead28f550539d814b98.tar.gz coreclr-0410c3e4fe54590eea34aead28f550539d814b98.tar.bz2 coreclr-0410c3e4fe54590eea34aead28f550539d814b98.zip |
Implement APIs for some threading metrics (CoreCLR) (#24113)
Implement APIs for some threading metrics (CoreCLR)
API review: https://github.com/dotnet/corefx/issues/35500
Diffstat (limited to 'src/vm/threads.cpp')
-rw-r--r-- | src/vm/threads.cpp | 82 |
1 files changed, 60 insertions, 22 deletions
diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp index 70c26118ea..37d30c392a 100644 --- a/src/vm/threads.cpp +++ b/src/vm/threads.cpp @@ -83,7 +83,9 @@ PTR_ThreadLocalModule ThreadLocalBlock::GetTLMIfExists(MethodTable* pMT) BOOL Thread::s_fCleanFinalizedThread = FALSE; -Volatile<LONG> Thread::s_threadPoolCompletionCountOverflow = 0; +UINT64 Thread::s_workerThreadPoolCompletionCountOverflow = 0; +UINT64 Thread::s_ioThreadPoolCompletionCountOverflow = 0; +UINT64 Thread::s_monitorLockContentionCountOverflow = 0; CrstStatic g_DeadlockAwareCrst; @@ -1528,7 +1530,9 @@ Thread::Thread() m_sfEstablisherOfActualHandlerFrame.Clear(); #endif // WIN64EXCEPTIONS - m_threadPoolCompletionCount = 0; + m_workerThreadPoolCompletionCount = 0; + m_ioThreadPoolCompletionCount = 0; + m_monitorLockContentionCount = 0; Thread *pThread = GetThread(); InitContext(); @@ -5350,9 +5354,15 @@ BOOL ThreadStore::RemoveThread(Thread *target) if (target->IsBackground()) s_pThreadStore->m_BackgroundThreadCount--; - FastInterlockExchangeAdd( - &Thread::s_threadPoolCompletionCountOverflow, - target->m_threadPoolCompletionCount); + FastInterlockExchangeAddLong( + (LONGLONG *)&Thread::s_workerThreadPoolCompletionCountOverflow, + target->m_workerThreadPoolCompletionCount); + FastInterlockExchangeAddLong( + (LONGLONG *)&Thread::s_ioThreadPoolCompletionCountOverflow, + target->m_ioThreadPoolCompletionCount); + FastInterlockExchangeAddLong( + (LONGLONG *)&Thread::s_monitorLockContentionCountOverflow, + target->m_monitorLockContentionCount); _ASSERTE(s_pThreadStore->m_ThreadCount >= 0); _ASSERTE(s_pThreadStore->m_BackgroundThreadCount >= 0); @@ -8002,7 +8012,23 @@ BOOL ThreadStore::HoldingThreadStore(Thread *pThread) } } -LONG Thread::GetTotalThreadPoolCompletionCount() +NOINLINE void Thread::OnIncrementCountOverflow(UINT32 *threadLocalCount, UINT64 *overflowCount) +{ + WRAPPER_NO_CONTRACT; + _ASSERTE(threadLocalCount != nullptr); + _ASSERTE(overflowCount != nullptr); + + // Increment overflow, accumulate the count for this increment into the overflow count and reset the thread-local count + + // The thread store lock, in coordination with other places that read these values, ensures that both changes + // below become visible together + ThreadStoreLockHolder tsl; + + *threadLocalCount = 0; + InterlockedExchangeAdd64((LONGLONG *)overflowCount, (LONGLONG)UINT32_MAX + 1); +} + +UINT64 Thread::GetTotalCount(SIZE_T threadLocalCountOffset, UINT64 *overflowCount) { CONTRACTL { @@ -8011,32 +8037,44 @@ LONG Thread::GetTotalThreadPoolCompletionCount() } CONTRACTL_END; - LONG total; - if (g_fEEStarted) //make sure we actually have a thread store - { - // make sure up-to-date thread-local counts are visible to us - ::FlushProcessWriteBuffers(); + // enumerate all threads, summing their local counts. + ThreadStoreLockHolder tsl; - // enumerate all threads, summing their local counts. - ThreadStoreLockHolder tsl; + UINT64 total = GetOverflowCount(overflowCount); - total = s_threadPoolCompletionCountOverflow.Load(); + Thread *pThread = NULL; + while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL) + { + total += *GetThreadLocalCountRef(pThread, threadLocalCountOffset); + } - Thread *pThread = NULL; - while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL) - { - total += pThread->m_threadPoolCompletionCount; - } + return total; +} + +UINT64 Thread::GetTotalThreadPoolCompletionCount() +{ + CONTRACTL + { + NOTHROW; + MODE_ANY; } - else + CONTRACTL_END; + + // enumerate all threads, summing their local counts. + ThreadStoreLockHolder tsl; + + UINT64 total = GetWorkerThreadPoolCompletionCountOverflow() + GetIOThreadPoolCompletionCountOverflow(); + + Thread *pThread = NULL; + while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL) { - total = s_threadPoolCompletionCountOverflow.Load(); + total += pThread->m_workerThreadPoolCompletionCount; + total += pThread->m_ioThreadPoolCompletionCount; } return total; } - INT32 Thread::ResetManagedThreadObject(INT32 nPriority) { CONTRACTL { |