From 3c07febf02b67c4c5f8eef846d5aa581372e454e Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 10 Apr 2019 12:08:27 +0200 Subject: [PATCH] Fix RecycledLists size on Unix The list size was set to g_SystemInfo.dwNumberOfProcessors which is a number of processors the current process is allowed to run on, but not the total number of processors in the system. Fixed to use PAL_GetTotalCpuCount. Also revert a change to the mbind node mask length computation I've incorrectly made in my last commit and make it clear that the value is a number of used bits in the node mask, which is the highest numa node plus 1. And finally, re-reading the mbind doc, I've found that the maxnode parameter is in fact "number of nodes" in the mask, so fixing that too. --- src/gc/unix/gcenv.unix.cpp | 5 +++-- src/pal/src/numa/numa.cpp | 5 +++-- src/vm/win32threadpool.cpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gc/unix/gcenv.unix.cpp b/src/gc/unix/gcenv.unix.cpp index 105a958..fbba7d9 100644 --- a/src/gc/unix/gcenv.unix.cpp +++ b/src/gc/unix/gcenv.unix.cpp @@ -573,7 +573,8 @@ bool GCToOSInterface::VirtualCommit(void* address, size_t size, uint16_t node) { if ((int)node <= g_highestNumaNode) { - int nodeMaskLength = (g_highestNumaNode + sizeof(unsigned long) - 1) / sizeof(unsigned long); + int usedNodeMaskBits = g_highestNumaNode + 1; + int nodeMaskLength = (usedNodeMaskBits + sizeof(unsigned long) - 1) / sizeof(unsigned long); unsigned long *nodeMask = (unsigned long*)alloca(nodeMaskLength * sizeof(unsigned long)); memset(nodeMask, 0, nodeMaskLength); @@ -581,7 +582,7 @@ bool GCToOSInterface::VirtualCommit(void* address, size_t size, uint16_t node) int mask = ((unsigned long)1) << (node & (sizeof(unsigned long) - 1)); nodeMask[index] = mask; - int st = mbind(address, size, MPOL_PREFERRED, nodeMask, g_highestNumaNode, 0); + int st = mbind(address, size, MPOL_PREFERRED, nodeMask, usedNodeMaskBits, 0); assert(st == 0); // If the mbind fails, we still return the allocated memory since the node is just a hint } diff --git a/src/pal/src/numa/numa.cpp b/src/pal/src/numa/numa.cpp index aabb800..4a07068 100644 --- a/src/pal/src/numa/numa.cpp +++ b/src/pal/src/numa/numa.cpp @@ -204,7 +204,8 @@ VirtualAllocExNuma( #if HAVE_NUMA_H if (result != NULL && g_numaAvailable) { - int nodeMaskLength = (g_highestNumaNode + sizeof(unsigned long) - 1) / sizeof(unsigned long); + int usedNodeMaskBits = g_highestNumaNode + 1; + int nodeMaskLength = (usedNodeMaskBits + sizeof(unsigned long) - 1) / sizeof(unsigned long); unsigned long *nodeMask = (unsigned long*)alloca(nodeMaskLength * sizeof(unsigned long)); memset(nodeMask, 0, nodeMaskLength); @@ -212,7 +213,7 @@ VirtualAllocExNuma( int mask = ((unsigned long)1) << (nndPreferred & (sizeof(unsigned long) - 1)); nodeMask[index] = mask; - int st = mbind(result, dwSize, MPOL_PREFERRED, nodeMask, g_highestNumaNode, 0); + int st = mbind(result, dwSize, MPOL_PREFERRED, nodeMask, usedNodeMaskBits, 0); _ASSERTE(st == 0); // If the mbind fails, we still return the allocated memory since the nndPreferred is just a hint diff --git a/src/vm/win32threadpool.cpp b/src/vm/win32threadpool.cpp index 09a3a07..b501496 100644 --- a/src/vm/win32threadpool.cpp +++ b/src/vm/win32threadpool.cpp @@ -391,7 +391,7 @@ BOOL ThreadpoolMgr::Initialize() else RecycledLists.Initialize( g_SystemInfo.dwNumberOfProcessors ); #else // !FEATURE_PAL - RecycledLists.Initialize( g_SystemInfo.dwNumberOfProcessors ); + RecycledLists.Initialize( PAL_GetTotalCpuCount() ); #endif // !FEATURE_PAL } EX_CATCH @@ -404,7 +404,7 @@ BOOL ThreadpoolMgr::Initialize() RetiredCPWakeupEvent = NULL; } - // Note: It is fine to call Destroy on unitialized critical sections + // Note: It is fine to call Destroy on uninitialized critical sections WorkerCriticalSection.Destroy(); WaitThreadsCriticalSection.Destroy(); TimerQueueCriticalSection.Destroy(); -- 2.7.4