diff --git a/src/coreclr/inc/configuration.h b/src/coreclr/inc/configuration.h index bf2d805e049b92..cfc7dcd5819a15 100644 --- a/src/coreclr/inc/configuration.h +++ b/src/coreclr/inc/configuration.h @@ -33,7 +33,9 @@ class Configuration // Unfortunately our traditional config system insists on interpreting numbers as 32-bit so interpret the config // in the traditional way separately if you need to. // - // Returns value for name if found in config. + // Returns (in priority order): + // - The value of the ConfigurationKnob (searched by name) if it's set (performs a _wcstoui64) + // - The default value passed in static ULONGLONG GetKnobULONGLONGValue(LPCWSTR name, ULONGLONG defaultValue); // Returns (in priority order): @@ -48,11 +50,17 @@ class Configuration static LPCWSTR GetKnobStringValue(LPCWSTR name); // Returns (in priority order): - // - The value of the ConfigDWORDInfo if it's set (1 is true, anything else is false) + // - The value of the ConfigDWORDInfo if it's set (0 is false, anything else is true) // - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcscmp with "true"). - // - The default set in the ConfigDWORDInfo (1 is true, anything else is false) + // - The default set in the ConfigDWORDInfo (0 is false, anything else is true) static bool GetKnobBooleanValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo); + // Returns (in priority order): + // - The value of the ConfigDWORDInfo if it's set (0 is false, anything else is true) + // - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcscmp with "true"). + // - The default value passed in + static bool GetKnobBooleanValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo, bool defaultValue); + // Returns (in priority order): // - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcscmp with "true"). // - The default value passed in diff --git a/src/coreclr/utilcode/configuration.cpp b/src/coreclr/utilcode/configuration.cpp index 50a5e335a742b9..170edc5b273bc2 100644 --- a/src/coreclr/utilcode/configuration.cpp +++ b/src/coreclr/utilcode/configuration.cpp @@ -123,6 +123,18 @@ bool Configuration::GetKnobBooleanValue(LPCWSTR name, const CLRConfig::ConfigDWO return (legacyValue != 0); } +bool Configuration::GetKnobBooleanValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo, bool defaultValue) +{ + bool returnedDefaultValue; + DWORD legacyValue = CLRConfig::GetConfigValue(dwordInfo, &returnedDefaultValue); + if (!returnedDefaultValue) + { + return (legacyValue != 0); + } + + return GetKnobBooleanValue(name, defaultValue); +} + bool Configuration::GetKnobBooleanValue(LPCWSTR name, bool defaultValue) { LPCWSTR knobValue = GetConfigurationValue(name); diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp index 2d2d2d22de2ec1..623ef923516ce5 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -760,7 +760,16 @@ DWORD LCM(DWORD u, DWORD v) CONTRACTL_END; #if !defined(FEATURE_NATIVEAOT) && (defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)) - BOOL enableGCCPUGroups = Configuration::GetKnobBooleanValue(W("System.GC.CpuGroup"), CLRConfig::EXTERNAL_GCCpuGroup); + USHORT groupCount = 0; + + // On Windows 11+ and Windows Server 2022+, a process is no longer restricted to a single processor group by default. + // If more than one processor group is available to the process (a non-affinitized process on Windows 11+), + // default to using multiple processor groups; otherwise, default to using a single processor group. This default + // behavior may be overridden by the configuration values below. + if (GetProcessGroupAffinity(GetCurrentProcess(), &groupCount, NULL) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) + groupCount = 1; + + BOOL enableGCCPUGroups = Configuration::GetKnobBooleanValue(W("System.GC.CpuGroup"), CLRConfig::EXTERNAL_GCCpuGroup, groupCount > 1); if (!enableGCCPUGroups) return; @@ -772,7 +781,7 @@ DWORD LCM(DWORD u, DWORD v) if (m_nGroups > 1) { m_enableGCCPUGroups = TRUE; - m_threadUseAllCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_UseAllCpuGroups) != 0; + m_threadUseAllCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_UseAllCpuGroups, groupCount > 1) != 0; m_threadAssignCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_AssignCpuGroups) != 0; // Save the processor group affinity of the initial thread