From 060990945a0117cb824b9d1c1e6c3a336533a3ee Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 5 Apr 2019 02:53:32 +0200 Subject: Remove Unix CPU groups emulation This change removes CPU groups emulation from Unix PAL and modifies the GC and thread pool code accordingly. --- src/vm/gcenv.os.cpp | 158 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 55 deletions(-) (limited to 'src/vm/gcenv.os.cpp') diff --git a/src/vm/gcenv.os.cpp b/src/vm/gcenv.os.cpp index a56215a207..8f9e1ba1bb 100644 --- a/src/vm/gcenv.os.cpp +++ b/src/vm/gcenv.os.cpp @@ -32,6 +32,10 @@ uint32_t g_pageSizeUnixInl = 0; static AffinitySet g_processAffinitySet; +#ifdef FEATURE_PAL +static uint32_t g_currentProcessCpuCount; +#endif // FEATURE_PAL + class GroupProcNo { uint16_t m_groupProc; @@ -106,8 +110,21 @@ bool GCToOSInterface::Initialize() #ifdef FEATURE_PAL g_pageSizeUnixInl = GetOsPageSize(); -#endif + g_currentProcessCpuCount = PAL_GetLogicalCpuCountFromOS(); + if (PAL_GetCurrentThreadAffinitySet(AffinitySet::BitsetDataSize, g_processAffinitySet.GetBitsetData())) + { + assert(g_currentProcessCpuCount == g_processAffinitySet.Count()); + } + else + { + // There is no way to get affinity on the current OS, set the affinity set to reflect all processors + for (size_t i = 0; i < g_currentProcessCpuCount; i++) + { + g_processAffinitySet.Add(i); + } + } +#else // FEATURE_PAL if (CPUGroupInfo::CanEnableGCCPUGroups()) { // When CPU groups are enabled, then the process is not bound by the process affinity set at process launch. @@ -135,6 +152,7 @@ bool GCToOSInterface::Initialize() } } } +#endif // FEATURE_PAL return true; } @@ -175,7 +193,7 @@ bool GCToOSInterface::SetCurrentThreadIdealAffinity(uint16_t srcProcNo, uint16_t LIMITED_METHOD_CONTRACT; bool success = true; - +#ifndef FEATURE_PAL GroupProcNo srcGroupProcNo(srcProcNo); GroupProcNo dstGroupProcNo(dstProcNo); @@ -202,7 +220,6 @@ bool GCToOSInterface::SetCurrentThreadIdealAffinity(uint16_t srcProcNo, uint16_t success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL); } -#if !defined(FEATURE_PAL) else { if (GetThreadIdealProcessorEx(GetCurrentThread(), &proc)) @@ -211,10 +228,13 @@ bool GCToOSInterface::SetCurrentThreadIdealAffinity(uint16_t srcProcNo, uint16_t success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, &proc); } } -#endif // !defined(FEATURE_PAL) -#endif - +#endif // !FEATURE_CORESYSTEM return success; + +#else // !FEATURE_PAL + return GCToOSInterface::SetThreadAffinity(dstProcNo); + +#endif // !FEATURE_PAL } // Get the number of the current processor @@ -472,7 +492,7 @@ size_t GCToOSInterface::GetCacheSizePerLogicalCpu(bool trueSize) bool GCToOSInterface::SetThreadAffinity(uint16_t procNo) { LIMITED_METHOD_CONTRACT; - +#ifndef FEATURE_PAL GroupProcNo groupProcNo(procNo); if (groupProcNo.GetGroup() != GroupProcNo::NoGroup) @@ -489,6 +509,9 @@ bool GCToOSInterface::SetThreadAffinity(uint16_t procNo) { return !!SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR)1 << groupProcNo.GetProcIndex()); } +#else // FEATURE_PAL + return PAL_SetCurrentThreadAffinity(procNo); +#endif // FEATURE_PAL } // Boosts the calling thread's thread priority to a level higher than the default @@ -510,7 +533,9 @@ bool GCToOSInterface::BoostThreadPriority() // set of enabled processors const AffinitySet* GCToOSInterface::SetGCThreadsAffinitySet(uintptr_t configAffinityMask, const AffinitySet* configAffinitySet) { +#ifndef FEATURE_PAL if (CPUGroupInfo::CanEnableGCCPUGroups()) +#endif // !FEATURE_PAL { if (!configAffinitySet->IsEmpty()) { @@ -524,6 +549,7 @@ const AffinitySet* GCToOSInterface::SetGCThreadsAffinitySet(uintptr_t configAffi } } } +#ifndef FEATURE_PAL else { if (configAffinityMask != 0) @@ -538,6 +564,7 @@ const AffinitySet* GCToOSInterface::SetGCThreadsAffinitySet(uintptr_t configAffi } } } +#endif // !FEATURE_PAL return &g_processAffinitySet; } @@ -549,10 +576,14 @@ uint32_t GCToOSInterface::GetCurrentProcessCpuCount() { LIMITED_METHOD_CONTRACT; +#ifndef FEATURE_PAL // GetCurrentProcessCpuCount only returns up to 64 procs. return CPUGroupInfo::CanEnableGCCPUGroups() ? GCToOSInterface::GetTotalProcessorCount(): ::GetCurrentProcessCpuCount(); +#else // !FEATURE_PAL + return g_currentProcessCpuCount; +#endif // !FEATURE_PAL } // Return the size of the user-mode portion of the virtual address space of this process. @@ -887,6 +918,7 @@ uint32_t GCToOSInterface::GetTotalProcessorCount() { LIMITED_METHOD_CONTRACT; +#ifndef FEATURE_PAL if (CPUGroupInfo::CanEnableGCCPUGroups()) { return CPUGroupInfo::GetNumActiveProcessors(); @@ -895,6 +927,9 @@ uint32_t GCToOSInterface::GetTotalProcessorCount() { return g_SystemInfo.dwNumberOfProcessors; } +#else // !FEATURE_PAL + return g_currentProcessCpuCount; +#endif // !FEATURE_PAL } bool GCToOSInterface::CanEnableGCNumaAware() @@ -904,20 +939,6 @@ bool GCToOSInterface::CanEnableGCNumaAware() return NumaNodeInfo::CanEnableGCNumaAware() != FALSE; } -bool GCToOSInterface::GetNumaProcessorNode(uint16_t proc_no, uint16_t *node_no) -{ - LIMITED_METHOD_CONTRACT; - - GroupProcNo groupProcNo(proc_no); - - PROCESSOR_NUMBER procNumber; - procNumber.Group = groupProcNo.GetGroup(); - procNumber.Number = (BYTE)groupProcNo.GetProcIndex(); - procNumber.Reserved = 0; - - return NumaNodeInfo::GetNumaProcessorNodeEx(&procNumber, node_no) != FALSE; -} - // Get processor number and optionally its NUMA node number for the specified heap number // Parameters: // heap_number - heap number to get the result for @@ -929,53 +950,76 @@ bool GCToOSInterface::GetProcessorForHeap(uint16_t heap_number, uint16_t* proc_n { bool success = false; - if (CPUGroupInfo::CanEnableGCCPUGroups()) + // Locate heap_number-th available processor + uint16_t procNumber; + size_t cnt = heap_number; + for (uint16_t i = 0; i < GCToOSInterface::GetTotalProcessorCount(); i++) { - uint16_t gn, gpn; - CPUGroupInfo::GetGroupForProcessor((uint16_t)heap_number, &gn, &gpn); + if (g_processAffinitySet.Contains(i)) + { + if (cnt == 0) + { + procNumber = i; + success = true; + break; + } + + cnt--; + } + } + + if (success) + { +#ifndef FEATURE_PAL + WORD gn, gpn; + + if (CPUGroupInfo::CanEnableGCCPUGroups()) + { + CPUGroupInfo::GetGroupForProcessor(procNumber, &gn, &gpn); + } + else + { + gn = GroupProcNo::NoGroup; + gpn = procNumber; + } + + GroupProcNo groupProcNo(gn, gpn); + *proc_no = groupProcNo.GetCombinedValue(); - *proc_no = GroupProcNo(gn, gpn).GetCombinedValue(); if (GCToOSInterface::CanEnableGCNumaAware()) { - if (!GCToOSInterface::GetNumaProcessorNode(*proc_no, node_no)) + PROCESSOR_NUMBER procNumber; + + if (CPUGroupInfo::CanEnableGCCPUGroups()) + { + procNumber.Group = gn; + } + else + { + // Get the current processor group + PROCESSOR_NUMBER procNumber; + GetCurrentProcessorNumberEx(&procNumber); + } + + procNumber.Number = (BYTE)gpn; + procNumber.Reserved = 0; + + if (NumaNodeInfo::GetNumaProcessorNodeEx(&procNumber, node_no)) { *node_no = NUMA_NODE_UNDEFINED; } } else { // no numa setting, each cpu group is treated as a node - *node_no = gn; + *node_no = groupProcNo.GetGroup(); } - - success = true; - } - else - { - int bit_number = 0; - uint8_t proc_number = 0; - for (uintptr_t mask = 1; mask != 0; mask <<= 1) +#else // !FEATURE_PAL + *proc_no = procNumber; + if (!GCToOSInterface::CanEnableGCNumaAware() || !NumaNodeInfo::GetNumaProcessorNodeEx(procNumber, (WORD*)node_no)) { - if (g_processAffinitySet.Contains(proc_number)) - { - if (bit_number == heap_number) - { - *proc_no = GroupProcNo(GroupProcNo::NoGroup, proc_number).GetCombinedValue(); - - if (GCToOSInterface::CanEnableGCNumaAware()) - { - if (!GCToOSInterface::GetNumaProcessorNode(proc_number, node_no)) - { - *node_no = NUMA_NODE_UNDEFINED; - } - } - - success = true; - break; - } - bit_number++; - } - proc_number++; + *node_no = NUMA_NODE_UNDEFINED; } +#endif // !FEATURE_PAL } return success; @@ -993,6 +1037,7 @@ bool GCToOSInterface::ParseGCHeapAffinitizeRangesEntry(const char** config_strin size_t index_offset = 0; char* number_end; +#ifndef FEATURE_PAL size_t group_number = strtoul(*config_string, &number_end, 10); if ((number_end == *config_string) || (*number_end != ':')) @@ -1011,6 +1056,7 @@ bool GCToOSInterface::ParseGCHeapAffinitizeRangesEntry(const char** config_strin index_offset = group_begin; *config_string = number_end + 1; +#endif // !FEATURE_PAL size_t start, end; if (!ParseIndexOrRange(config_string, &start, &end)) @@ -1018,11 +1064,13 @@ bool GCToOSInterface::ParseGCHeapAffinitizeRangesEntry(const char** config_strin return false; } +#ifndef FEATURE_PAL if ((start >= group_size) || (end >= group_size)) { // Invalid CPU index values or range return false; } +#endif // !FEATURE_PAL *start_index = index_offset + start; *end_index = index_offset + end; -- cgit v1.2.3