Cygwin: cpuinfo: Use active CPU count per group

There are systems with a MaximumProcessorCount not
reflecting the actually available CPUs.  The ActiveProcessorCount
is correct though.  So we use ActiveProcessorCount rather than
MaximumProcessorCount per group to set group affinity correctly.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2018-04-11 12:45:57 +02:00
parent 92f4e0500b
commit cef1070bcb
1 changed files with 36 additions and 20 deletions

View File

@ -639,32 +639,48 @@ format_proc_cpuinfo (void *, char *&destbuf)
char *buf = tp.c_get (); char *buf = tp.c_get ();
char *bufptr = buf; char *bufptr = buf;
DWORD lpi_size = NT_MAX_PATH;
//WORD num_cpu_groups = 1; /* Pre Windows 7, only one group... */ //WORD num_cpu_groups = 1; /* Pre Windows 7, only one group... */
WORD num_cpu_per_group = 64; /* ...and a max of 64 CPUs. */ WORD num_cpu_per_group = 64; /* ...and a max of 64 CPUs. */
if (wincap.has_processor_groups ()) PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi =
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) tp.c_get ();
DWORD lpi_size = NT_MAX_PATH;
/* Fake a SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX group info block on Vista
systems. This may be over the top but if the below code just using
ActiveProcessorCount turns out to be insufficient, we can build on that. */
if (!wincap.has_processor_groups ()
|| !GetLogicalProcessorInformationEx (RelationGroup, lpi, &lpi_size))
{ {
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi = lpi_size = sizeof *lpi;
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) tp.c_get (); lpi->Relationship = RelationGroup;
lpi_size = NT_MAX_PATH; lpi->Size = lpi_size;
if (!GetLogicalProcessorInformationEx (RelationGroup, lpi, &lpi_size)) lpi->Group.MaximumGroupCount = 1;
lpi = NULL; lpi->Group.ActiveGroupCount = 1;
else lpi->Group.GroupInfo[0].MaximumProcessorCount = wincap.cpu_count ();
{ lpi->Group.GroupInfo[0].ActiveProcessorCount
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX plpi = lpi; = __builtin_popcountl (wincap.cpu_mask ());
for (DWORD size = lpi_size; size > 0; lpi->Group.GroupInfo[0].ActiveProcessorMask = wincap.cpu_mask ();
size -= plpi->Size, add_size (plpi, plpi->Size))
if (plpi->Relationship == RelationGroup)
{
//num_cpu_groups = plpi->Group.MaximumGroupCount;
num_cpu_per_group
= plpi->Group.GroupInfo[0].MaximumProcessorCount;
break;
}
}
} }
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX plpi = lpi;
for (DWORD size = lpi_size; size > 0;
size -= plpi->Size, add_size (plpi, plpi->Size))
if (plpi->Relationship == RelationGroup)
{
//num_cpu_groups = plpi->Group.MaximumGroupCount;
/* Turns out, there are systems with a MaximumProcessorCount not
reflecting the actually available CPUs. The ActiveProcessorCount
is correct though. So we just use ActiveProcessorCount for now,
hoping the best. If it turns out that we have to handle more
complex CPU layouts with weird ActiveProcessorMasks, we can
do that by restructuring the subsequent CPU loop. */
num_cpu_per_group
= plpi->Group.GroupInfo[0].ActiveProcessorCount;
break;
}
cpu_num_p = wcpcpy (cpu_key, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION" cpu_num_p = wcpcpy (cpu_key, L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION"
"\\System\\CentralProcessor\\"); "\\System\\CentralProcessor\\");
for (cpu_number = 0; ; cpu_number++) for (cpu_number = 0; ; cpu_number++)