From 7685f5eb4542af504704c2a184f9c6cc604c73f2 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sat, 2 May 2020 23:38:01 +0100 Subject: [PATCH] Only ensure the ThreadPool is active when queuing tasks Rather than double requesting threads on both enqueue and run, only ensure there is 1 or more requests outstanding at enqueue, and let dispatch request up to ProcessorCount threads; rather than doing it in both places --- .../src/System/Threading/ThreadPool.cs | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs index fe1021272a282e..78dc21ba192be7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs @@ -424,9 +424,28 @@ private ThreadPoolWorkQueueThreadLocals CreateThreadLocals() return ThreadPoolWorkQueueThreadLocals.threadLocals = new ThreadPoolWorkQueueThreadLocals(this); } + internal void EnsureThreadPoolActive() + { + // Used for queuing. + + // If we have not yet requested a thread, then request a new thread so the ThreadPool is active. + int count = numOutstandingThreadRequests; + while (count < 1) + { + int prev = Interlocked.CompareExchange(ref numOutstandingThreadRequests, count + 1, count); + if (prev == count) + { + ThreadPool.RequestWorkerThread(); + break; + } + count = prev; + } + } + internal void EnsureThreadRequested() { - // + // Used when running work items with a non-empty queue. + // If we have not yet requested #procs threads, then request a new thread. // // CoreCLR: Note that there is a separate count in the VM which has already been incremented @@ -486,7 +505,7 @@ public void Enqueue(object callback, bool forceGlobal) workItems.Enqueue(callback); } - EnsureThreadRequested(); + EnsureThreadPoolActive(); } internal bool LocalFindAndPop(object callback)