Пример #1
0
        /// <summary>
        /// Signal <see cref="UserUnregisterWaitHandle"/> if it has not been signaled yet and is a valid handle.
        /// </summary>
        private void SignalUserWaitHandle()
        {
            _callbackLock.VerifyIsLocked();
            SafeWaitHandle handle      = UserUnregisterWaitHandle;
            IntPtr         handleValue = UserUnregisterWaitHandleValue;

            try
            {
                if (handleValue != IntPtr.Zero && handleValue != (IntPtr)(-1))
                {
                    Debug.Assert(handleValue == handle.DangerousGetHandle());
#if PLATFORM_WINDOWS
                    Interop.Kernel32.SetEvent(handle);
#else
                    WaitSubsystem.SetEvent(handleValue);
#endif
                }
            }
            finally
            {
                handle?.DangerousRelease();
                _callbacksComplete?.Set();
                _unregistered = true;
            }
        }
Пример #2
0
        //
        // This method must only be called if ShouldAdjustMaxWorkersActive has returned true, *and*
        // _hillClimbingThreadAdjustmentLock is held.
        //
        private void AdjustMaxWorkersActive()
        {
            _hillClimbingThreadAdjustmentLock.VerifyIsLocked();
            int  currentTicks        = Environment.TickCount;
            int  totalNumCompletions = (int)_completionCounter.Count;
            int  numCompletions      = totalNumCompletions - _separated.priorCompletionCount;
            long startTime           = _currentSampleStartTime;
            long endTime             = Stopwatch.GetTimestamp();
            long freq = Stopwatch.Frequency;

            double elapsedSeconds = (double)(endTime - startTime) / freq;

            if (elapsedSeconds * 1000 >= _threadAdjustmentIntervalMs / 2)
            {
                ThreadCounts currentCounts = ThreadCounts.VolatileReadCounts(ref _separated.counts);
                int          newMax;
                (newMax, _threadAdjustmentIntervalMs) = HillClimbing.ThreadPoolHillClimber.Update(currentCounts.numThreadsGoal, elapsedSeconds, numCompletions);

                while (newMax != currentCounts.numThreadsGoal)
                {
                    ThreadCounts newCounts = currentCounts;
                    newCounts.numThreadsGoal = (short)newMax;

                    ThreadCounts oldCounts = ThreadCounts.CompareExchangeCounts(ref _separated.counts, newCounts, currentCounts);
                    if (oldCounts == currentCounts)
                    {
                        //
                        // If we're increasing the max, inject a thread.  If that thread finds work, it will inject
                        // another thread, etc., until nobody finds work or we reach the new maximum.
                        //
                        // If we're reducing the max, whichever threads notice this first will sleep and timeout themselves.
                        //
                        if (newMax > oldCounts.numThreadsGoal)
                        {
                            WorkerThread.MaybeAddWorkingWorker();
                        }
                        break;
                    }
                    else
                    {
                        if (oldCounts.numThreadsGoal > currentCounts.numThreadsGoal && oldCounts.numThreadsGoal >= newMax)
                        {
                            // someone (probably the gate thread) increased the thread count more than
                            // we are about to do.  Don't interfere.
                            break;
                        }

                        currentCounts = oldCounts;
                    }
                }
                _separated.priorCompletionCount          = totalNumCompletions;
                _separated.nextCompletedWorkRequestsTime = currentTicks + _threadAdjustmentIntervalMs;
                Volatile.Write(ref _separated.priorCompletedWorkRequestsTime, currentTicks);
                _currentSampleStartTime = endTime;
            }
        }
Пример #3
0
        /// <summary>
        /// Signal <see cref="UserUnregisterWaitHandle"/> if it has not been signaled yet and is a valid handle.
        /// </summary>
        private void SignalUserWaitHandle()
        {
            _callbackLock.VerifyIsLocked();
            SafeWaitHandle handle      = UserUnregisterWaitHandle;
            IntPtr         handleValue = UserUnregisterWaitHandleValue;

            try
            {
                if (handleValue != IntPtr.Zero && handleValue != (IntPtr)(-1))
                {
                    EventWaitHandle.Set(handleValue);
                }
            }
            finally
            {
                handle?.DangerousRelease();
                _callbacksComplete?.Set();
                _unregistered = true;
            }
        }
        /// <summary>
        /// Signal <see cref="UserUnregisterWaitHandle"/> if it has not been signaled yet and is a valid handle.
        /// </summary>
        private void SignalUserWaitHandle()
        {
            s_callbackLock.VerifyIsLocked();
            SafeWaitHandle?handle      = UserUnregisterWaitHandle;
            IntPtr         handleValue = UserUnregisterWaitHandleValue;

            try
            {
                if (handleValue != IntPtr.Zero && handleValue != InvalidHandleValue)
                {
                    Debug.Assert(handleValue == handle !.DangerousGetHandle());
                    EventWaitHandle.Set(handle);
                }
            }
            finally
            {
                handle?.DangerousRelease();
                _callbacksComplete?.Set();
                _unregistered = true;
            }
        }