aboutsummaryrefslogtreecommitdiff
path: root/webrtc/base/systeminfo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/base/systeminfo.cc')
-rw-r--r--webrtc/base/systeminfo.cc213
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