diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index 45888786b6dc..024c87a66f46 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -2266,6 +2266,8 @@ VOLATILE(BOOL) gc_heap::gc_started; CLREvent gc_heap::gc_start_event; +bool gc_heap::gc_thread_no_affinitize_p = false; + SVAL_IMPL_NS(int, SVR, gc_heap, n_heaps); SPTR_IMPL_NS(PTR_gc_heap, SVR, gc_heap, g_heaps); @@ -5199,14 +5201,16 @@ bool gc_heap::create_gc_thread () affinity.Processor = GCThreadAffinity::None; #if !defined(FEATURE_REDHAWK) && !defined(FEATURE_PAL) - //We are about to set affinity for GC threads, it is a good place to setup NUMA and - //CPU groups, because the process mask, processor number, group number are all - //readyly available. - if (CPUGroupInfo::CanEnableGCCPUGroups()) - set_thread_group_affinity_for_heap(heap_number, &affinity); - else - set_thread_affinity_mask_for_heap(heap_number, &affinity); - + if (!gc_thread_no_affinitize_p) + { + //We are about to set affinity for GC threads, it is a good place to setup NUMA and + //CPU groups, because the process mask, processor number, group number are all + //readyly available. + if (CPUGroupInfo::CanEnableGCCPUGroups()) + set_thread_group_affinity_for_heap(heap_number, &affinity); + else + set_thread_affinity_mask_for_heap(heap_number, &affinity); + } #endif // !FEATURE_REDHAWK && !FEATURE_PAL return GCToOSInterface::CreateThread(gc_thread_stub, this, &affinity); @@ -33673,9 +33677,18 @@ HRESULT GCHeap::Initialize () gc_heap::min_segment_size = min (seg_size, large_seg_size); #ifdef MULTIPLE_HEAPS + if (g_pConfig->GetGCNoAffinitize()) + gc_heap::gc_thread_no_affinitize_p = true; + + uint32_t nhp_from_config = g_pConfig->GetGCHeapCount(); // GetGCProcessCpuCount only returns up to 64 procs. - unsigned nhp = CPUGroupInfo::CanEnableGCCPUGroups() ? CPUGroupInfo::GetNumActiveProcessors(): - GCToOSInterface::GetCurrentProcessCpuCount(); + uint32_t nhp_from_process = CPUGroupInfo::CanEnableGCCPUGroups() ? + CPUGroupInfo::GetNumActiveProcessors(): + GCToOSInterface::GetCurrentProcessCpuCount(); + + uint32_t nhp = ((nhp_from_config == 0) ? nhp_from_process : + (min (nhp_from_config, nhp_from_process))); + hr = gc_heap::initialize_gc (seg_size, large_seg_size /*LHEAP_ALLOC*/, nhp); #else hr = gc_heap::initialize_gc (seg_size, large_seg_size /*LHEAP_ALLOC*/); diff --git a/src/gc/gcpriv.h b/src/gc/gcpriv.h index 4a2e9296205f..ec0c8324f497 100644 --- a/src/gc/gcpriv.h +++ b/src/gc/gcpriv.h @@ -2891,6 +2891,9 @@ class gc_heap int gc_policy; //sweep, compact, expand #ifdef MULTIPLE_HEAPS + PER_HEAP_ISOLATED + bool gc_thread_no_affinitize_p; + PER_HEAP_ISOLATED CLREvent gc_start_event; diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h index 2bb6e7897182..1cb9edef63ac 100644 --- a/src/inc/clrconfigvalues.h +++ b/src/inc/clrconfigvalues.h @@ -353,6 +353,8 @@ RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_HeapVerify, W("HeapVerify"), RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_SetupGcCoverage, W("SetupGcCoverage"), "This doesn't appear to be a config flag", CLRConfig::REGUTIL_default) RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCNumaAware, W("GCNumaAware"), 1, "Specifies if to enable GC NUMA aware") RETAIL_CONFIG_DWORD_INFO(EXTERNAL_GCCpuGroup, W("GCCpuGroup"), 0, "Specifies if to enable GC to support CPU groups") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCHeapCount, W("GCHeapCount"), 0, "") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCNoAffinitize, W("GCNoAffinitize"), 0, "") // // IBC diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp index 95e3d0c9feda..08938c371952 100644 --- a/src/vm/eeconfig.cpp +++ b/src/vm/eeconfig.cpp @@ -240,6 +240,8 @@ HRESULT EEConfig::Init() iGCForceCompact = 0; iGCHoardVM = 0; iGCLOHCompactionMode = 0; + iGCHeapCount = 0; + iGCNoAffinitize = 0; #ifdef GCTRIMCOMMIT iGCTrimCommit = 0; @@ -973,6 +975,9 @@ HRESULT EEConfig::sync() #endif iGCForceCompact = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_gcForceCompact, iGCForceCompact); + iGCNoAffinitize = Configuration::GetKnobBooleanValue(W("System.GC.NoAffinitize"), + CLRConfig::UNSUPPORTED_GCNoAffinitize); + iGCHeapCount = Configuration::GetKnobDWORDValue(W("System.GC.HeapCount"), CLRConfig::UNSUPPORTED_GCHeapCount); fStressLog = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, fStressLog) != 0; fForceEnc = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_ForceEnc, fForceEnc) != 0; diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h index 0853455aa361..02342d7e9387 100644 --- a/src/vm/eeconfig.h +++ b/src/vm/eeconfig.h @@ -692,6 +692,8 @@ class EEConfig int GetGCForceCompact() const {LIMITED_METHOD_CONTRACT; return iGCForceCompact; } int GetGCRetainVM () const {LIMITED_METHOD_CONTRACT; return iGCHoardVM;} int GetGCLOHCompactionMode() const {LIMITED_METHOD_CONTRACT; return iGCLOHCompactionMode;} + int GetGCHeapCount() const {LIMITED_METHOD_CONTRACT; return iGCHeapCount;} + int GetGCNoAffinitize () const {LIMITED_METHOD_CONTRACT; return iGCNoAffinitize;} #ifdef GCTRIMCOMMIT @@ -1077,6 +1079,8 @@ class EEConfig int iGCForceCompact; int iGCHoardVM; int iGCLOHCompactionMode; + int iGCHeapCount; + int iGCNoAffinitize; #ifdef GCTRIMCOMMIT