From ffb865f3e05fcba0c24baab27201ce2414b5430c Mon Sep 17 00:00:00 2001 From: skvlad Date: Fri, 16 Dec 2016 16:48:28 -0800 Subject: [PATCH] Revert of Delete unused code from systeminfo. (patchset #3 id:40001 of https://codereview.webrtc.org/2578323005/ ) Reason for revert: Breaks downstream build. Original issue's description: > Delete unused code from systeminfo. > > BUG=webrtc:6906 > > Review-Url: https://codereview.webrtc.org/2578323005 > Cr-Commit-Position: refs/heads/master@{#15655} > Committed: https://chromium.googlesource.com/external/webrtc/+/617ca316e9363986a54926a185fac799de3869c2 TBR=perkj@webrtc.org,kthelgason@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:6906 Review-Url: https://codereview.webrtc.org/2584563004 . Cr-Commit-Position: refs/heads/master@{#15660} --- webrtc/BUILD.gn | 3 + webrtc/base/BUILD.gn | 2 + webrtc/base/systeminfo.cc | 213 ++++++++++++++++++++++ webrtc/base/systeminfo.h | 49 +++++ webrtc/base/systeminfo_unittest.cc | 150 +++++++++++++++ webrtc/media/base/videocapturer.cc | 1 + webrtc/system_wrappers/source/cpu_info.cc | 52 +----- 7 files changed, 420 insertions(+), 50 deletions(-) create mode 100644 webrtc/base/systeminfo.cc create mode 100644 webrtc/base/systeminfo.h create mode 100644 webrtc/base/systeminfo_unittest.cc diff --git a/webrtc/BUILD.gn b/webrtc/BUILD.gn index b625d19418..064b1b440b 100644 --- a/webrtc/BUILD.gn +++ b/webrtc/BUILD.gn @@ -428,6 +428,9 @@ if (rtc_include_tests) { "base/stringencode_unittest.cc", "base/stringutils_unittest.cc", "base/swap_queue_unittest.cc", + + # TODO(ronghuawu): Reenable this test. + # "systeminfo_unittest.cc", "base/task_queue_unittest.cc", "base/task_unittest.cc", "base/testclient_unittest.cc", diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index 171878ae8e..b46e4c2a79 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -170,6 +170,8 @@ rtc_static_library("rtc_base_approved") { "stringutils.cc", "stringutils.h", "swap_queue.h", + "systeminfo.cc", + "systeminfo.h", "template_util.h", "thread_annotations.h", "thread_checker.h", diff --git a/webrtc/base/systeminfo.cc b/webrtc/base/systeminfo.cc new file mode 100644 index 0000000000..b400aa08a8 --- /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 +#include +#ifndef EXCLUDE_D3D9 +#include +#endif +#include // for __cpuid() +#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) +#include +#include +#elif defined(WEBRTC_LINUX) +#include +#endif +#if defined(WEBRTC_MAC) +#include +#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(si.dwNumberOfProcessors); +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) + number_of_cores = static_cast(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 (size_t 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(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(&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(sysconf(_SC_PHYS_PAGES)) * + static_cast(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 diff --git a/webrtc/base/systeminfo.h b/webrtc/base/systeminfo.h new file mode 100644 index 0000000000..99d18b2960 --- /dev/null +++ b/webrtc/base/systeminfo.h @@ -0,0 +1,49 @@ +/* + * 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. + */ + +#ifndef WEBRTC_BASE_SYSTEMINFO_H__ +#define WEBRTC_BASE_SYSTEMINFO_H__ + +#include + +#include "webrtc/base/basictypes.h" + +namespace rtc { + +class SystemInfo { + public: + enum Architecture { + SI_ARCH_UNKNOWN = -1, + SI_ARCH_X86 = 0, + SI_ARCH_X64 = 1, + SI_ARCH_ARM = 2 + }; + + SystemInfo(); + + // The number of CPU Threads in the system. + static int GetMaxCpus(); + // The number of CPU Threads currently available to this process. + static int GetCurCpus(); + // Identity of the CPUs. + Architecture GetCpuArchitecture(); + std::string GetCpuVendor(); + // Total amount of physical memory, in bytes. + int64_t GetMemorySize(); + // The model name of the machine, e.g. "MacBookAir1,1" + std::string GetMachineModel(); + + private: + static int logical_cpus_; +}; + +} // namespace rtc + +#endif // WEBRTC_BASE_SYSTEMINFO_H__ diff --git a/webrtc/base/systeminfo_unittest.cc b/webrtc/base/systeminfo_unittest.cc new file mode 100644 index 0000000000..b1fc65e091 --- /dev/null +++ b/webrtc/base/systeminfo_unittest.cc @@ -0,0 +1,150 @@ +/* + * Copyright 2009 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/gunit.h" +#include "webrtc/base/stringutils.h" +#include "webrtc/base/systeminfo.h" + +#if defined(CPU_X86) || defined(CPU_ARM) +TEST(SystemInfoTest, CpuVendorNonEmpty) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuVendor: " << info.GetCpuVendor(); + EXPECT_FALSE(info.GetCpuVendor().empty()); +} + +// Tests Vendor identification is Intel or AMD. +// See Also http://en.wikipedia.org/wiki/CPUID +TEST(SystemInfoTest, CpuVendorIntelAMDARM) { + rtc::SystemInfo info; +#if defined(CPU_X86) + EXPECT_TRUE(rtc::string_match(info.GetCpuVendor().c_str(), + "GenuineIntel") || + rtc::string_match(info.GetCpuVendor().c_str(), + "AuthenticAMD")); +#elif defined(CPU_ARM) + EXPECT_TRUE(rtc::string_match(info.GetCpuVendor().c_str(), "ARM")); +#endif +} +#endif // defined(CPU_X86) || defined(CPU_ARM) + +// Tests CpuArchitecture matches expectations. +TEST(SystemInfoTest, GetCpuArchitecture) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuArchitecture: " << info.GetCpuArchitecture(); + rtc::SystemInfo::Architecture architecture = info.GetCpuArchitecture(); +#if defined(CPU_X86) || defined(CPU_ARM) + if (sizeof(intptr_t) == 8) { + EXPECT_EQ(rtc::SystemInfo::SI_ARCH_X64, architecture); + } else if (sizeof(intptr_t) == 4) { +#if defined(CPU_ARM) + EXPECT_EQ(rtc::SystemInfo::SI_ARCH_ARM, architecture); +#else + EXPECT_EQ(rtc::SystemInfo::SI_ARCH_X86, architecture); +#endif + } +#endif +} + +// Tests MachineModel is set. On Mac test machine model is known. +TEST(SystemInfoTest, MachineModelKnown) { + rtc::SystemInfo info; + EXPECT_FALSE(info.GetMachineModel().empty()); + const char *machine_model = info.GetMachineModel().c_str(); + LOG(LS_INFO) << "MachineModel: " << machine_model; + bool known = true; +#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) + // Full list as of May 2012. Update when new OSX based models are added. + known = rtc::string_match(machine_model, "MacBookPro*") || + rtc::string_match(machine_model, "MacBookAir*") || + rtc::string_match(machine_model, "MacBook*") || + rtc::string_match(machine_model, "MacPro*") || + rtc::string_match(machine_model, "Macmini*") || + rtc::string_match(machine_model, "iMac*") || + rtc::string_match(machine_model, "Xserve*"); +#elif !defined(WEBRTC_IOS) + // All other machines return Not available. + known = rtc::string_match(info.GetMachineModel().c_str(), + "Not available"); +#endif + if (!known) { + LOG(LS_WARNING) << "Machine Model Unknown: " << machine_model; + } +} + +// Tests physical memory size. +TEST(SystemInfoTest, MemorySize) { + rtc::SystemInfo info; + LOG(LS_INFO) << "MemorySize: " << info.GetMemorySize(); + EXPECT_GT(info.GetMemorySize(), -1); +} + +// Tests number of logical cpus available to the system. +TEST(SystemInfoTest, MaxCpus) { + rtc::SystemInfo info; + LOG(LS_INFO) << "MaxCpus: " << info.GetMaxCpus(); + EXPECT_GT(info.GetMaxCpus(), 0); +} + +// Tests number of logical cpus available to the process. +TEST(SystemInfoTest, CurCpus) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CurCpus: " << info.GetCurCpus(); + EXPECT_GT(info.GetCurCpus(), 0); + EXPECT_LE(info.GetCurCpus(), info.GetMaxCpus()); +} + +#ifdef CPU_X86 +// CPU family/model/stepping is only available on X86. The following tests +// that they are set when running on x86 CPUs. Valid Family/Model/Stepping +// values are non-zero on known CPUs. + +// Tests Intel CPU Family identification. +TEST(SystemInfoTest, CpuFamily) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuFamily: " << info.GetCpuFamily(); + EXPECT_GT(info.GetCpuFamily(), 0); +} + +// Tests Intel CPU Model identification. +TEST(SystemInfoTest, CpuModel) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuModel: " << info.GetCpuModel(); + EXPECT_GT(info.GetCpuModel(), 0); +} + +// Tests Intel CPU Stepping identification. +TEST(SystemInfoTest, CpuStepping) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuStepping: " << info.GetCpuStepping(); + EXPECT_GT(info.GetCpuStepping(), 0); +} +#else // CPU_X86 +// If not running on x86 CPU the following tests expect the functions to +// return 0. +TEST(SystemInfoTest, CpuFamily) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuFamily: " << info.GetCpuFamily(); + EXPECT_EQ(0, info.GetCpuFamily()); +} + +// Tests Intel CPU Model identification. +TEST(SystemInfoTest, CpuModel) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuModel: " << info.GetCpuModel(); + EXPECT_EQ(0, info.GetCpuModel()); +} + +// Tests Intel CPU Stepping identification. +TEST(SystemInfoTest, CpuStepping) { + rtc::SystemInfo info; + LOG(LS_INFO) << "CpuStepping: " << info.GetCpuStepping(); + EXPECT_EQ(0, info.GetCpuStepping()); +} +#endif // CPU_X86 diff --git a/webrtc/media/base/videocapturer.cc b/webrtc/media/base/videocapturer.cc index ced48a575e..d129557bce 100644 --- a/webrtc/media/base/videocapturer.cc +++ b/webrtc/media/base/videocapturer.cc @@ -16,6 +16,7 @@ #include "webrtc/base/common.h" #include "webrtc/base/logging.h" +#include "webrtc/base/systeminfo.h" #include "webrtc/video_frame.h" namespace cricket { diff --git a/webrtc/system_wrappers/source/cpu_info.cc b/webrtc/system_wrappers/source/cpu_info.cc index 4a61c7a6f3..40231b65af 100644 --- a/webrtc/system_wrappers/source/cpu_info.cc +++ b/webrtc/system_wrappers/source/cpu_info.cc @@ -10,60 +10,12 @@ #include "webrtc/system_wrappers/include/cpu_info.h" -#if defined(WEBRTC_WIN) -#include -#include -#ifndef EXCLUDE_D3D9 -#include -#endif -#elif defined(WEBRTC_LINUX) -#include -#endif -#if defined(WEBRTC_MAC) -#include -#endif - -#include "webrtc/base/logging.h" - -namespace internal { -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(si.dwNumberOfProcessors); -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) - number_of_cores = static_cast(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; -} -} +#include "webrtc/base/systeminfo.h" namespace webrtc { uint32_t CpuInfo::DetectNumberOfCores() { - // 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. - static uint32_t logical_cpus = 0; - if (!logical_cpus) - logical_cpus = static_cast(internal::DetectNumberOfCores()); - return logical_cpus; + return static_cast(rtc::SystemInfo::GetMaxCpus()); } } // namespace webrtc