diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Blocking.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Blocking.cs index bf2b0d1d1cb3c..73fe2afe9a4d0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Blocking.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.Blocking.cs @@ -180,7 +180,7 @@ private uint PerformBlockingAdjustment(bool previousDelayElapsed, out bool addWo do { - if (newNumThreadsGoal <= counts.NumExistingThreads) + if (newNumThreadsGoal <= counts.NumExistingThreads || BlockingConfig.IgnoreMemoryUsage) { break; } @@ -260,6 +260,8 @@ private static class BlockingConfig { public static readonly bool IsCooperativeBlockingEnabled = AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.Blocking.CooperativeBlocking", true); + public static readonly bool IgnoreMemoryUsage = + AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.Blocking.IgnoreMemoryUsage", false); public static readonly short ThreadsToAddWithoutDelay; public static readonly short ThreadsPerDelayStep; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs index b28286d8ebe0e..2843f99347ca5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs @@ -36,7 +36,7 @@ private static void GateThreadStart() LowLevelLock threadAdjustmentLock = threadPoolInstance._threadAdjustmentLock; DelayHelper delayHelper = default; - if (BlockingConfig.IsCooperativeBlockingEnabled) + if (BlockingConfig.IsCooperativeBlockingEnabled && !BlockingConfig.IgnoreMemoryUsage) { // Initialize memory usage and limits, and register to update them on gen 2 GCs threadPoolInstance.OnGen2GCCallback(); diff --git a/src/libraries/System.Threading.ThreadPool/tests/ThreadPoolTests.cs b/src/libraries/System.Threading.ThreadPool/tests/ThreadPoolTests.cs index 2c380f9d401b7..71cfdc57a8709 100644 --- a/src/libraries/System.Threading.ThreadPool/tests/ThreadPoolTests.cs +++ b/src/libraries/System.Threading.ThreadPool/tests/ThreadPoolTests.cs @@ -906,7 +906,6 @@ public static void ThreadPoolThreadCreationDoesNotTransferExecutionContext() } [ConditionalFact(nameof(IsThreadingAndRemoteExecutorSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/66852", TestPlatforms.OSX)] public static void CooperativeBlockingCanCreateThreadsFaster() { // Run in a separate process to test in a clean thread pool environment such that work items queued by the test @@ -924,6 +923,7 @@ public static void CooperativeBlockingCanCreateThreadsFaster() int workItemCount = processorCount + 120; SetBlockingConfigValue("ThreadsToAddWithoutDelay_ProcCountFactor", 1); SetBlockingConfigValue("MaxDelayMs", 1); + SetBlockingConfigValue("IgnoreMemoryUsage", true); var allWorkItemsUnblocked = new AutoResetEvent(false); @@ -954,17 +954,19 @@ public static void CooperativeBlockingCanCreateThreadsFaster() Assert.True(allWorkItemsUnblocked.WaitOne(30_000)); } - void SetBlockingConfigValue(string name, int value) => + void SetBlockingConfigValue(string name, object value) => AppContextSetData("System.Threading.ThreadPool.Blocking." + name, value); void AppContextSetData(string name, object value) { - typeof(AppContext).InvokeMember( - "SetData", - BindingFlags.ExactBinding | BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, - null, - null, - new object[] { name, value }); + if (value is bool boolValue) + { + AppContext.SetSwitch(name, boolValue); + } + else + { + AppContext.SetData(name, value); + } } }).Dispose(); }