summaryrefslogtreecommitdiff
path: root/src/vm/threads.cpp
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@users.noreply.github.com>2019-04-19 19:22:53 -0700
committerGitHub <noreply@github.com>2019-04-19 19:22:53 -0700
commit0410c3e4fe54590eea34aead28f550539d814b98 (patch)
tree0a7d9b8ee2df4e672024ed410ee04e267f8e5bbe /src/vm/threads.cpp
parent924d4fcc6961a76881a42a5a4a80479352708ace (diff)
downloadcoreclr-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.cpp82
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 {