summaryrefslogtreecommitdiff
path: root/src/gc
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2019-04-02 23:35:09 +0200
committerJan Vorlicek <janvorli@microsoft.com>2019-04-03 21:12:09 +0200
commitcb8b829fd3717acc2688025341f822e4097cf5c5 (patch)
tree2979eb6430998ab527ccd87919eb24ada6251384 /src/gc
parent94359a5208206be08ff44a1fc14e0334e2af2071 (diff)
downloadcoreclr-cb8b829fd3717acc2688025341f822e4097cf5c5.tar.gz
coreclr-cb8b829fd3717acc2688025341f822e4097cf5c5.tar.bz2
coreclr-cb8b829fd3717acc2688025341f822e4097cf5c5.zip
Use the GCHeapAffinitizeRanges / GCHeapAffinitizeMask exclusively
The GCHeapAffinitizeRanges are now used only when CPU groups are enabled and the GCHeapAffinitizeMask when CPU groups are disabled.
Diffstat (limited to 'src/gc')
-rw-r--r--src/gc/env/gcenv.os.h18
-rw-r--r--src/gc/gc.cpp19
-rw-r--r--src/gc/gcconfig.cpp75
-rw-r--r--src/gc/gcconfig.h2
-rw-r--r--src/gc/unix/gcenv.unix.cpp19
-rw-r--r--src/gc/windows/gcenv.windows.cpp67
6 files changed, 118 insertions, 82 deletions
diff --git a/src/gc/env/gcenv.os.h b/src/gc/env/gcenv.os.h
index 323e19309b..b98037bc6d 100644
--- a/src/gc/env/gcenv.os.h
+++ b/src/gc/env/gcenv.os.h
@@ -153,12 +153,12 @@ class AffinitySet
uintptr_t m_bitset[MAX_SUPPORTED_CPUS / BitsPerBitsetEntry];
- uintptr_t GetBitsetEntryMask(size_t cpuIndex)
+ static uintptr_t GetBitsetEntryMask(size_t cpuIndex)
{
return (uintptr_t)1 << (cpuIndex & (BitsPerBitsetEntry - 1));
}
- size_t GetBitsetEntryIndex(size_t cpuIndex)
+ static size_t GetBitsetEntryIndex(size_t cpuIndex)
{
return cpuIndex / BitsPerBitsetEntry;
}
@@ -171,7 +171,7 @@ public:
}
// Check if the set contains a processor
- bool Contains(size_t cpuIndex)
+ bool Contains(size_t cpuIndex) const
{
return (m_bitset[GetBitsetEntryIndex(cpuIndex)] & GetBitsetEntryMask(cpuIndex)) != 0;
}
@@ -189,7 +189,7 @@ public:
}
// Check if the set is empty
- bool IsEmpty()
+ bool IsEmpty() const
{
for (size_t i = 0; i < MAX_SUPPORTED_CPUS / BitsPerBitsetEntry; i++)
{
@@ -203,7 +203,7 @@ public:
}
// Return number of processors in the affinity set
- size_t Count()
+ size_t Count() const
{
size_t count = 0;
for (size_t i = 0; i < MAX_SUPPORTED_CPUS; i++)
@@ -388,10 +388,13 @@ public:
// true if the priority boost was successful, false otherwise.
static bool BoostThreadPriority();
- // Get set of processors enabled for GC for the current process
+ // Set the set of processors enabled for GC threads for the current process based on config specified affinity mask and set
+ // Parameters:
+ // configAffinityMask - mask specified by the GCHeapAffinitizeMask config
+ // configAffinitySet - affinity set specified by the GCHeapAffinitizeRanges config
// Return:
// set of enabled processors
- static AffinitySet* GetCurrentProcessAffinitySet();
+ static const AffinitySet* SetGCThreadsAffinitySet(uintptr_t configAffinityMask, const AffinitySet* configAffinitySet);
//
// Global memory info
@@ -476,7 +479,6 @@ public:
// Return:
// true if it succeeded
static bool GetProcessorForHeap(uint16_t heap_number, uint16_t* proc_no, uint16_t* node_no);
-
};
#endif // __GCENV_OS_H__
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index 910ff07874..704cf2673d 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -34086,24 +34086,13 @@ HRESULT GCHeap::Initialize()
#ifdef MULTIPLE_HEAPS
AffinitySet config_affinity_set;
- if (!ParseGCHeapAffinitySettings(&config_affinity_set))
+ if (!ParseGCHeapAffinitizeRanges(&config_affinity_set))
{
return CLR_E_GC_BAD_AFFINITY_CONFIG;
}
- AffinitySet* process_affinity_set = GCToOSInterface::GetCurrentProcessAffinitySet();
-
- if (!config_affinity_set.IsEmpty())
- {
- // Update the process affinity set using the configured set
- for (size_t i = 0; i < MAX_SUPPORTED_CPUS; i++)
- {
- if (process_affinity_set->Contains(i) && !config_affinity_set.Contains(i))
- {
- process_affinity_set->Remove(i);
- }
- }
- }
+ uintptr_t config_affinity_mask = static_cast<uintptr_t>(GCConfig::GetGCHeapAffinitizeMask());
+ const AffinitySet* process_affinity_set = GCToOSInterface::SetGCThreadsAffinitySet(config_affinity_mask, &config_affinity_set);
if (process_affinity_set->IsEmpty())
{
@@ -34129,7 +34118,7 @@ HRESULT GCHeap::Initialize()
if (gc_heap::heap_hard_limit)
{
- gc_heap::gc_thread_no_affinitize_p = (config_affinity_set.Count() == 0);
+ gc_heap::gc_thread_no_affinitize_p = ((config_affinity_set.Count() == 0) && (config_affinity_mask == 0));
}
if (!(gc_heap::gc_thread_no_affinitize_p))
diff --git a/src/gc/gcconfig.cpp b/src/gc/gcconfig.cpp
index 1e9dbe1980..b151511e96 100644
--- a/src/gc/gcconfig.cpp
+++ b/src/gc/gcconfig.cpp
@@ -47,71 +47,56 @@ GC_CONFIGURATION_KEYS
#undef INT_CONFIG
}
-bool ParseGCHeapAffinitySettings(AffinitySet* config_affinity_set)
+bool ParseGCHeapAffinitizeRanges(AffinitySet* config_affinity_set)
{
bool success = true;
- // Get the affinity set configured by the user
- uintptr_t heap_affinity_mask = GCConfig::GetGCHeapAffinitizeMask();
- if (heap_affinity_mask != 0)
+ GCConfigStringHolder cpu_index_ranges_holder(GCConfig::GetGCHeapAffinitizeRanges());
+ const char* cpu_index_ranges = cpu_index_ranges_holder.Get();
+
+ // The cpu index ranges is a comma separated list of indices or ranges of indices (e.g. 1-5).
+ // Example 1,3,5,7-9,12
+
+ if (cpu_index_ranges != NULL)
{
- for (size_t i = 0; i < 8 * sizeof(uintptr_t); i++)
+ char* number_end;
+
+ do
{
- if (heap_affinity_mask & ((uintptr_t)1 << i))
+ size_t start_index = strtoul(cpu_index_ranges, &number_end, 10);
+
+ if (number_end == cpu_index_ranges)
{
- config_affinity_set->Add(i);
+ // No number found, invalid format
+ break;
}
- }
- }
- else
- {
- GCConfigStringHolder cpu_index_ranges_holder(GCConfig::GetGCHeapAffinitizeRanges());
- const char* cpu_index_ranges = cpu_index_ranges_holder.Get();
- // The cpu index ranges is a comma separated list of indices or ranges of indices (e.g. 1-5).
- // Example 1,3,5,7-9,12
-
- if (cpu_index_ranges != NULL)
- {
- char* number_end;
+ size_t end_index = start_index;
- do
+ if (*number_end == '-')
{
- size_t start_index = strtoul(cpu_index_ranges, &number_end, 10);
-
- if (number_end == cpu_index_ranges)
+ char* range_end_start = number_end + 1;
+ end_index = strtoul(range_end_start, &number_end, 10);
+ if (number_end == range_end_start)
{
// No number found, invalid format
break;
}
+ }
- size_t end_index = start_index;
-
- if (*number_end == '-')
- {
- char* range_end_start = number_end + 1;
- end_index = strtoul(range_end_start, &number_end, 10);
- if (number_end == range_end_start)
- {
- // No number found, invalid format
- break;
- }
- }
-
- if ((start_index < MAX_SUPPORTED_CPUS) && end_index < (MAX_SUPPORTED_CPUS))
+ if ((start_index < MAX_SUPPORTED_CPUS) && end_index < (MAX_SUPPORTED_CPUS))
+ {
+ for (size_t i = start_index; i <= end_index; i++)
{
- for (size_t i = start_index; i <= end_index; i++)
- {
- config_affinity_set->Add(i);
- }
+ config_affinity_set->Add(i);
}
-
- cpu_index_ranges = number_end + 1;
}
- while (*number_end == ',');
- success = (*number_end == '\0');
+ cpu_index_ranges = number_end + 1;
}
+ while (*number_end == ',');
+
+ success = (*number_end == '\0');
}
return success;
diff --git a/src/gc/gcconfig.h b/src/gc/gcconfig.h
index f292a12a91..b2fea16cb2 100644
--- a/src/gc/gcconfig.h
+++ b/src/gc/gcconfig.h
@@ -156,6 +156,6 @@ static void Initialize();
};
-bool ParseGCHeapAffinitySettings(AffinitySet* config_affinity_set);
+bool ParseGCHeapAffinitizeRanges(AffinitySet* config_affinity_set);
#endif // __GCCONFIG_H__
diff --git a/src/gc/unix/gcenv.unix.cpp b/src/gc/unix/gcenv.unix.cpp
index 140c5468bf..4719dc9d97 100644
--- a/src/gc/unix/gcenv.unix.cpp
+++ b/src/gc/unix/gcenv.unix.cpp
@@ -490,11 +490,26 @@ bool GCToOSInterface::BoostThreadPriority()
return false;
}
-// Get set of processors enabled for GC for the current process
+// Set the set of processors enabled for GC threads for the current process based on config specified affinity mask and set
+// Parameters:
+// configAffinityMask - mask specified by the GCHeapAffinitizeMask config
+// configAffinitySet - affinity set specified by the GCHeapAffinitizeRanges config
// Return:
// set of enabled processors
-AffinitySet* GCToOSInterface::GetCurrentProcessAffinitySet()
+const AffinitySet* GCToOSInterface::SetGCThreadsAffinitySet(uintptr_t configAffinityMask, const AffinitySet* configAffinitySet)
{
+ if (!configAffinitySet->IsEmpty())
+ {
+ // Update the process affinity set using the configured set
+ for (size_t i = 0; i < MAX_SUPPORTED_CPUS; i++)
+ {
+ if (g_processAffinitySet.Contains(i) && !configAffinitySet->Contains(i))
+ {
+ g_processAffinitySet.Remove(i);
+ }
+ }
+ }
+
return &g_processAffinitySet;
}
diff --git a/src/gc/windows/gcenv.windows.cpp b/src/gc/windows/gcenv.windows.cpp
index 738fdecfa5..5d323dd583 100644
--- a/src/gc/windows/gcenv.windows.cpp
+++ b/src/gc/windows/gcenv.windows.cpp
@@ -518,16 +518,30 @@ bool GCToOSInterface::Initialize()
InitNumaNodeInfo();
InitCPUGroupInfo();
- uintptr_t pmask, smask;
- if (!!::GetProcessAffinityMask(::GetCurrentProcess(), (PDWORD_PTR)&pmask, (PDWORD_PTR)&smask))
+ if (CanEnableGCCPUGroups())
{
- pmask &= smask;
-
- for (size_t i = 0; i < 8 * sizeof(uintptr_t); i++)
+ // When CPU groups are enabled, then the process is not bound by the process affinity set at process launch.
+ // Set the initial affinity mask so that all processors are enabled.
+ for (size_t i = 0; i < g_nProcessors; i++)
+ {
+ g_processAffinitySet.Add(i);
+ }
+ }
+ else
+ {
+ // When CPU groups are disabled, the process affinity mask specified at the process launch cannot be
+ // escaped.
+ uintptr_t pmask, smask;
+ if (!!::GetProcessAffinityMask(::GetCurrentProcess(), (PDWORD_PTR)&pmask, (PDWORD_PTR)&smask))
{
- if ((pmask & ((uintptr_t)1 << i)) != 0)
+ pmask &= smask;
+
+ for (size_t i = 0; i < 8 * sizeof(uintptr_t); i++)
{
- g_processAffinitySet.Add(i);
+ if ((pmask & ((uintptr_t)1 << i)) != 0)
+ {
+ g_processAffinitySet.Add(i);
+ }
}
}
}
@@ -953,11 +967,44 @@ bool GCToOSInterface::BoostThreadPriority()
return !!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
}
-// Get set of processors enabled for GC for the current process
+// Set the set of processors enabled for GC threads for the current process based on config specified affinity mask and set
+// Parameters:
+// configAffinityMask - mask specified by the GCHeapAffinitizeMask config
+// configAffinitySet - affinity set specified by the GCHeapAffinitizeRanges config
// Return:
// set of enabled processors
-AffinitySet* GCToOSInterface::GetCurrentProcessAffinitySet()
+const AffinitySet* GCToOSInterface::SetGCThreadsAffinitySet(uintptr_t configAffinityMask, const AffinitySet* configAffinitySet)
{
+ // When the configAffinitySet is not empty, enforce the cpu groups
+ if (CanEnableGCCPUGroups())
+ {
+ if (!configAffinitySet->IsEmpty())
+ {
+ // Update the process affinity set using the configured set
+ for (size_t i = 0; i < MAX_SUPPORTED_CPUS; i++)
+ {
+ if (g_processAffinitySet.Contains(i) && !configAffinitySet->Contains(i))
+ {
+ g_processAffinitySet.Remove(i);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (configAffinityMask != 0)
+ {
+ // Update the process affinity set using the configured mask
+ for (size_t i = 0; i < 8 * sizeof(uintptr_t); i++)
+ {
+ if (g_processAffinitySet.Contains(i) && ((configAffinityMask & ((uintptr_t)1 << i)) == 0))
+ {
+ g_processAffinitySet.Remove(i);
+ }
+ }
+ }
+ }
+
return &g_processAffinitySet;
}
@@ -1205,7 +1252,6 @@ bool GCToOSInterface::GetProcessorForHeap(uint16_t heap_number, uint16_t* proc_n
uint16_t gn, gpn;
GetGroupForProcessor((uint16_t)heap_number, &gn, &gpn);
-// dprintf(3, ("using processor group %d, mask %Ix for heap %d\n", gn, (uintptr_t)1 << gpn), heap_number));
*proc_no = GroupProcNo(gn, gpn).GetCombinedValue();
if (GCToOSInterface::CanEnableGCNumaAware())
@@ -1232,7 +1278,6 @@ bool GCToOSInterface::GetProcessorForHeap(uint16_t heap_number, uint16_t* proc_n
{
if (bit_number == heap_number)
{
- //dprintf (3, ("Using processor %d for heap %d", proc_number, heap_number));
*proc_no = GroupProcNo(GroupProcNo::NoGroup, proc_number).GetCombinedValue();
if (GCToOSInterface::CanEnableGCNumaAware())