Exemplo n.º 1
0
        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 void NotifyThreadUnblocked()
        {
            Debug.Assert(BlockingConfig.IsCooperativeBlockingEnabled);
            Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);

            bool wakeGateThread = false;

            _threadAdjustmentLock.Acquire();
            try
            {
                Debug.Assert(_numBlockedThreads > 0);
                _numBlockedThreads--;

                if (_pendingBlockingAdjustment != PendingBlockingAdjustment.Immediately &&
                    _numThreadsAddedDueToBlocking > 0 &&
                    _separated.numThreadsGoal > TargetThreadsGoalForBlockingAdjustment)
                {
                    wakeGateThread             = true;
                    _pendingBlockingAdjustment = PendingBlockingAdjustment.Immediately;
                }
            }
            finally
            {
                _threadAdjustmentLock.Release();
            }

            if (wakeGateThread)
            {
                GateThread.Wake(this);
            }
        }
Exemplo n.º 3
0
 internal void RequestWorker()
 {
     // The order of operations here is important. MaybeAddWorkingWorker() and EnsureRunning() use speculative checks to
     // do their work and the memory barrier from the interlocked operation is necessary in this case for correctness.
     Interlocked.Increment(ref _separated.numRequestedWorkers);
     WorkerThread.MaybeAddWorkingWorker(this);
     GateThread.EnsureRunning(this);
 }
        public bool NotifyThreadBlocked()
        {
            if (!BlockingConfig.IsCooperativeBlockingEnabled || !Thread.CurrentThread.IsThreadPoolThread)
            {
                return(false);
            }

            bool wakeGateThread = false;

            _threadAdjustmentLock.Acquire();
            try
            {
                _numBlockedThreads++;
                Debug.Assert(_numBlockedThreads > 0);

                if (_pendingBlockingAdjustment != PendingBlockingAdjustment.WithDelayIfNecessary &&
                    _separated.numThreadsGoal < TargetThreadsGoalForBlockingAdjustment)
                {
                    if (_pendingBlockingAdjustment == PendingBlockingAdjustment.None)
                    {
                        wakeGateThread = true;
                    }
                    _pendingBlockingAdjustment = PendingBlockingAdjustment.WithDelayIfNecessary;
                }
            }
            finally
            {
                _threadAdjustmentLock.Release();
            }

            if (wakeGateThread)
            {
                GateThread.Wake(this);
            }
            return(true);
        }
Exemplo n.º 5
0
 internal void RequestWorker()
 {
     Interlocked.Increment(ref _numRequestedWorkers);
     WorkerThread.MaybeAddWorkingWorker();
     GateThread.EnsureRunning();
 }
Exemplo n.º 6
0
        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);
        }
 internal static void EnsureGateThreadRunning() => GateThread.EnsureRunning(ThreadPoolInstance);