Simplify scheduler configuration and pending composite caching

This commit is contained in:
Marek Lemańczyk committed 2025-10-20 01:07:02 +02:00
1 parent e9cff7bfcd
commit a7ed762428
3 files changed
+23 -48

No files matched your search

+17 -42
View File
@@ -1,31 +1,18 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace PerfectNumbers.Core;
public sealed class UnboundedTaskScheduler : TaskScheduler
{
private static readonly object InstanceLock = new();
private static UnboundedTaskScheduler? _instance;
private static int _configuredThreadCount = Environment.ProcessorCount;
public static UnboundedTaskScheduler Instance
{
get
{
lock (InstanceLock)
{
_instance ??= new UnboundedTaskScheduler(GetNormalizedThreadCount(_configuredThreadCount));
return _instance;
}
}
}
public static UnboundedTaskScheduler Instance => _instance ??= new UnboundedTaskScheduler(_configuredThreadCount);
public static int ConfiguredThreadCount => GetNormalizedThreadCount(Volatile.Read(ref _configuredThreadCount));
public static int ConfiguredThreadCount => _configuredThreadCount;
private readonly object _poolLock = new();
private TaskThreadPool _threadPool;
private UnboundedTaskScheduler(int threadCount)
@@ -35,20 +22,15 @@ public sealed class UnboundedTaskScheduler : TaskScheduler
public static void ConfigureThreadCount(int threadCount)
{
int normalizedThreadCount = GetNormalizedThreadCount(threadCount);
_configuredThreadCount = threadCount;
PrimeOrderCalculator.PrimeOrderSearchConfig.ConfigureHeuristicDefault(threadCount);
lock (InstanceLock)
{
Volatile.Write(ref _configuredThreadCount, normalizedThreadCount);
PrimeOrderCalculator.PrimeOrderSearchConfig.ConfigureHeuristicDefault(normalizedThreadCount);
if (_instance is null)
{
return;
}
_instance.UpdateThreadPool(normalizedThreadCount);
}
// On EvenPerfectBitScanner's execution path the scheduler instance is created after configuration,
// so updating an existing pool would never run. Leave the update path disabled for now.
// if (_instance is not null)
// {
// _instance.UpdateThreadPool(threadCount);
// }
}
public override int MaximumConcurrencyLevel => int.MaxValue;
@@ -60,18 +42,15 @@ public sealed class UnboundedTaskScheduler : TaskScheduler
private void UpdateThreadPool(int threadCount)
{
lock (_poolLock)
if (_threadPool.ThreadCount == threadCount)
{
if (_threadPool.ThreadCount == threadCount)
{
return;
}
TaskThreadPool newPool = new(threadCount, ExecuteTask);
TaskThreadPool oldPool = _threadPool;
_threadPool = newPool;
oldPool.Dispose();
return;
}
TaskThreadPool newPool = new(threadCount, ExecuteTask);
TaskThreadPool oldPool = _threadPool;
_threadPool = newPool;
oldPool.Dispose();
}
private void ExecuteTask(Task task)
@@ -89,8 +68,4 @@ public sealed class UnboundedTaskScheduler : TaskScheduler
return _threadPool.GetScheduledTasks();
}
private static int GetNormalizedThreadCount(int threadCount)
{
return threadCount < 1 ? 1 : threadCount;
}
}