Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move thread pool initialization to native side #36789

Merged
merged 3 commits into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,7 @@ public static partial class ThreadPool
// Time in ms for which ThreadPoolWorkQueue.Dispatch keeps executing work items before returning to the OS
private const uint DispatchQuantum = 30;

private static bool GetEnableWorkerTracking()
{
bool enableWorkerTracking = false;
InitializeVMTp(ref enableWorkerTracking);
return enableWorkerTracking;
}
internal static readonly bool EnableWorkerTracking = GetEnableWorkerTracking();

internal static bool KeepDispatching(int startTickCount)
{
Expand Down Expand Up @@ -340,8 +335,8 @@ internal static void NotifyWorkItemProgress()
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void NotifyWorkItemProgressNative();

[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void InitializeVMTp(ref bool enableWorkerTracking);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool GetEnableWorkerTracking();

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern IntPtr RegisterWaitForSingleObjectNative(
Expand Down
14 changes: 8 additions & 6 deletions src/coreclr/src/vm/comthreadpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ FCIMPLEND
FCIMPL0(VOID, ThreadPoolNative::NotifyRequestProgress)
{
FCALL_CONTRACT;
_ASSERTE(ThreadpoolMgr::IsInitialized()); // can't be here without requesting a thread first

ThreadpoolMgr::NotifyWorkItemCompleted();

Expand Down Expand Up @@ -247,6 +248,7 @@ FCIMPLEND
FCIMPL0(FC_BOOL_RET, ThreadPoolNative::NotifyRequestComplete)
{
FCALL_CONTRACT;
_ASSERTE(ThreadpoolMgr::IsInitialized()); // can't be here without requesting a thread first

ThreadpoolMgr::NotifyWorkItemCompleted();

Expand Down Expand Up @@ -305,15 +307,14 @@ FCIMPLEND

/*****************************************************************************************************/

void QCALLTYPE ThreadPoolNative::InitializeVMTp(CLR_BOOL* pEnableWorkerTracking)
FCIMPL0(FC_BOOL_RET, ThreadPoolNative::GetEnableWorkerTracking)
{
QCALL_CONTRACT;
FCALL_CONTRACT;

BEGIN_QCALL;
ThreadpoolMgr::EnsureInitialized();
*pEnableWorkerTracking = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ThreadPool_EnableWorkerTracking) ? TRUE : FALSE;
END_QCALL;
BOOL result = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ThreadPool_EnableWorkerTracking) ? TRUE : FALSE;
FC_RETURN_BOOL(result);
}
FCIMPLEND

/*****************************************************************************************************/

Expand Down Expand Up @@ -473,6 +474,7 @@ BOOL QCALLTYPE ThreadPoolNative::RequestWorkerThread()

BEGIN_QCALL;

ThreadpoolMgr::EnsureInitialized();
ThreadpoolMgr::SetAppDomainRequestsActive();

res = ThreadpoolMgr::QueueUserWorkItem(NULL,
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/comthreadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ThreadPoolNative
static FCDECL0(VOID, NotifyRequestProgress);
static FCDECL0(FC_BOOL_RET, NotifyRequestComplete);

static void QCALLTYPE InitializeVMTp(CLR_BOOL* pEnableWorkerTracking);
static FCDECL0(FC_BOOL_RET, GetEnableWorkerTracking);

static FCDECL1(void, ReportThreadStatus, CLR_BOOL isWorking);

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ FCFuncStart(gThreadPoolFuncs)
FCFuncElement("GetMaxThreadsNative", ThreadPoolNative::CorGetMaxThreads)
FCFuncElement("NotifyWorkItemComplete", ThreadPoolNative::NotifyRequestComplete)
FCFuncElement("NotifyWorkItemProgressNative", ThreadPoolNative::NotifyRequestProgress)
QCFuncElement("InitializeVMTp", ThreadPoolNative::InitializeVMTp)
FCFuncElement("GetEnableWorkerTracking", ThreadPoolNative::GetEnableWorkerTracking)
FCFuncElement("ReportThreadStatus", ThreadPoolNative::ReportThreadStatus)
QCFuncElement("RequestWorkerThread", ThreadPoolNative::RequestWorkerThread)
FCFuncEnd()
Expand Down
19 changes: 18 additions & 1 deletion src/coreclr/src/vm/win32threadpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void ThreadpoolMgr::EnsureInitialized()
{
CONTRACTL
{
THROWS; // Initialize can throw
THROWS; // EnsureInitializedSlow can throw
MODE_ANY;
GC_NOTRIGGER;
}
Expand All @@ -244,6 +244,19 @@ void ThreadpoolMgr::EnsureInitialized()
if (IsInitialized())
return;

EnsureInitializedSlow();
}

NOINLINE void ThreadpoolMgr::EnsureInitializedSlow()
{
CONTRACTL
{
THROWS; // Initialize can throw
MODE_ANY;
GC_NOTRIGGER;
}
CONTRACTL_END;

DWORD dwSwitchCount = 0;

retry:
Expand Down Expand Up @@ -758,7 +771,10 @@ void ThreadpoolMgr::ReportThreadStatus(bool isWorking)
MODE_ANY;
}
CONTRACTL_END;

_ASSERTE(IsInitialized()); // can't be here without requesting a thread first
_ASSERTE(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ThreadPool_EnableWorkerTracking));

while (true)
{
WorkingThreadCounts currentCounts, newCounts;
Expand Down Expand Up @@ -3069,6 +3085,7 @@ void ThreadpoolMgr::DeregisterWait(WaitInfo* pArgs)
void ThreadpoolMgr::WaitHandleCleanup(HANDLE hWaitObject)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(IsInitialized()); // cannot call cleanup before first registering

WaitInfo* waitInfo = (WaitInfo*) hWaitObject;
_ASSERTE(waitInfo->refCount > 0);
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/src/vm/win32threadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,12 @@ class ThreadpoolMgr
return entry;
}

public:
static void EnsureInitialized();
private:
static void EnsureInitializedSlow();

public:
static void InitPlatformVariables();

inline static BOOL IsInitialized()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ internal void WaitForRemoval()

public static partial class ThreadPool
{
internal const bool EnableWorkerTracking = false;

internal static void InitializeForThreadPoolThread() { }

public static bool SetMaxThreads(int workerThreads, int completionPortThreads)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,8 @@ internal static bool Dispatch()
//
// Execute the workitem outside of any finally blocks, so that it can be aborted if needed.
//
if (ThreadPool.s_enableWorkerTracking)
#pragma warning disable CS0162 // Unreachable code detected. EnableWorkerTracking may be constant false in some runtimes.
if (ThreadPool.EnableWorkerTracking)
{
bool reportedStatus = false;
try
Expand All @@ -630,6 +631,7 @@ internal static bool Dispatch()
ThreadPool.ReportThreadStatus(isWorking: false);
}
}
#pragma warning restore CS0162
else if (workItem is Task task)
{
// Check for Task first as it's currently faster to type check
Expand Down Expand Up @@ -935,7 +937,6 @@ internal static void PerformWaitOrTimerCallback(_ThreadPoolWaitOrTimerCallback h
public static partial class ThreadPool
{
internal static readonly ThreadPoolWorkQueue s_workQueue = new ThreadPoolWorkQueue();
internal static readonly bool s_enableWorkerTracking = GetEnableWorkerTracking();

/// <summary>Shim used to invoke <see cref="IAsyncStateMachineBox.MoveNext"/> of the supplied <see cref="IAsyncStateMachineBox"/>.</summary>
internal static readonly Action<object?> s_invokeAsyncStateMachineBox = state =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ namespace System.Threading
{
public static partial class ThreadPool
{
private static bool GetEnableWorkerTracking() => false;

internal static void ReportThreadStatus(bool isWorking)
{
}
Expand Down