summaryrefslogtreecommitdiff
path: root/src/vm/win32threadpool.cpp
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@microsoft.com>2017-04-10 19:48:54 -0700
committerGitHub <noreply@github.com>2017-04-10 19:48:54 -0700
commitcdde90945fe82715a4f58f090925a0ca78db11e6 (patch)
tree152813e152a21d86e8a26756c6c1e4d897b3ec01 /src/vm/win32threadpool.cpp
parent7e5e9c0a3713f2f1bd69e665b45f74ee7ac8e8b3 (diff)
downloadcoreclr-cdde90945fe82715a4f58f090925a0ca78db11e6.tar.gz
coreclr-cdde90945fe82715a4f58f090925a0ca78db11e6.tar.bz2
coreclr-cdde90945fe82715a4f58f090925a0ca78db11e6.zip
Fix some static methods on ThreadPool to wait for initialization (#10869)
Fix for part of #10521
Diffstat (limited to 'src/vm/win32threadpool.cpp')
-rw-r--r--src/vm/win32threadpool.cpp200
1 files changed, 59 insertions, 141 deletions
diff --git a/src/vm/win32threadpool.cpp b/src/vm/win32threadpool.cpp
index da6c1b2c84..bc84762b06 100644
--- a/src/vm/win32threadpool.cpp
+++ b/src/vm/win32threadpool.cpp
@@ -553,7 +553,7 @@ BOOL ThreadpoolMgr::SetMaxThreadsHelper(DWORD MaxWorkerThreads,
/************************************************************************/
BOOL ThreadpoolMgr::SetMaxThreads(DWORD MaxWorkerThreads,
- DWORD MaxIOCompletionThreads)
+ DWORD MaxIOCompletionThreads)
{
CONTRACTL
{
@@ -563,31 +563,13 @@ BOOL ThreadpoolMgr::SetMaxThreads(DWORD MaxWorkerThreads,
}
CONTRACTL_END;
+ EnsureInitialized();
- if (IsInitialized())
- {
- return SetMaxThreadsHelper(MaxWorkerThreads, MaxIOCompletionThreads);
- }
-
- if (InterlockedCompareExchange(&Initialization, 1, 0) == 0)
- {
- Initialize();
-
- BOOL helper_result = FALSE;
- helper_result = SetMaxThreadsHelper(MaxWorkerThreads, MaxIOCompletionThreads);
-
- Initialization = -1;
- return helper_result;
- }
- else // someone else is initializing. Too late, return false
- {
- return FALSE;
- }
-
+ return SetMaxThreadsHelper(MaxWorkerThreads, MaxIOCompletionThreads);
}
BOOL ThreadpoolMgr::GetMaxThreads(DWORD* MaxWorkerThreads,
- DWORD* MaxIOCompletionThreads)
+ DWORD* MaxIOCompletionThreads)
{
LIMITED_METHOD_CONTRACT;
@@ -598,44 +580,15 @@ BOOL ThreadpoolMgr::GetMaxThreads(DWORD* MaxWorkerThreads,
return FALSE;
}
- if (IsInitialized())
- {
- *MaxWorkerThreads = (DWORD)MaxLimitTotalWorkerThreads;
- *MaxIOCompletionThreads = MaxLimitTotalCPThreads;
- }
- else
- {
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), *MaxWorkerThreads = 1024);
-
- //ThreadPool_CPUGroup
- CPUGroupInfo::EnsureInitialized();
- if (CPUGroupInfo::CanEnableGCCPUGroups() && CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
- NumberOfProcessors = CPUGroupInfo::GetNumActiveProcessors();
- else
- NumberOfProcessors = GetCurrentProcessCpuCount();
- DWORD min = GetForceMinWorkerThreadsValue();
- if (min == 0)
- min = NumberOfProcessors;
-
- DWORD forceMax = GetForceMaxWorkerThreadsValue();
- if (forceMax > 0)
- {
- *MaxWorkerThreads = forceMax;
- }
- else
- {
- *MaxWorkerThreads = GetDefaultMaxLimitWorkerThreads(min);
- }
-
- END_SO_INTOLERANT_CODE;
+ EnsureInitialized();
- *MaxIOCompletionThreads = MaxLimitTotalCPThreads;
- }
+ *MaxWorkerThreads = (DWORD)MaxLimitTotalWorkerThreads;
+ *MaxIOCompletionThreads = MaxLimitTotalCPThreads;
return TRUE;
}
BOOL ThreadpoolMgr::SetMinThreads(DWORD MinWorkerThreads,
- DWORD MinIOCompletionThreads)
+ DWORD MinIOCompletionThreads)
{
CONTRACTL
{
@@ -645,75 +598,61 @@ BOOL ThreadpoolMgr::SetMinThreads(DWORD MinWorkerThreads,
}
CONTRACTL_END;
+ EnsureInitialized();
- if (!IsInitialized())
- {
- if (InterlockedCompareExchange(&Initialization, 1, 0) == 0)
- {
- Initialize();
- Initialization = -1;
- }
- }
+ // doesn't need to be WorkerCS, but using it to avoid race condition between setting min and max, and didn't want to create a new CS.
+ CrstHolder csh(&WorkerCriticalSection);
- if (IsInitialized())
- {
- // doesn't need to be WorkerCS, but using it to avoid race condition between setting min and max, and didn't want to create a new CS.
- CrstHolder csh(&WorkerCriticalSection);
+ BOOL init_result = FALSE;
- BOOL init_result = false;
+ if (MinWorkerThreads >= 0 && MinIOCompletionThreads >= 0 &&
+ MinWorkerThreads <= (DWORD) MaxLimitTotalWorkerThreads &&
+ MinIOCompletionThreads <= (DWORD) MaxLimitTotalCPThreads)
+ {
+ BEGIN_SO_INTOLERANT_CODE(GetThread());
- if (MinWorkerThreads >= 0 && MinIOCompletionThreads >= 0 &&
- MinWorkerThreads <= (DWORD) MaxLimitTotalWorkerThreads &&
- MinIOCompletionThreads <= (DWORD) MaxLimitTotalCPThreads)
+ if (GetForceMinWorkerThreadsValue() == 0)
{
- BEGIN_SO_INTOLERANT_CODE(GetThread());
+ MinLimitTotalWorkerThreads = min(MinWorkerThreads, (DWORD)ThreadCounter::MaxPossibleCount);
- if (GetForceMinWorkerThreadsValue() == 0)
+ ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
+ while (counts.MaxWorking < MinLimitTotalWorkerThreads)
{
- MinLimitTotalWorkerThreads = min(MinWorkerThreads, (DWORD)ThreadCounter::MaxPossibleCount);
+ ThreadCounter::Counts newCounts = counts;
+ newCounts.MaxWorking = MinLimitTotalWorkerThreads;
- ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
- while (counts.MaxWorking < MinLimitTotalWorkerThreads)
+ ThreadCounter::Counts oldCounts = WorkerCounter.CompareExchangeCounts(newCounts, counts);
+ if (oldCounts == counts)
{
- ThreadCounter::Counts newCounts = counts;
- newCounts.MaxWorking = MinLimitTotalWorkerThreads;
-
- ThreadCounter::Counts oldCounts = WorkerCounter.CompareExchangeCounts(newCounts, counts);
- if (oldCounts == counts)
- {
- counts = newCounts;
+ counts = newCounts;
- // if we increased the limit, and there are pending workitems, we need
- // to dispatch a thread to process the work.
- if (newCounts.MaxWorking > oldCounts.MaxWorking &&
- PerAppDomainTPCountList::AreRequestsPendingInAnyAppDomains())
- {
- MaybeAddWorkingWorker();
- }
- }
- else
+ // if we increased the limit, and there are pending workitems, we need
+ // to dispatch a thread to process the work.
+ if (newCounts.MaxWorking > oldCounts.MaxWorking &&
+ PerAppDomainTPCountList::AreRequestsPendingInAnyAppDomains())
{
- counts = oldCounts;
+ MaybeAddWorkingWorker();
}
}
+ else
+ {
+ counts = oldCounts;
+ }
}
+ }
- END_SO_INTOLERANT_CODE;
-
- MinLimitTotalCPThreads = min(MinIOCompletionThreads, (DWORD)ThreadCounter::MaxPossibleCount);
+ END_SO_INTOLERANT_CODE;
- init_result = TRUE;
- }
+ MinLimitTotalCPThreads = min(MinIOCompletionThreads, (DWORD)ThreadCounter::MaxPossibleCount);
- return init_result;
+ init_result = TRUE;
}
- // someone else is initializing. Too late, return false
- return FALSE;
+ return init_result;
}
BOOL ThreadpoolMgr::GetMinThreads(DWORD* MinWorkerThreads,
- DWORD* MinIOCompletionThreads)
+ DWORD* MinIOCompletionThreads)
{
LIMITED_METHOD_CONTRACT;
@@ -724,25 +663,10 @@ BOOL ThreadpoolMgr::GetMinThreads(DWORD* MinWorkerThreads,
return FALSE;
}
- if (IsInitialized())
- {
- *MinWorkerThreads = (DWORD)MinLimitTotalWorkerThreads;
- *MinIOCompletionThreads = MinLimitTotalCPThreads;
- }
- else
- {
- CPUGroupInfo::EnsureInitialized();
- if (CPUGroupInfo::CanEnableGCCPUGroups() && CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
- NumberOfProcessors = CPUGroupInfo::GetNumActiveProcessors();
- else
- NumberOfProcessors = GetCurrentProcessCpuCount();
- DWORD forceMin;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), forceMin=0);
- forceMin = GetForceMinWorkerThreadsValue();
- END_SO_INTOLERANT_CODE;
- *MinWorkerThreads = forceMin > 0 ? forceMin : NumberOfProcessors;
- *MinIOCompletionThreads = NumberOfProcessors;
- }
+ EnsureInitialized();
+
+ *MinWorkerThreads = (DWORD)MinLimitTotalWorkerThreads;
+ *MinIOCompletionThreads = MinLimitTotalCPThreads;
return TRUE;
}
@@ -751,32 +675,26 @@ BOOL ThreadpoolMgr::GetAvailableThreads(DWORD* AvailableWorkerThreads,
{
LIMITED_METHOD_CONTRACT;
- if (IsInitialized())
+ if (!AvailableWorkerThreads || !AvailableIOCompletionThreads)
{
+ SetLastHRError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
- if (!AvailableWorkerThreads || !AvailableIOCompletionThreads)
- {
- SetLastHRError(ERROR_INVALID_DATA);
- return FALSE;
- }
+ EnsureInitialized();
- ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
+ ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
- if (MaxLimitTotalWorkerThreads < counts.NumActive)
- *AvailableWorkerThreads = 0;
- else
- *AvailableWorkerThreads = MaxLimitTotalWorkerThreads - counts.NumWorking;
+ if (MaxLimitTotalWorkerThreads < counts.NumActive)
+ *AvailableWorkerThreads = 0;
+ else
+ *AvailableWorkerThreads = MaxLimitTotalWorkerThreads - counts.NumWorking;
- counts = CPThreadCounter.GetCleanCounts();
- if (MaxLimitTotalCPThreads < counts.NumActive)
- *AvailableIOCompletionThreads = counts.NumActive - counts.NumWorking;
- else
- *AvailableIOCompletionThreads = MaxLimitTotalCPThreads - counts.NumWorking;
- }
+ counts = CPThreadCounter.GetCleanCounts();
+ if (MaxLimitTotalCPThreads < counts.NumActive)
+ *AvailableIOCompletionThreads = counts.NumActive - counts.NumWorking;
else
- {
- GetMaxThreads(AvailableWorkerThreads,AvailableIOCompletionThreads);
- }
+ *AvailableIOCompletionThreads = MaxLimitTotalCPThreads - counts.NumWorking;
return TRUE;
}