diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs index 070b4e2c99d940..a2184f544cf1ad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs @@ -66,7 +66,7 @@ private static int DetermineThreadPoolThreadTimeoutMs() } [ThreadStatic] - private static object? t_completionCountObject; + private static ThreadInt64PersistentCounter.ThreadLocalNode? t_completionCountNode; #pragma warning disable IDE1006 // Naming Styles // The singleton must be initialized after the static variables above, as the constructor may be dependent on them. @@ -317,22 +317,22 @@ public void GetAvailableThreads(out int workerThreads, out int ioCompletionThrea public int ThreadCount => _separated.counts.VolatileRead().NumExistingThreads; public long CompletedWorkItemCount => _completionCounter.Count; - public object GetOrCreateThreadLocalCompletionCountObject() => - t_completionCountObject ?? CreateThreadLocalCompletionCountObject(); + public ThreadInt64PersistentCounter.ThreadLocalNode GetOrCreateThreadLocalCompletionCountNode() => + t_completionCountNode ?? CreateThreadLocalCompletionCountNode(); [MethodImpl(MethodImplOptions.NoInlining)] - private object CreateThreadLocalCompletionCountObject() + private ThreadInt64PersistentCounter.ThreadLocalNode CreateThreadLocalCompletionCountNode() { - Debug.Assert(t_completionCountObject == null); + Debug.Assert(t_completionCountNode == null); - object threadLocalCompletionCountObject = _completionCounter.CreateThreadLocalCountObject(); - t_completionCountObject = threadLocalCompletionCountObject; - return threadLocalCompletionCountObject; + ThreadInt64PersistentCounter.ThreadLocalNode threadLocalCompletionCountNode = _completionCounter.CreateThreadLocalCountObject(); + t_completionCountNode = threadLocalCompletionCountNode; + return threadLocalCompletionCountNode; } - private void NotifyWorkItemProgress(object threadLocalCompletionCountObject, int currentTimeMs) + private void NotifyWorkItemProgress(ThreadInt64PersistentCounter.ThreadLocalNode threadLocalCompletionCountNode, int currentTimeMs) { - ThreadInt64PersistentCounter.Increment(threadLocalCompletionCountObject); + threadLocalCompletionCountNode.Increment(); _separated.lastDequeueTime = currentTimeMs; if (ShouldAdjustMaxWorkersActive(currentTimeMs)) @@ -342,13 +342,13 @@ private void NotifyWorkItemProgress(object threadLocalCompletionCountObject, int } internal void NotifyWorkItemProgress() => - NotifyWorkItemProgress(GetOrCreateThreadLocalCompletionCountObject(), Environment.TickCount); + NotifyWorkItemProgress(GetOrCreateThreadLocalCompletionCountNode(), Environment.TickCount); - internal bool NotifyWorkItemComplete(object? threadLocalCompletionCountObject, int currentTimeMs) + internal bool NotifyWorkItemComplete(ThreadInt64PersistentCounter.ThreadLocalNode? threadLocalCompletionCountNode, int currentTimeMs) { - Debug.Assert(threadLocalCompletionCountObject != null); + Debug.Assert(threadLocalCompletionCountNode != null); - NotifyWorkItemProgress(threadLocalCompletionCountObject, currentTimeMs); + NotifyWorkItemProgress(threadLocalCompletionCountNode, currentTimeMs); return !WorkerThread.ShouldStopProcessingWorkNow(this); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs index 29cf2dce305657..a4a6e749cdd747 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs @@ -25,28 +25,7 @@ public ThreadInt64PersistentCounter() _nodes = new ThreadLocalNode(this); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Increment(object threadLocalCountObject) - { - Debug.Assert(threadLocalCountObject is ThreadLocalNode); - Unsafe.As(threadLocalCountObject).Increment(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Decrement(object threadLocalCountObject) - { - Debug.Assert(threadLocalCountObject is ThreadLocalNode); - Unsafe.As(threadLocalCountObject).Decrement(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Add(object threadLocalCountObject, uint count) - { - Debug.Assert(threadLocalCountObject is ThreadLocalNode); - Unsafe.As(threadLocalCountObject).Add(count); - } - - public object CreateThreadLocalCountObject() + public ThreadLocalNode CreateThreadLocalCountObject() { var node = new ThreadLocalNode(this); @@ -105,7 +84,7 @@ public long Count } } - private sealed class ThreadLocalNode + internal sealed class ThreadLocalNode { private uint _count; private readonly ThreadInt64PersistentCounter _counter; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.cs index 75e5d38767aa2b..8b07e1b1aebb9a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.cs @@ -99,10 +99,10 @@ internal static void NotifyThreadUnblocked() { } - internal static object? GetOrCreateThreadLocalCompletionCountObject() => null; + internal static ThreadInt64PersistentCounter.ThreadLocalNode? GetOrCreateThreadLocalCompletionCountNode() => null; #pragma warning disable IDE0060 - internal static bool NotifyWorkItemComplete(object? threadLocalCompletionCountObject, int currentTimeMs) + internal static bool NotifyWorkItemComplete(ThreadInt64PersistentCounter.ThreadLocalNode? threadLocalCompletionCountNode, int currentTimeMs) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs index 3766266fa671e7..b100409793ba20 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs @@ -22,8 +22,8 @@ public static partial class ThreadPool internal static bool YieldFromDispatchLoop => false; #endif - internal static object GetOrCreateThreadLocalCompletionCountObject() => - PortableThreadPool.ThreadPoolInstance.GetOrCreateThreadLocalCompletionCountObject(); + internal static ThreadInt64PersistentCounter.ThreadLocalNode GetOrCreateThreadLocalCompletionCountNode() => + PortableThreadPool.ThreadPoolInstance.GetOrCreateThreadLocalCompletionCountNode(); public static bool SetMaxThreads(int workerThreads, int completionPortThreads) => PortableThreadPool.ThreadPoolInstance.SetMaxThreads(workerThreads, completionPortThreads); @@ -61,8 +61,8 @@ internal static void NotifyThreadUnblocked() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool NotifyWorkItemComplete(object threadLocalCompletionCountObject, int currentTimeMs) => - PortableThreadPool.ThreadPoolInstance.NotifyWorkItemComplete(threadLocalCompletionCountObject, currentTimeMs); + internal static bool NotifyWorkItemComplete(ThreadInt64PersistentCounter.ThreadLocalNode threadLocalCompletionCountNode, int currentTimeMs) => + PortableThreadPool.ThreadPoolInstance.NotifyWorkItemComplete(threadLocalCompletionCountNode, currentTimeMs); /// /// This method is called to request a new thread pool worker to handle pending work. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.cs index 0d082fd863cb95..fa499f0fd857fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Wasi.cs @@ -89,9 +89,9 @@ internal static void NotifyThreadUnblocked() { } - internal static object? GetOrCreateThreadLocalCompletionCountObject() => null; + internal static ThreadInt64PersistentCounter.ThreadLocalNode? GetOrCreateThreadLocalCompletionCountNode() => null; - internal static bool NotifyWorkItemComplete(object? _1, int _2) => true; + internal static bool NotifyWorkItemComplete(ThreadInt64PersistentCounter.ThreadLocalNode? _1, int _2) => true; private static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle? waitObject, diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs index bd27b57f398238..0ad70d35a92c32 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs @@ -67,10 +67,10 @@ internal static void InitializeForThreadPoolThread() [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void IncrementCompletedWorkItemCount() => WindowsThreadPool.IncrementCompletedWorkItemCount(); - internal static object GetOrCreateThreadLocalCompletionCountObject() => + internal static ThreadInt64PersistentCounter.ThreadLocalNode GetOrCreateThreadLocalCompletionCountNode() => ThreadPool.UseWindowsThreadPool ? - WindowsThreadPool.GetOrCreateThreadLocalCompletionCountObject() : - PortableThreadPool.ThreadPoolInstance.GetOrCreateThreadLocalCompletionCountObject(); + WindowsThreadPool.GetOrCreateThreadLocalCompletionCountNode() : + PortableThreadPool.ThreadPoolInstance.GetOrCreateThreadLocalCompletionCountNode(); public static bool SetMaxThreads(int workerThreads, int completionPortThreads) => ThreadPool.UseWindowsThreadPool ? @@ -132,10 +132,10 @@ internal static void NotifyWorkItemProgress() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool NotifyWorkItemComplete(object threadLocalCompletionCountObject, int currentTimeMs) => + internal static bool NotifyWorkItemComplete(ThreadInt64PersistentCounter.ThreadLocalNode threadLocalCompletionCountNode, int currentTimeMs) => ThreadPool.UseWindowsThreadPool ? - WindowsThreadPool.NotifyWorkItemComplete(threadLocalCompletionCountObject, currentTimeMs) : - PortableThreadPool.ThreadPoolInstance.NotifyWorkItemComplete(threadLocalCompletionCountObject, currentTimeMs); + WindowsThreadPool.NotifyWorkItemComplete(threadLocalCompletionCountNode, currentTimeMs) : + PortableThreadPool.ThreadPoolInstance.NotifyWorkItemComplete(threadLocalCompletionCountNode, currentTimeMs); internal static bool NotifyThreadBlocked() => ThreadPool.UseWindowsThreadPool ? diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs index 99455d29b80c00..247d5663c17f9a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs @@ -1084,7 +1084,7 @@ internal static bool Dispatch() // Has the desire for logging changed since the last time we entered? workQueue.RefreshLoggingEnabled(); - object? threadLocalCompletionCountObject = tl.threadLocalCompletionCountObject; + ThreadInt64PersistentCounter.ThreadLocalNode? threadLocalCompletionCountNode = tl.threadLocalCompletionCountNode; Thread currentThread = tl.currentThread; // Start on clean ExecutionContext and SynchronizationContext @@ -1170,7 +1170,7 @@ internal static bool Dispatch() // us to return the thread to the pool or not. // int currentTickCount = Environment.TickCount; - if (!ThreadPool.NotifyWorkItemComplete(threadLocalCompletionCountObject!, currentTickCount)) + if (!ThreadPool.NotifyWorkItemComplete(threadLocalCompletionCountNode!, currentTickCount)) { // This thread is being parked and may remain inactive for a while. Transfer any thread-local work items // to ensure that they would not be heavily delayed. Tell the caller that this thread was requested to stop @@ -1276,7 +1276,7 @@ internal sealed class ThreadPoolWorkQueueThreadLocals public readonly ThreadPoolWorkQueue workQueue; public readonly ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue; public readonly Thread currentThread; - public readonly object? threadLocalCompletionCountObject; + public readonly ThreadInt64PersistentCounter.ThreadLocalNode? threadLocalCompletionCountNode; public readonly Random.XoshiroImpl random = new Random.XoshiroImpl(); public ThreadPoolWorkQueueThreadLocals(ThreadPoolWorkQueue tpq) @@ -1286,7 +1286,7 @@ public ThreadPoolWorkQueueThreadLocals(ThreadPoolWorkQueue tpq) workStealingQueue = new ThreadPoolWorkQueue.WorkStealingQueue(); ThreadPoolWorkQueue.WorkStealingQueueList.Add(workStealingQueue); currentThread = Thread.CurrentThread; - threadLocalCompletionCountObject = ThreadPool.GetOrCreateThreadLocalCompletionCountObject(); + threadLocalCompletionCountNode = ThreadPool.GetOrCreateThreadLocalCompletionCountNode(); } public void TransferLocalWork() @@ -1411,8 +1411,7 @@ void IThreadPoolWorkItem.Execute() if (stageBeforeUpdate == QueueProcessingStage.Determining) { // Discount a work item here to avoid counting this queue processing work item - ThreadInt64PersistentCounter.Decrement( - ThreadPoolWorkQueueThreadLocals.threadLocals!.threadLocalCompletionCountObject!); + ThreadPoolWorkQueueThreadLocals.threadLocals!.threadLocalCompletionCountNode!.Decrement(); return; } } @@ -1455,7 +1454,7 @@ void IThreadPoolWorkItem.Execute() // Discount a work item here to avoid counting this queue processing work item if (completedCount > 1) { - ThreadInt64PersistentCounter.Add(tl.threadLocalCompletionCountObject!, completedCount - 1); + tl.threadLocalCompletionCountNode!.Add(completedCount - 1); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/WindowsThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/WindowsThreadPool.cs index afd969ca4faec2..25fa8cda1ad3e6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/WindowsThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/WindowsThreadPool.cs @@ -53,24 +53,24 @@ private struct WorkingThreadCounter private static readonly ThreadInt64PersistentCounter s_completedWorkItemCounter = new ThreadInt64PersistentCounter(); [ThreadStatic] - private static object? t_completionCountObject; + private static ThreadInt64PersistentCounter.ThreadLocalNode? t_completionCountNode; internal static void InitializeForThreadPoolThread() => t_threadCountHolder = new ThreadCountHolder(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void IncrementCompletedWorkItemCount() => ThreadInt64PersistentCounter.Increment(GetOrCreateThreadLocalCompletionCountObject()); + internal static void IncrementCompletedWorkItemCount() => GetOrCreateThreadLocalCompletionCountNode().Increment(); - internal static object GetOrCreateThreadLocalCompletionCountObject() => - t_completionCountObject ?? CreateThreadLocalCompletionCountObject(); + internal static ThreadInt64PersistentCounter.ThreadLocalNode GetOrCreateThreadLocalCompletionCountNode() => + t_completionCountNode ?? CreateThreadLocalCompletionCountNode(); [MethodImpl(MethodImplOptions.NoInlining)] - private static object CreateThreadLocalCompletionCountObject() + private static ThreadInt64PersistentCounter.ThreadLocalNode CreateThreadLocalCompletionCountNode() { - Debug.Assert(t_completionCountObject == null); + Debug.Assert(t_completionCountNode == null); - object threadLocalCompletionCountObject = s_completedWorkItemCounter.CreateThreadLocalCountObject(); - t_completionCountObject = threadLocalCompletionCountObject; - return threadLocalCompletionCountObject; + ThreadInt64PersistentCounter.ThreadLocalNode threadLocalCompletionCountNode = s_completedWorkItemCounter.CreateThreadLocalCountObject(); + t_completionCountNode = threadLocalCompletionCountNode; + return threadLocalCompletionCountNode; } #pragma warning disable IDE0060 // Remove unused parameter @@ -132,9 +132,9 @@ public static void GetAvailableThreads(out int workerThreads, out int completion internal static void NotifyWorkItemProgress() => IncrementCompletedWorkItemCount(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool NotifyWorkItemComplete(object threadLocalCompletionCountObject, int _ /*currentTimeMs*/) + internal static bool NotifyWorkItemComplete(ThreadInt64PersistentCounter.ThreadLocalNode threadLocalCompletionCountNode, int _ /*currentTimeMs*/) { - ThreadInt64PersistentCounter.Increment(threadLocalCompletionCountObject); + threadLocalCompletionCountNode.Increment(); return true; }