12 [StructLayout(
LayoutKind.Explicit, Size = 384)]
69 int32Config2 =
Math.
Max(1, int32Config2);
116 uint num2 = ((num >= 500) ? 1u : (500 - num));
125 uint num5 =
Math.
Min(num2, num4);
219 threadAdjustmentLock.
Acquire();
232 if (threadCounts2 == threadCounts)
238 threadCounts = threadCounts2;
243 threadAdjustmentLock.
Release();
267 uint num2 = ((threadPoolInstance._cpuUtilization >= 80) ? ((uint)(threadPoolInstance._separated.counts.NumThreadsGoal * 1000)) : 500u);
287 else if ((num & 4) == 0)
306 IsThreadPoolThread =
true,
308 Name =
".NET ThreadPool Gate"
380 double num = rhs.Real * rhs.Real + rhs.Imaginary * rhs.
Imaginary;
462 if (int32Config <= int32Config2)
480 public (
int newThreadCount,
int newSampleMs)
Update(
int currentThreadCount,
double sampleDurationSeconds,
int numCompletions)
498 double num = (double)numCompletions / sampleDurationSeconds;
518 for (
int i = 0; i < num5; i++)
523 double num8 = num6 / (double)num5;
524 double num9 = num7 / (double)num5;
525 if (num8 > 0.0 && num9 > 0.0)
527 double period = (double)num5 / ((
double)num5 / (double)
_wavePeriod + 1.0);
528 double num10 = (double)num5 / ((
double)num5 / (double)
_wavePeriod - 1.0);
531 if (num10 <= (
double)num5)
544 if (complex.
Abs() > 0.0)
551 complex3 =
new Complex(0.0, 0.0);
577 val2 =
Math.
Min(maxThreads, val2);
578 val2 =
Math.
Max(minThreadsGoal, val2);
581 NativeRuntimeEventSource.
Log.ThreadPoolWorkerThreadAdjustmentStats(sampleDurationSeconds, num, complex.
Real, complex2.
Real, num3,
_averageThroughputNoise, complex3.
Real, num4,
_currentControlSetting, (ushort)val, 0);
583 if (val2 != currentThreadCount)
614 reference.stateOrTransition = stateOrTransition;
617 reference.lastHistoryMean = (float)throughput;
636 double num = Math.PI * 2.0 / period;
638 double num3 = 2.0 * num2;
642 for (
int i = 0; i < numSamples; i++)
648 return new Complex(num5 - num6 * num2, num6 *
Math.
Sin(num)) / numSamples;
699 return (
short)(
_data >> (int)shift);
704 _data = (
_data & (ulong)(~(65535
L << (
int)shift))) | ((ulong)(ushort)
value << (int)shift);
728 threadCounts2 = threadCounts;
729 threadCounts2.NumThreadsGoal =
value;
731 if (threadCounts3 == threadCounts)
735 threadCounts = threadCounts3;
737 return threadCounts2;
752 return lhs._data == rhs.
_data;
755 public override bool Equals([NotNullWhen(
true)]
object obj)
759 return _data == threadCounts._data;
803 IsThreadPoolThread =
true,
805 Name =
".NET ThreadPool Wait"
823 for (
int i = 0; i < num; i++)
829 num2 = ((num2 != -1) ?
Math.
Min(num3, num2) : num3);
838 if (num4 >= 128 && num4 < 129 + num)
859 for (
int j = 0; j < num; j++)
890 for (j = 0; j < numUserWaits2 && registeredWaitHandle !=
_registeredWaits[j]; j++)
894 if (j + 1 < numUserWaits2)
897 int num2 = numUserWaits2;
943 bool success =
false;
944 handle.Handle.DangerousAddRef(ref success);
948 handle.WaitThread =
this;
983 handle.WaitForCallbacks();
1017 bool spinWait =
true;
1018 while (lowLevelLifoSemaphore.
Wait(20000, spinWait))
1045 threadAdjustmentLock.
Acquire();
1058 short num = (
short)(numExistingThreads - 1);
1061 if (threadCounts2 == threadCounts)
1070 threadCounts = threadCounts2;
1075 threadAdjustmentLock.
Release();
1092 short numProcessingWork;
1094 short numExistingThreads;
1103 num = (
short)(numProcessingWork + 1);
1105 num2 =
Math.
Max(numExistingThreads, num);
1107 newCounts.NumProcessingWork = num;
1108 newCounts.NumExistingThreads = num2;
1110 if (threadCounts2 == threadCounts)
1114 threadCounts = threadCounts2;
1116 int num3 = num2 - numExistingThreads;
1117 int num4 = num - numProcessingWork;
1136 if (!(threadCounts3 == threadCounts))
1138 threadCounts = threadCounts3;
1159 if (threadCounts2 == threadCounts)
1163 threadCounts = threadCounts2;
1188 thread.IsThreadPoolThread =
true;
1189 thread.IsBackground =
true;
1219 return (
short)(
_data >> (int)shift);
1224 _data = (
_data & (uint)(~(65535 << (
int)shift))) | (uint)((ushort)
value << (int)shift);
1256 return lhs._data == rhs.
_data;
1263 return _data == countsOfThreadsProcessingUserCallbacks._data;
1295 if (num > 0 && num2 > 0)
1297 long val = num2 * 100 / num;
1386 if (workerThreads < 0 || ioCompletionThreads < 0)
1444 if (workerThreads <= 0 || ioCompletionThreads <= 0)
1503 _separated.lastDequeueTime = currentTimeMs;
1539 double num = (double)(timestamp - currentSampleStartTime) / (double)frequency;
1548 if (numThreadsGoal != (
short)num3)
1551 if (num3 > numThreadsGoal)
1556 _separated.priorCompletionCount = num2;
1564 threadAdjustmentLock.
Release();
1580 uint num3 = (uint)(currentTimeMs - num);
1689 if (num == targetThreadsGoalForBlockingAdjustment)
1693 if (num > targetThreadsGoalForBlockingAdjustment)
1708 short num4 =
Math.
Min(targetThreadsGoalForBlockingAdjustment, val);
1716 if (!previousDelayElapsed)
1720 num5 = (
short)(num + 1);
1725 if (memoryLimitBytes > 0)
1728 long num7 = memoryLimitBytes * 8 / 10;
1733 long val2 = counts.NumExistingThreads + (num7 - num6) / 65536;
1749 if (num >= targetThreadsGoalForBlockingAdjustment)
1775 if (waitThreadNode ==
null)
1786 waitThreadNode2 = waitThreadNode;
1787 waitThreadNode = waitThreadNode.
Next;
1789 while (waitThreadNode !=
null);
1805 handle.PerformCallback(timedOut);
1829 if (waitThreadNode.
Thread == thread)
1837 waitThreadNode2 = waitThreadNode;
1838 waitThreadNode = waitThreadNode.
Next;
1840 while (waitThreadNode !=
null && waitThreadNode.
Thread != thread);
1841 if (waitThreadNode !=
null)
1843 waitThreadNode2.Next = waitThreadNode.
Next;
1853 if (isProcessingUserCallback)
1862 if (!(countsOfThreadsProcessingUserCallbacks2 == countsOfThreadsProcessingUserCallbacks))
1864 countsOfThreadsProcessingUserCallbacks = countsOfThreadsProcessingUserCallbacks2;
1880 if (countsOfThreadsProcessingUserCallbacks2 == countsOfThreadsProcessingUserCallbacks || countsOfThreadsProcessingUserCallbacks2.
HighWatermark == countsOfThreadsProcessingUserCallbacks2.
Current)
1884 countsOfThreadsProcessingUserCallbacks = countsOfThreadsProcessingUserCallbacks2;
1886 return countsOfThreadsProcessingUserCallbacks2.
HighWatermark;
static bool GetSystemTimes(out long idle, out long kernel, out long user)
static short GetInt16Config(string configName, short defaultValue, bool allowNegative=true)
static bool GetBooleanConfig(string configName, bool defaultValue)
static int GetInt32Config(string configName, int defaultValue, bool allowNegative=true)
int IList. IndexOf(object value)
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
static readonly long Frequency
static long GetTimestamp()
static readonly NativeRuntimeEventSource Log
ThreadAdjustmentReasonMap
static int ProcessorCount
static bool IsSingleProcessor
static GCMemoryInfo GetGCMemoryInfo()
static void Register(Func< bool > callback)
static double Cos(double d)
static byte Min(byte val1, byte val2)
static double Sqrt(double d)
static double Pow(double x, double y)
static double Abs(double value)
static double Sin(double a)
static byte Max(byte val1, byte val2)
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
static int Decrement(ref int location)
static int Increment(ref int location)
bool Wait(int timeoutMs, bool spinWait)
static readonly uint MaxDelayMs
static readonly short ThreadsPerDelayStep
static readonly uint DelayStepMs
static readonly short ThreadsToAddWithoutDelay
static readonly bool IsCooperativeBlockingEnabled
static void Wake(PortableThreadPool threadPoolInstance)
static void EnsureRunning(PortableThreadPool threadPoolInstance)
static readonly AutoResetEvent RunGateThreadEvent
static int GetRunningStateForNumRuns(int numRuns)
static void EnsureRunningSlow(PortableThreadPool threadPoolInstance)
static readonly AutoResetEvent DelayEvent
static bool SufficientDelaySinceLastDequeue(PortableThreadPool threadPoolInstance)
static void GateThreadStart()
static void CreateGateThread(PortableThreadPool threadPoolInstance)
readonly double _targetThroughputRatio
Complex GetWaveComponent(double[] samples, int numSamples, double period)
static readonly bool IsDisabled
void ChangeThreadCount(int newThreadCount, StateOrTransition state)
readonly int _sampleIntervalMsLow
readonly double _targetSignalToNoiseRatio
readonly double _throughputErrorSmoothingFactor
double _secondsElapsedSinceLastChange
readonly double _maxSampleError
double _completionsSinceLastChange
readonly int _sampleIntervalMsHigh
double _averageThroughputNoise
void LogTransition(int newThreadCount, double throughput, StateOrTransition stateOrTransition)
int _accumulatedCompletionCount
readonly double _threadMagnitudeMultiplier
double _currentControlSetting
double _accumulatedSampleDurationSeconds
readonly double[] _threadCounts
void ForceChange(int newThreadCount, StateOrTransition state)
readonly int _samplesToMeasure
readonly int _maxThreadWaveMagnitude
readonly Random _randomIntervalGenerator
readonly double _gainExponent
readonly double _maxChangePerSample
static readonly HillClimbing ThreadPoolHillClimber
readonly double[] _samples
readonly double _maxChangePerSecond
WaitThreadNode(WaitThread thread)
void UnregisterWait(RegisteredWaitHandle handle)
bool RegisterWaitHandle(RegisteredWaitHandle handle)
readonly RegisteredWaitHandle[] _registeredWaits
readonly SafeWaitHandle[] _waitHandles
readonly RegisteredWaitHandle[] _pendingRemoves
void UnregisterWait(RegisteredWaitHandle handle, bool blocking)
readonly AutoResetEvent _changeHandlesEvent
void QueueWaitCompletion(RegisteredWaitHandle registeredHandle, bool timedOut)
static void RemoveWorkingWorker(PortableThreadPool threadPoolInstance)
static readonly ThreadStart s_workerThreadStart
static void WorkerThreadStart()
static bool TryCreateWorkerThread()
static readonly LowLevelLifoSemaphore s_semaphore
static bool ShouldStopProcessingWorkNow(PortableThreadPool threadPoolInstance)
static void MaybeAddWorkingWorker(PortableThreadPool threadPoolInstance)
static bool TakeActiveRequest(PortableThreadPool threadPoolInstance)
object GetOrCreateThreadLocalCompletionCountObject()
static readonly short ForcedMaxWorkerThreads
static readonly short ForcedMinWorkerThreads
short GetAndResetHighWatermarkCountOfThreadsProcessingUserCallbacks()
bool TryRemoveWaitThread(WaitThread thread)
PendingBlockingAdjustment _pendingBlockingAdjustment
static void EnsureGateThreadRunning()
readonly LowLevelLock _threadAdjustmentLock
CountsOfThreadsProcessingUserCallbacks _countsOfThreadsProcessingUserCallbacks
static object t_completionCountObject
int _threadAdjustmentIntervalMs
CacheLineSeparated _separated
short _numThreadsAddedDueToBlocking
void AdjustMaxWorkersActive()
int GetAvailableThreads()
PendingBlockingAdjustment
readonly LowLevelLock _waitThreadLock
readonly ThreadInt64PersistentCounter _completionCounter
bool SetMinThreads(int workerThreads, int ioCompletionThreads)
long CompletedWorkItemCount
void NotifyThreadUnblocked()
static void CompleteWait(RegisteredWaitHandle handle, bool timedOut)
void RemoveWaitThread(WaitThread thread)
object CreateThreadLocalCompletionCountObject()
long _currentSampleStartTime
bool ShouldAdjustMaxWorkersActive(int currentTimeMs)
short TargetThreadsGoalForBlockingAdjustment
bool SetMaxThreads(int workerThreads, int ioCompletionThreads)
uint PerformBlockingAdjustment(bool previousDelayElapsed)
bool NotifyWorkItemComplete(object threadLocalCompletionCountObject, int currentTimeMs)
WaitThreadNode _waitThreadsHead
void ReportThreadStatus(bool isProcessingUserCallback)
void NotifyWorkItemProgress(object threadLocalCompletionCountObject, int currentTimeMs)
bool NotifyThreadBlocked()
static readonly PortableThreadPool ThreadPoolInstance
uint PerformBlockingAdjustment(bool previousDelayElapsed, out bool addWorker)
void RegisterWaitHandle(RegisteredWaitHandle handle)
void NotifyWorkItemProgress()
static void Increment(object threadLocalCountObject)
object CreateThreadLocalCountObject()
static void SetMinIOCompletionThreads(int ioCompletionThreads)
static bool EnableWorkerTracking
static bool PerformRuntimeSpecificGateActivities(int cpuUtilization)
static void SetMaxIOCompletionThreads(int ioCompletionThreads)
static void UnsafeQueueWaitCompletion(CompleteWaitThreadPoolWorkItem completeWaitWorkItem)
static bool CanSetMinIOCompletionThreads(int ioCompletionThreads)
static bool CanSetMaxIOCompletionThreads(int ioCompletionThreads)
static Thread CurrentThread
static void SpinWait(int iterations)
static void UninterruptibleSleep0()
void UnsafeStart(object? parameter)
static bool Read(ref bool location)
static void Write(ref bool location, bool value)
static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout)
SafeWaitHandle SafeWaitHandle
delegate void ThreadStart()
long HighMemoryLoadThresholdBytes
volatile int numRequestedWorkers
int nextCompletedWorkRequestsTime
int priorCompletedWorkRequestsTime
int gateThreadRunningState
CountsOfThreadsProcessingUserCallbacks InterlockedCompareExchange(CountsOfThreadsProcessingUserCallbacks newCounts, CountsOfThreadsProcessingUserCallbacks oldCounts)
void SetInt16Value(short value, byte shift)
override int GetHashCode()
CountsOfThreadsProcessingUserCallbacks(uint data)
void ResetHighWatermark()
override bool Equals([NotNullWhen(true)] object obj)
static bool operator==(CountsOfThreadsProcessingUserCallbacks lhs, CountsOfThreadsProcessingUserCallbacks rhs)
short GetInt16Value(byte shift)
bool HasBlockingAdjustmentDelay
uint _previousBlockingAdjustmentDelayMs
void SetGateActivitiesTime(int currentTimeMs)
bool _runGateActivitiesAfterNextDelay
bool ShouldPerformGateActivities(int currentTimeMs, bool wasSignaledToWake)
void ClearBlockingAdjustmentDelay()
bool _adjustForBlockingAfterNextDelay
int _previousBlockingAdjustmentDelayStartTimeMs
bool HasBlockingAdjustmentDelayElapsed(int currentTimeMs, bool wasSignaledToWake)
void SetBlockingAdjustmentTimeAndDelay(int currentTimeMs, uint delayMs)
int _previousGateActivitiesTimeMs
uint GetNextDelay(int currentTimeMs)
static Complex operator*(double scalar, Complex complex)
static Complex operator-(Complex lhs, Complex rhs)
Complex(double real, double imaginary)
static Complex operator/(Complex complex, double scalar)
StateOrTransition stateOrTransition
ThreadCounts VolatileRead()
static bool operator==(ThreadCounts lhs, ThreadCounts rhs)
void InterlockedDecrementNumProcessingWork()
override bool Equals([NotNullWhen(true)] object obj)
ThreadCounts InterlockedCompareExchange(ThreadCounts newCounts, ThreadCounts oldCounts)
override int GetHashCode()
void SubtractNumProcessingWork(short value)
short GetInt16Value(byte shift)
void SubtractNumExistingThreads(short value)
ThreadCounts InterlockedSetNumThreadsGoal(short value)
void SetInt16Value(short value, byte shift)