Skip to content

Commit ee11e80

Browse files
anematodePikaCat-OuO
authored andcommitted
Fix RelationCache on Windows 10 compiles
Windows 10 is missing the GroupMasks and GroupCount members, this breaks compiles on Windows 10. Windows 11 builds, including the official ones, run fine on Windows 10/11. To support developers/testers on Windows 10, fallback conditionally to the Windows 10 struct definition. No functional change
1 parent 2a453b4 commit ee11e80

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

src/numa.h

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,50 @@ inline WindowsAffinity get_process_affinity() {
371371
return affinity;
372372
}
373373

374+
// Type machinery used to emulate Cache->GroupCount
375+
376+
template<typename T, typename = void>
377+
struct HasGroupCount: std::false_type {};
378+
379+
template<typename T>
380+
struct HasGroupCount<T, std::void_t<decltype(std::declval<T>().Cache.GroupCount)>>: std::true_type {
381+
};
382+
383+
template<typename T, typename Pred, std::enable_if_t<HasGroupCount<T>::value, bool> = true>
384+
std::set<CpuIndex> readCacheMembers(const T* info, Pred&& is_cpu_allowed) {
385+
std::set<CpuIndex> cpus;
386+
// On Windows 10 this will read a 0 because GroupCount doesn't exist
387+
int groupCount = std::max(info->Cache.GroupCount, WORD(1));
388+
for (WORD procGroup = 0; procGroup < groupCount; ++procGroup)
389+
{
390+
for (BYTE number = 0; number < WIN_PROCESSOR_GROUP_SIZE; ++number)
391+
{
392+
WORD groupNumber = info->Cache.GroupMasks[procGroup].Group;
393+
const CpuIndex c = static_cast<CpuIndex>(groupNumber) * WIN_PROCESSOR_GROUP_SIZE
394+
+ static_cast<CpuIndex>(number);
395+
if (!(info->Cache.GroupMasks[procGroup].Mask & (1ULL << number)) || !is_cpu_allowed(c))
396+
continue;
397+
cpus.insert(c);
398+
}
399+
}
400+
return cpus;
401+
}
402+
403+
template<typename T, typename Pred, std::enable_if_t<!HasGroupCount<T>::value, bool> = true>
404+
std::set<CpuIndex> readCacheMembers(const T* info, Pred&& is_cpu_allowed) {
405+
std::set<CpuIndex> cpus;
406+
for (BYTE number = 0; number < WIN_PROCESSOR_GROUP_SIZE; ++number)
407+
{
408+
WORD groupNumber = info->Cache.GroupMask.Group;
409+
const CpuIndex c = static_cast<CpuIndex>(groupNumber) * WIN_PROCESSOR_GROUP_SIZE
410+
+ static_cast<CpuIndex>(number);
411+
if (!(info->Cache.GroupMask.Mask & (1ULL << number)) || !is_cpu_allowed(c))
412+
continue;
413+
cpus.insert(c);
414+
}
415+
return cpus;
416+
}
417+
374418
#endif
375419

376420
#if defined(__linux__) && !defined(__ANDROID__)
@@ -1174,29 +1218,17 @@ class NumaConfig {
11741218
if (info->Relationship == RelationCache && info->Cache.Level == 3)
11751219
{
11761220
L3Domain domain{};
1177-
for (WORD procGroup = 0; procGroup < info->Cache.GroupCount; ++procGroup)
1178-
{
1179-
for (BYTE number = 0; number < WIN_PROCESSOR_GROUP_SIZE; ++number)
1180-
{
1181-
WORD groupNumber = info->Cache.GroupMasks[procGroup].Group;
1182-
const CpuIndex c =
1183-
static_cast<CpuIndex>(groupNumber) * WIN_PROCESSOR_GROUP_SIZE
1184-
+ static_cast<CpuIndex>(number);
1185-
if (!(info->Cache.GroupMasks[procGroup].Mask & (1ULL << number))
1186-
|| !is_cpu_allowed(c))
1187-
continue;
1188-
domain.systemNumaIndex = systemConfig.nodeByCpu.at(c);
1189-
domain.cpus.insert(c);
1190-
}
1191-
}
1221+
domain.cpus = readCacheMembers(info, is_cpu_allowed);
11921222
if (!domain.cpus.empty())
1223+
{
1224+
domain.systemNumaIndex = systemConfig.nodeByCpu.at(*domain.cpus.begin());
11931225
l3Domains.push_back(std::move(domain));
1226+
}
11941227
}
11951228
// Variable length data structure, advance to next
11961229
info = reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(
11971230
reinterpret_cast<char*>(info) + info->Size);
11981231
}
1199-
12001232
#endif
12011233

12021234
if (!l3Domains.empty())

0 commit comments

Comments
 (0)