diff options
Diffstat (limited to 'webrtc/base/systeminfo.cc')
-rw-r--r-- | webrtc/base/systeminfo.cc | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/webrtc/base/systeminfo.cc b/webrtc/base/systeminfo.cc new file mode 100644 index 0000000000..bfc96b3763 --- /dev/null +++ b/webrtc/base/systeminfo.cc @@ -0,0 +1,213 @@ +/* + * Copyright 2008 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/base/systeminfo.h" + +#if defined(WEBRTC_WIN) +#include <winsock2.h> +#include <windows.h> +#ifndef EXCLUDE_D3D9 +#include <d3d9.h> +#endif +#include <intrin.h> // for __cpuid() +#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) +#include <ApplicationServices/ApplicationServices.h> +#include <CoreServices/CoreServices.h> +#elif defined(WEBRTC_LINUX) +#include <unistd.h> +#endif +#if defined(WEBRTC_MAC) +#include <sys/sysctl.h> +#endif + +#include "webrtc/base/common.h" +#include "webrtc/base/logging.h" +#include "webrtc/base/stringutils.h" + +namespace rtc { + +// See Also: http://msdn.microsoft.com/en-us/library/ms683194(v=vs.85).aspx +#if !defined(WEBRTC_WIN) +// TODO(fbarchard): Use gcc 4.4 provided cpuid intrinsic +// 32 bit fpic requires ebx be preserved +#if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__) +static inline void __cpuid(int cpu_info[4], int info_type) { + __asm__ volatile ( // NOLINT + "mov %%ebx, %%edi\n" + "cpuid\n" + "xchg %%edi, %%ebx\n" + : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "a"(info_type) + ); // NOLINT +} +#elif defined(__i386__) || defined(__x86_64__) +static inline void __cpuid(int cpu_info[4], int info_type) { + __asm__ volatile ( // NOLINT + "cpuid\n" + : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "a"(info_type) + ); // NOLINT +} +#endif +#endif // WEBRTC_WIN + +static int DetectNumberOfCores() { + // We fall back on assuming a single core in case of errors. + int number_of_cores = 1; + +#if defined(WEBRTC_WIN) + SYSTEM_INFO si; + GetSystemInfo(&si); + number_of_cores = static_cast<int>(si.dwNumberOfProcessors); +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) + number_of_cores = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN)); +#elif defined(WEBRTC_MAC) + int name[] = {CTL_HW, HW_AVAILCPU}; + size_t size = sizeof(number_of_cores); + if (0 != sysctl(name, 2, &number_of_cores, &size, NULL, 0)) { + LOG(LS_ERROR) << "Failed to get number of cores"; + number_of_cores = 1; + } +#else + LOG(LS_ERROR) << "No function to get number of cores"; +#endif + + LOG(LS_INFO) << "Available number of cores: " << number_of_cores; + + return number_of_cores; +} + +// Statically cache the number of system cores available since if the process +// is running in a sandbox, we may only be able to read the value once (before +// the sandbox is initialized) and not thereafter. +// For more information see crbug.com/176522. +int SystemInfo::logical_cpus_ = 0; + +SystemInfo::SystemInfo() { +} + +// Return the number of cpu threads available to the system. +// static +int SystemInfo::GetMaxCpus() { + if (!logical_cpus_) + logical_cpus_ = DetectNumberOfCores(); + return logical_cpus_; +} + +// Return the number of cpus available to the process. Since affinity can be +// changed on the fly, do not cache this value. +// Can be affected by heat. +int SystemInfo::GetCurCpus() { + int cur_cpus = 0; +#if defined(WEBRTC_WIN) + DWORD_PTR process_mask = 0; + DWORD_PTR system_mask = 0; + ::GetProcessAffinityMask(::GetCurrentProcess(), &process_mask, &system_mask); + for (int i = 0; i < sizeof(DWORD_PTR) * 8; ++i) { + if (process_mask & 1) + ++cur_cpus; + process_mask >>= 1; + } +#elif defined(WEBRTC_MAC) + uint32_t sysctl_value; + size_t length = sizeof(sysctl_value); + int error = sysctlbyname("hw.ncpu", &sysctl_value, &length, NULL, 0); + cur_cpus = !error ? static_cast<int>(sysctl_value) : 1; +#else + // Linux, Solaris, WEBRTC_ANDROID + cur_cpus = GetMaxCpus(); +#endif + return cur_cpus; +} + +// Return the type of this CPU. +SystemInfo::Architecture SystemInfo::GetCpuArchitecture() { +#if defined(__arm__) || defined(_M_ARM) + return SI_ARCH_ARM; +#elif defined(__x86_64__) || defined(_M_X64) + return SI_ARCH_X64; +#elif defined(__i386__) || defined(_M_IX86) + return SI_ARCH_X86; +#else + return SI_ARCH_UNKNOWN; +#endif +} + +// Returns the vendor string from the cpu, e.g. "GenuineIntel", "AuthenticAMD". +// See "Intel Processor Identification and the CPUID Instruction" +// (Intel document number: 241618) +std::string SystemInfo::GetCpuVendor() { +#if defined(CPU_X86) + int cpu_info[4]; + __cpuid(cpu_info, 0); + cpu_info[0] = cpu_info[1]; // Reorder output + cpu_info[1] = cpu_info[3]; + // cpu_info[2] = cpu_info[2]; // Avoid -Werror=self-assign + cpu_info[3] = 0; + return std::string(reinterpret_cast<char*>(&cpu_info[0])); +#elif defined(CPU_ARM) + return "ARM"; +#else + return "Undefined"; +#endif +} + +// Returns the amount of installed physical memory in Bytes. Cacheable. +// Returns -1 on error. +int64_t SystemInfo::GetMemorySize() { + int64_t memory = -1; + +#if defined(WEBRTC_WIN) + MEMORYSTATUSEX status = {0}; + status.dwLength = sizeof(status); + + if (GlobalMemoryStatusEx(&status)) { + memory = status.ullTotalPhys; + } else { + LOG_GLE(LS_WARNING) << "GlobalMemoryStatusEx failed."; + } + +#elif defined(WEBRTC_MAC) + size_t len = sizeof(memory); + int error = sysctlbyname("hw.memsize", &memory, &len, NULL, 0); + if (error || memory == 0) + memory = -1; +#elif defined(WEBRTC_LINUX) + memory = static_cast<int64_t>(sysconf(_SC_PHYS_PAGES)) * + static_cast<int64_t>(sysconf(_SC_PAGESIZE)); + if (memory < 0) { + LOG(LS_WARNING) << "sysconf(_SC_PHYS_PAGES) failed." + << "sysconf(_SC_PHYS_PAGES) " << sysconf(_SC_PHYS_PAGES) + << "sysconf(_SC_PAGESIZE) " << sysconf(_SC_PAGESIZE); + memory = -1; + } +#endif + + return memory; +} + +// Return the name of the machine model we are currently running on. +// This is a human readable string that consists of the name and version +// number of the hardware, i.e 'MacBookAir1,1'. Returns an empty string if +// model can not be determined. +std::string SystemInfo::GetMachineModel() { +#if defined(WEBRTC_MAC) + char buffer[128]; + size_t length = sizeof(buffer); + int error = sysctlbyname("hw.model", buffer, &length, NULL, 0); + if (!error) + return std::string(buffer, length - 1); + return std::string(); +#else + return "Not available"; +#endif +} + +} // namespace rtc |