1// Copyright 2016 The Chromium Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/system/sys_info.h" 6 7#import <Foundation/Foundation.h> 8#include <mach/mach_host.h> 9#include <mach/mach_init.h> 10#include <stddef.h> 11#include <stdint.h> 12#include <sys/sysctl.h> 13#include <sys/types.h> 14 15#include "base/check_op.h" 16#include "base/feature_list.h" 17#include "base/mac/mac_util.h" 18#include "base/mac/scoped_mach_port.h" 19#include "base/notreached.h" 20#include "base/numerics/safe_conversions.h" 21#include "base/process/process_metrics.h" 22#include "base/strings/string_util.h" 23#include "base/strings/stringprintf.h" 24#include "base/system/sys_info_internal.h" 25#include "third_party/abseil-cpp/absl/types/optional.h" 26 27namespace base { 28 29namespace { 30 31bool g_is_cpu_security_mitigation_enabled = false; 32 33// Queries sysctlbyname() for the given key and returns the value from the 34// system or the empty string on failure. 35std::string GetSysctlStringValue(const char* key_name) { 36 char value[256]; 37 size_t len = sizeof(value); 38 if (sysctlbyname(key_name, &value, &len, nullptr, 0) != 0) 39 return std::string(); 40 DCHECK_GE(len, 1u); 41 DCHECK_LE(len, sizeof(value)); 42 DCHECK_EQ('\0', value[len - 1]); 43 return std::string(value, len - 1); 44} 45 46} // namespace 47 48namespace internal { 49 50absl::optional<int> NumberOfPhysicalProcessors() { 51 return GetSysctlIntValue("hw.physicalcpu_max"); 52} 53 54absl::optional<int> NumberOfProcessorsWhenCpuSecurityMitigationEnabled() { 55 if (!g_is_cpu_security_mitigation_enabled || 56 !FeatureList::IsEnabled(kNumberOfCoresWithCpuSecurityMitigation)) { 57 return absl::nullopt; 58 } 59 return NumberOfPhysicalProcessors(); 60} 61 62} // namespace internal 63 64BASE_FEATURE(kNumberOfCoresWithCpuSecurityMitigation, 65 "NumberOfCoresWithCpuSecurityMitigation", 66 FEATURE_DISABLED_BY_DEFAULT); 67 68// static 69std::string SysInfo::OperatingSystemName() { 70 return "Mac OS X"; 71} 72 73// static 74std::string SysInfo::OperatingSystemVersion() { 75 int32_t major, minor, bugfix; 76 OperatingSystemVersionNumbers(&major, &minor, &bugfix); 77 return base::StringPrintf("%d.%d.%d", major, minor, bugfix); 78} 79 80// static 81void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version, 82 int32_t* minor_version, 83 int32_t* bugfix_version) { 84 NSOperatingSystemVersion version = 85 [[NSProcessInfo processInfo] operatingSystemVersion]; 86 *major_version = saturated_cast<int32_t>(version.majorVersion); 87 *minor_version = saturated_cast<int32_t>(version.minorVersion); 88 *bugfix_version = saturated_cast<int32_t>(version.patchVersion); 89} 90 91// static 92std::string SysInfo::OperatingSystemArchitecture() { 93 switch (mac::GetCPUType()) { 94 case mac::CPUType::kIntel: 95 return "x86_64"; 96 case mac::CPUType::kTranslatedIntel: 97 case mac::CPUType::kArm: 98 return "arm64"; 99 } 100} 101 102// static 103uint64_t SysInfo::AmountOfPhysicalMemoryImpl() { 104 struct host_basic_info hostinfo; 105 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; 106 base::mac::ScopedMachSendRight host(mach_host_self()); 107 int result = host_info(host.get(), HOST_BASIC_INFO, 108 reinterpret_cast<host_info_t>(&hostinfo), &count); 109 if (result != KERN_SUCCESS) { 110 NOTREACHED(); 111 return 0; 112 } 113 DCHECK_EQ(HOST_BASIC_INFO_COUNT, count); 114 return hostinfo.max_mem; 115} 116 117// static 118uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() { 119 SystemMemoryInfoKB info; 120 if (!GetSystemMemoryInfo(&info)) 121 return 0; 122 // We should add inactive file-backed memory also but there is no such 123 // information from Mac OS unfortunately. 124 return checked_cast<uint64_t>(info.free + info.speculative) * 1024; 125} 126 127// static 128std::string SysInfo::CPUModelName() { 129 return GetSysctlStringValue("machdep.cpu.brand_string"); 130} 131 132// static 133std::string SysInfo::HardwareModelName() { 134 return GetSysctlStringValue("hw.model"); 135} 136 137// static 138SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() { 139 HardwareInfo info; 140 info.manufacturer = "Apple Inc."; 141 info.model = HardwareModelName(); 142 DCHECK(IsStringUTF8(info.manufacturer)); 143 DCHECK(IsStringUTF8(info.model)); 144 return info; 145} 146 147// static 148void SysInfo::SetIsCpuSecurityMitigationsEnabled(bool is_enabled) { 149 g_is_cpu_security_mitigation_enabled = is_enabled; 150} 151 152} // namespace base 153