public bool SetMinThreads(int workerThreads, int ioCompletionThreads) { if (workerThreads < 0 || ioCompletionThreads < 0) { return(false); } bool addWorker = false; bool wakeGateThread = false; _threadAdjustmentLock.Acquire(); try { if (workerThreads > _maxThreads || !ThreadPool.CanSetMinIOCompletionThreads(ioCompletionThreads)) { return(false); } ThreadPool.SetMinIOCompletionThreads(ioCompletionThreads); if (ForcedMinWorkerThreads != 0) { return(true); } short newMinThreads = (short)Math.Max(1, Math.Min(workerThreads, MaxPossibleThreadCount)); _minThreads = newMinThreads; if (_numBlockedThreads > 0) { // Blocking adjustment will adjust the goal according to its heuristics if (_pendingBlockingAdjustment != PendingBlockingAdjustment.Immediately) { _pendingBlockingAdjustment = PendingBlockingAdjustment.Immediately; wakeGateThread = true; } } else if (_separated.counts.NumThreadsGoal < newMinThreads) { _separated.counts.InterlockedSetNumThreadsGoal(newMinThreads); if (_separated.numRequestedWorkers > 0) { addWorker = true; } } } finally { _threadAdjustmentLock.Release(); } if (addWorker) { WorkerThread.MaybeAddWorkingWorker(this); } else if (wakeGateThread) { GateThread.Wake(this); } return(true); }
public bool SetMinThreads(int workerThreads, int ioCompletionThreads) { if (workerThreads < 0 || ioCompletionThreads < 0) { return(false); } _maxMinThreadLock.Acquire(); try { if (workerThreads > _maxThreads || !ThreadPool.CanSetMinIOCompletionThreads(ioCompletionThreads)) { return(false); } ThreadPool.SetMinIOCompletionThreads(ioCompletionThreads); if (s_forcedMinWorkerThreads != 0) { return(true); } short newMinThreads = (short)Math.Max(1, Math.Min(workerThreads, MaxPossibleThreadCount)); _minThreads = newMinThreads; ThreadCounts counts = _separated.counts.VolatileRead(); while (counts.NumThreadsGoal < newMinThreads) { ThreadCounts newCounts = counts; newCounts.NumThreadsGoal = newMinThreads; ThreadCounts oldCounts = _separated.counts.InterlockedCompareExchange(newCounts, counts); if (oldCounts == counts) { if (_separated.numRequestedWorkers > 0) { WorkerThread.MaybeAddWorkingWorker(this); } break; } counts = oldCounts; } return(true); } finally { _maxMinThreadLock.Release(); } }
public bool SetMinThreads(int workerThreads, int ioCompletionThreads) { if (workerThreads < 0 || ioCompletionThreads < 0) { return(false); } bool addWorker = false; bool wakeGateThread = false; _threadAdjustmentLock.Acquire(); try { if (workerThreads > _maxThreads) { return(false); } if (ThreadPool.UsePortableThreadPoolForIO ? ioCompletionThreads > _legacy_maxIOCompletionThreads : !ThreadPool.CanSetMinIOCompletionThreads(ioCompletionThreads)) { return(false); } if (HasForcedMinThreads && workerThreads != ForcedMinWorkerThreads) { return(false); } if (ThreadPool.UsePortableThreadPoolForIO) { _legacy_minIOCompletionThreads = (short)Math.Max(1, ioCompletionThreads); } else { ThreadPool.SetMinIOCompletionThreads(ioCompletionThreads); } short newMinThreads = (short)Math.Max(1, workerThreads); if (newMinThreads == _minThreads) { return(true); } _minThreads = newMinThreads; if (_numBlockedThreads > 0) { // Blocking adjustment will adjust the goal according to its heuristics if (_pendingBlockingAdjustment != PendingBlockingAdjustment.Immediately) { _pendingBlockingAdjustment = PendingBlockingAdjustment.Immediately; wakeGateThread = true; } } else if (_separated.counts.NumThreadsGoal < newMinThreads) { _separated.counts.InterlockedSetNumThreadsGoal(newMinThreads); if (_separated.numRequestedWorkers > 0) { addWorker = true; } } if (NativeRuntimeEventSource.Log.IsEnabled()) { NativeRuntimeEventSource.Log.ThreadPoolMinMaxThreads( (ushort)_minThreads, (ushort)_maxThreads, (ushort)_legacy_minIOCompletionThreads, (ushort)_legacy_maxIOCompletionThreads); } } finally { _threadAdjustmentLock.Release(); } if (addWorker) { WorkerThread.MaybeAddWorkingWorker(this); } else if (wakeGateThread) { GateThread.Wake(this); } return(true); }