summaryrefslogtreecommitdiff
path: root/src/gc
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2019-03-14 22:30:00 +0100
committerJan Kotas <jkotas@microsoft.com>2019-03-14 14:30:00 -0700
commit23fbf7e7ab231876b9d54b52bac044cdde159118 (patch)
tree2f50034ca0d6a97c5d089b9ae9d3a5bfe576e1cd /src/gc
parent20e66e1a1ea4e93916026647bac3347e7863dd9b (diff)
downloadcoreclr-23fbf7e7ab231876b9d54b52bac044cdde159118.tar.gz
coreclr-23fbf7e7ab231876b9d54b52bac044cdde159118.tar.bz2
coreclr-23fbf7e7ab231876b9d54b52bac044cdde159118.zip
Fix GetProcessAffinityMask (#23247)
The function was returning mask not expected by runtime for coreclr built with NUMA enabled on machines with multiple NUMA nodes. The mask was 0 in case the current process was affinitized to CPUs from multiple NUMA nodes. It was following MSDN doc, however the doc turned out to be ambiguous. Moreover, the runtime depended on the fact that on Windows, a process is never run on multiple NUMA nodes unless is explicitly calls APIs to set ideal processor for threads. But on Unix, there is no such case and by default, a process is affinitized to all existing processors over all NUMA nodes. And there was one more issue. The GetProcessAffinityMask was returning a mask within a single CPU group, which is a transformed view of NUMA node on Windows. So the CPU indices in the mask didn't necessarily correspond to the native Unix CPU indices. But, the SetThreadAffinityMask was using the native Unix CPU indices. To fix the problem, the GetProcessAffinityMask is changed so that it always returns a mask corresponding to the native Unix CPU indices (reporting upto 64 processors as the mask is 64 bit wide). Thus it corresponds to what the SetThreadAffinityMask expects. And it also exactly matches the behavior when NUMA support is not compiled in. Moreover, the COMPlus_GCHeapAffinitizeMask bits now correspond to the native Unix CPU indices. The GetProcessAffinityMask is used by GC and thread pool only when NUMA is not enabled using the COMPlus_GCCpuGroup env variable.
Diffstat (limited to 'src/gc')
-rw-r--r--src/gc/unix/gcenv.unix.cpp17
1 files changed, 6 insertions, 11 deletions
diff --git a/src/gc/unix/gcenv.unix.cpp b/src/gc/unix/gcenv.unix.cpp
index 8148f6ff29..e64f62ac34 100644
--- a/src/gc/unix/gcenv.unix.cpp
+++ b/src/gc/unix/gcenv.unix.cpp
@@ -467,14 +467,9 @@ static uintptr_t GetFullAffinityMask(int cpuCount)
// specify a 1 bit for a processor when the system affinity mask specifies a 0 bit for that processor.
bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processAffinityMask, uintptr_t* systemAffinityMask)
{
- if (g_logicalCpuCount > 64)
- {
- *processAffinityMask = 0;
- *systemAffinityMask = 0;
- return true;
- }
+ unsigned int cpuCountInMask = (g_logicalCpuCount > 64) ? 64 : g_logicalCpuCount;
- uintptr_t systemMask = GetFullAffinityMask(g_logicalCpuCount);
+ uintptr_t systemMask = GetFullAffinityMask(cpuCountInMask);
#if HAVE_SCHED_GETAFFINITY
@@ -485,7 +480,7 @@ bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processAffinityMa
{
uintptr_t processMask = 0;
- for (unsigned int i = 0; i < g_logicalCpuCount; i++)
+ for (unsigned int i = 0; i < cpuCountInMask; i++)
{
if (CPU_ISSET(i, &cpuSet))
{
@@ -500,9 +495,9 @@ bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processAffinityMa
else if (errno == EINVAL)
{
// There are more processors than can fit in a cpu_set_t
- // return zero in both masks.
- *processAffinityMask = 0;
- *systemAffinityMask = 0;
+ // return all bits set for all processors (upto 64) for both masks
+ *processAffinityMask = systemMask;
+ *systemAffinityMask = systemMask;
return true;
}
else