Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,26 @@ private static void GateThreadStart()
bool debuggerBreakOnWorkStarvation =
AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.DebugBreakOnWorkerStarvation", false);

// CPU utilization is updated when the gate thread performs periodic activities (GateActivitiesPeriodMs), so
// that would also affect the actual interval. Set to 0 to disable using CPU utilization and have components
// behave as though CPU utilization is low. The default value of 1 causes CPU utilization to be updated whenever
// the gate thread performs periodic activities.
int cpuUtilizationIntervalMs =
AppContextConfigHelper.GetInt32Config(
"System.Threading.ThreadPool.CpuUtilizationIntervalMs",
"DOTNET_ThreadPool_CpuUtilizationIntervalMs",
defaultValue: 1,
allowNegative: false);

// The first reading is over a time range other than what we are focusing on, so we do not use the read other
// than to send it to any runtime-specific implementation that may also use the CPU utilization.
CpuUtilizationReader cpuUtilizationReader = default;
_ = cpuUtilizationReader.CurrentUtilization;
int lastCpuUtilizationRefreshTimeMs = 0;
if (cpuUtilizationIntervalMs > 0)
{
lastCpuUtilizationRefreshTimeMs = Environment.TickCount;
_ = cpuUtilizationReader.CurrentUtilization;
}

PortableThreadPool threadPoolInstance = ThreadPoolInstance;
LowLevelLock threadAdjustmentLock = threadPoolInstance._threadAdjustmentLock;
Expand Down Expand Up @@ -102,8 +118,17 @@ private static void GateThreadStart()
(uint)threadPoolInstance.GetAndResetHighWatermarkCountOfThreadsProcessingUserCallbacks());
}

int cpuUtilization = (int)cpuUtilizationReader.CurrentUtilization;
threadPoolInstance._cpuUtilization = cpuUtilization;
// Determine whether CPU utilization should be updated. CPU utilization is only used by the starvation
// heuristic and hill climbing, and neither of those are active when there is a pending blocking
// adjustment.
if (cpuUtilizationIntervalMs > 0 &&
threadPoolInstance._pendingBlockingAdjustment == PendingBlockingAdjustment.None &&
(uint)(currentTimeMs - lastCpuUtilizationRefreshTimeMs) >= (uint)cpuUtilizationIntervalMs)
{
lastCpuUtilizationRefreshTimeMs = currentTimeMs;
int cpuUtilization = (int)cpuUtilizationReader.CurrentUtilization;
threadPoolInstance._cpuUtilization = cpuUtilization;
}

if (!disableStarvationDetection &&
threadPoolInstance._pendingBlockingAdjustment == PendingBlockingAdjustment.None &&
Expand Down
Loading