diff options
author | Abseil Team <absl-team@google.com> | 2021-04-13 10:34:23 -0700 |
---|---|---|
committer | Dino Radaković <dinor@google.com> | 2021-04-13 16:57:41 -0700 |
commit | 25bc82d7ef481bd06723aae805d286eba81900ca (patch) | |
tree | c3a878e5cbd2f8426cbc43ffad8c1f0655cd34a5 /absl/base | |
parent | b97a1ecda869ca8754d467a56c50275cebfeb328 (diff) |
Export of internal Abseil changes
--
f09549625d7417fca379ff68334379d281480608 by Martijn Vels <mvels@google.com>:
Fix GetNumCPUs() for WIN32 platforms
PiperOrigin-RevId: 368245360
--
e903c6690d0568f80356e03b07a895b031553977 by Abseil Team <absl-team@google.com>:
Optimize `Cord::InlineRep::InlineRep(Cord::InlineRep&& src)`.
PiperOrigin-RevId: 368198990
GitOrigin-RevId: f09549625d7417fca379ff68334379d281480608
Change-Id: I2d750c8c87f2804335a60ba8db949dedfaa462e2
Diffstat (limited to 'absl/base')
-rw-r--r-- | absl/base/internal/sysinfo.cc | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index 4a3b2050..08a1e288 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -61,9 +61,76 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace base_internal { +namespace { + +#if defined(_WIN32) + +// Returns number of bits set in `bitMask` +DWORD Win32CountSetBits(ULONG_PTR bitMask) { + for (DWORD bitSetCount = 0; ; ++bitSetCount) { + if (bitMask == 0) return bitSetCount; + bitMask &= bitMask - 1; + } +} + +// Returns the number of logical CPUs using GetLogicalProcessorInformation(), or +// 0 if the number of processors is not available or can not be computed. +// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation +int Win32NumCPUs() { +#pragma comment(lib, "kernel32.lib") + using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; + + DWORD info_size = sizeof(Info); + Info* info(static_cast<Info*>(malloc(info_size))); + if (info == nullptr) return 0; + + bool success = GetLogicalProcessorInformation(info, &info_size); + if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + free(info); + info = static_cast<Info*>(malloc(info_size)); + if (info == nullptr) return 0; + success = GetLogicalProcessorInformation(info, &info_size); + } + + DWORD logicalProcessorCount = 0; + if (success) { + Info* ptr = info; + DWORD byteOffset = 0; + while (byteOffset + sizeof(Info) <= info_size) { + switch (ptr->Relationship) { + case RelationProcessorCore: + logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask); + break; + + case RelationNumaNode: + case RelationCache: + case RelationProcessorPackage: + // Ignore other entries + break; + + default: + // Ignore unknown entries + break; + } + byteOffset += sizeof(Info); + ptr++; + } + } + free(info); + return logicalProcessorCount; +} + +#endif + +} // namespace + + static int GetNumCPUs() { #if defined(__myriad2__) return 1; +#elif defined(_WIN32) + const unsigned hardware_concurrency = Win32NumCPUs(); + return hardware_concurrency ? hardware_concurrency : 1; #else // Other possibilities: // - Read /sys/devices/system/cpu/online and use cpumask_parse() |