diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2018-08-07 15:51:10 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2018-08-07 15:51:10 +0300 |
commit | 1e0a1f59d9e64430ce796c578e0813100c0cf0d7 (patch) | |
tree | dda23756b72c4ee6cf58b0b3a51f95fb8691767b /winsup/cygwin/miscfuncs.cc | |
parent | c233d42264846f11e1d99b6664c8394b3ff32a78 (diff) |
Cygwin: implement sched_getcpu
* create new function __get_cpus_per_group to evaluate # of CPU groups
* Call from format_proc_cpuinfo and sched_getcpu
* Bump API minor version
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/miscfuncs.cc')
-rw-r--r-- | winsup/cygwin/miscfuncs.cc | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 3ad658739..b5dfffc7d 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -15,6 +15,7 @@ details. */ #include "path.h" #include "fhandler.h" #include "exception.h" +#include "tls_pbuf.h" int __reg2 check_invalid_virtual_addr (const void *s, unsigned sz) @@ -959,3 +960,55 @@ SetThreadName(DWORD dwThreadID, const char* threadName) __except (NO_ERROR) __endtry } + +#define add_size(p,s) ((p) = ((__typeof__(p))((PBYTE)(p)+(s)))) + +WORD +__get_cpus_per_group (void) +{ + static WORD num_cpu_per_group = 0; + + tmp_pathbuf tp; + + if (num_cpu_per_group) + return num_cpu_per_group; + + num_cpu_per_group = 64; + + 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)) + { + lpi_size = sizeof *lpi; + lpi->Relationship = RelationGroup; + lpi->Size = lpi_size; + lpi->Group.MaximumGroupCount = 1; + lpi->Group.ActiveGroupCount = 1; + lpi->Group.GroupInfo[0].MaximumProcessorCount = wincap.cpu_count (); + lpi->Group.GroupInfo[0].ActiveProcessorCount + = __builtin_popcountl (wincap.cpu_mask ()); + lpi->Group.GroupInfo[0].ActiveProcessorMask = wincap.cpu_mask (); + } + + 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) + { + /* 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 for + the best. */ + num_cpu_per_group + = plpi->Group.GroupInfo[0].ActiveProcessorCount; + break; + } + + return num_cpu_per_group; +} |