xref: /aosp_15_r20/external/cronet/base/system/sys_info_mac.mm (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker// Copyright 2016 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker// found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker#include "base/system/sys_info.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker#import <Foundation/Foundation.h>
8*6777b538SAndroid Build Coastguard Worker#include <mach/mach_host.h>
9*6777b538SAndroid Build Coastguard Worker#include <mach/mach_init.h>
10*6777b538SAndroid Build Coastguard Worker#include <stddef.h>
11*6777b538SAndroid Build Coastguard Worker#include <stdint.h>
12*6777b538SAndroid Build Coastguard Worker#include <sys/sysctl.h>
13*6777b538SAndroid Build Coastguard Worker#include <sys/types.h>
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker#include <optional>
16*6777b538SAndroid Build Coastguard Worker#include <string_view>
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker#include "base/apple/scoped_mach_port.h"
19*6777b538SAndroid Build Coastguard Worker#include "base/check_op.h"
20*6777b538SAndroid Build Coastguard Worker#include "base/debug/stack_trace.h"
21*6777b538SAndroid Build Coastguard Worker#include "base/feature_list.h"
22*6777b538SAndroid Build Coastguard Worker#include "base/mac/mac_util.h"
23*6777b538SAndroid Build Coastguard Worker#include "base/no_destructor.h"
24*6777b538SAndroid Build Coastguard Worker#include "base/notreached.h"
25*6777b538SAndroid Build Coastguard Worker#include "base/numerics/safe_conversions.h"
26*6777b538SAndroid Build Coastguard Worker#include "base/posix/sysctl.h"
27*6777b538SAndroid Build Coastguard Worker#include "base/process/process_metrics.h"
28*6777b538SAndroid Build Coastguard Worker#include "base/strings/string_number_conversions.h"
29*6777b538SAndroid Build Coastguard Worker#include "base/strings/string_util.h"
30*6777b538SAndroid Build Coastguard Worker#include "base/strings/stringprintf.h"
31*6777b538SAndroid Build Coastguard Worker#include "base/synchronization/lock.h"
32*6777b538SAndroid Build Coastguard Worker#include "base/system/sys_info_internal.h"
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Workernamespace base {
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Workernamespace {
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker// Whether this process has CPU security mitigations enabled.
39*6777b538SAndroid Build Coastguard Workerbool g_is_cpu_security_mitigation_enabled = false;
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker// Whether NumberOfProcessors() was called. Used to detect when the CPU security
42*6777b538SAndroid Build Coastguard Worker// mitigations state changes after a call to NumberOfProcessors().
43*6777b538SAndroid Build Coastguard Workerbool g_is_cpu_security_mitigation_enabled_read = false;
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker}  // namespace
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Workernamespace internal {
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Workerstd::optional<int> NumberOfPhysicalProcessors() {
50*6777b538SAndroid Build Coastguard Worker  return GetSysctlIntValue("hw.physicalcpu_max");
51*6777b538SAndroid Build Coastguard Worker}
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Workerstd::optional<int> NumberOfProcessorsWhenCpuSecurityMitigationEnabled() {
54*6777b538SAndroid Build Coastguard Worker  g_is_cpu_security_mitigation_enabled_read = true;
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker  if (!g_is_cpu_security_mitigation_enabled ||
57*6777b538SAndroid Build Coastguard Worker      !FeatureList::IsEnabled(kNumberOfCoresWithCpuSecurityMitigation)) {
58*6777b538SAndroid Build Coastguard Worker    return std::nullopt;
59*6777b538SAndroid Build Coastguard Worker  }
60*6777b538SAndroid Build Coastguard Worker  return NumberOfPhysicalProcessors();
61*6777b538SAndroid Build Coastguard Worker}
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker}  // namespace internal
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard WorkerBASE_FEATURE(kNumberOfCoresWithCpuSecurityMitigation,
66*6777b538SAndroid Build Coastguard Worker             "NumberOfCoresWithCpuSecurityMitigation",
67*6777b538SAndroid Build Coastguard Worker             FEATURE_ENABLED_BY_DEFAULT);
68*6777b538SAndroid Build Coastguard Worker
69*6777b538SAndroid Build Coastguard Worker// static
70*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::OperatingSystemName() {
71*6777b538SAndroid Build Coastguard Worker  return "Mac OS X";
72*6777b538SAndroid Build Coastguard Worker}
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker// static
75*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::OperatingSystemVersion() {
76*6777b538SAndroid Build Coastguard Worker  int32_t major, minor, bugfix;
77*6777b538SAndroid Build Coastguard Worker  OperatingSystemVersionNumbers(&major, &minor, &bugfix);
78*6777b538SAndroid Build Coastguard Worker  return base::StringPrintf("%d.%d.%d", major, minor, bugfix);
79*6777b538SAndroid Build Coastguard Worker}
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker// static
82*6777b538SAndroid Build Coastguard Workervoid SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
83*6777b538SAndroid Build Coastguard Worker                                            int32_t* minor_version,
84*6777b538SAndroid Build Coastguard Worker                                            int32_t* bugfix_version) {
85*6777b538SAndroid Build Coastguard Worker  NSOperatingSystemVersion version =
86*6777b538SAndroid Build Coastguard Worker      NSProcessInfo.processInfo.operatingSystemVersion;
87*6777b538SAndroid Build Coastguard Worker  *major_version = saturated_cast<int32_t>(version.majorVersion);
88*6777b538SAndroid Build Coastguard Worker  *minor_version = saturated_cast<int32_t>(version.minorVersion);
89*6777b538SAndroid Build Coastguard Worker  *bugfix_version = saturated_cast<int32_t>(version.patchVersion);
90*6777b538SAndroid Build Coastguard Worker}
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker// static
93*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::OperatingSystemArchitecture() {
94*6777b538SAndroid Build Coastguard Worker  switch (mac::GetCPUType()) {
95*6777b538SAndroid Build Coastguard Worker    case mac::CPUType::kIntel:
96*6777b538SAndroid Build Coastguard Worker      return "x86_64";
97*6777b538SAndroid Build Coastguard Worker    case mac::CPUType::kTranslatedIntel:
98*6777b538SAndroid Build Coastguard Worker    case mac::CPUType::kArm:
99*6777b538SAndroid Build Coastguard Worker      return "arm64";
100*6777b538SAndroid Build Coastguard Worker  }
101*6777b538SAndroid Build Coastguard Worker}
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker// static
104*6777b538SAndroid Build Coastguard Workeruint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
105*6777b538SAndroid Build Coastguard Worker  struct host_basic_info hostinfo;
106*6777b538SAndroid Build Coastguard Worker  mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
107*6777b538SAndroid Build Coastguard Worker  base::apple::ScopedMachSendRight host(mach_host_self());
108*6777b538SAndroid Build Coastguard Worker  int result = host_info(host.get(), HOST_BASIC_INFO,
109*6777b538SAndroid Build Coastguard Worker                         reinterpret_cast<host_info_t>(&hostinfo), &count);
110*6777b538SAndroid Build Coastguard Worker  if (result != KERN_SUCCESS) {
111*6777b538SAndroid Build Coastguard Worker    NOTREACHED();
112*6777b538SAndroid Build Coastguard Worker    return 0;
113*6777b538SAndroid Build Coastguard Worker  }
114*6777b538SAndroid Build Coastguard Worker  DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
115*6777b538SAndroid Build Coastguard Worker  return hostinfo.max_mem;
116*6777b538SAndroid Build Coastguard Worker}
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker// static
119*6777b538SAndroid Build Coastguard Workeruint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
120*6777b538SAndroid Build Coastguard Worker  SystemMemoryInfoKB info;
121*6777b538SAndroid Build Coastguard Worker  if (!GetSystemMemoryInfo(&info))
122*6777b538SAndroid Build Coastguard Worker    return 0;
123*6777b538SAndroid Build Coastguard Worker  // We should add inactive file-backed memory also but there is no such
124*6777b538SAndroid Build Coastguard Worker  // information from Mac OS unfortunately.
125*6777b538SAndroid Build Coastguard Worker  return checked_cast<uint64_t>(info.free + info.speculative) * 1024;
126*6777b538SAndroid Build Coastguard Worker}
127*6777b538SAndroid Build Coastguard Worker
128*6777b538SAndroid Build Coastguard Worker// static
129*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::CPUModelName() {
130*6777b538SAndroid Build Coastguard Worker  return StringSysctlByName("machdep.cpu.brand_string").value_or(std::string{});
131*6777b538SAndroid Build Coastguard Worker}
132*6777b538SAndroid Build Coastguard Worker
133*6777b538SAndroid Build Coastguard Worker// static
134*6777b538SAndroid Build Coastguard Workerstd::string SysInfo::HardwareModelName() {
135*6777b538SAndroid Build Coastguard Worker  // The old "hw.machine" and "hw.model" sysctls are discouraged in favor of the
136*6777b538SAndroid Build Coastguard Worker  // new "hw.product" and "hw.target". See
137*6777b538SAndroid Build Coastguard Worker  // https://github.com/apple-oss-distributions/xnu/blob/aca3beaa3dfbd42498b42c5e5ce20a938e6554e5/bsd/sys/sysctl.h#L1168-L1169
138*6777b538SAndroid Build Coastguard Worker  // and
139*6777b538SAndroid Build Coastguard Worker  // https://github.com/apple-oss-distributions/xnu/blob/aca3beaa3dfbd42498b42c5e5ce20a938e6554e5/bsd/kern/kern_mib.c#L534-L536
140*6777b538SAndroid Build Coastguard Worker  if (base::mac::MacOSMajorVersion() < 11) {
141*6777b538SAndroid Build Coastguard Worker    return StringSysctl({CTL_HW, HW_MODEL}).value_or(std::string{});
142*6777b538SAndroid Build Coastguard Worker  } else {
143*6777b538SAndroid Build Coastguard Worker    return StringSysctl({CTL_HW, HW_PRODUCT}).value_or(std::string{});
144*6777b538SAndroid Build Coastguard Worker  }
145*6777b538SAndroid Build Coastguard Worker}
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker// static
148*6777b538SAndroid Build Coastguard Workerstd::optional<SysInfo::HardwareModelNameSplit>
149*6777b538SAndroid Build Coastguard WorkerSysInfo::SplitHardwareModelNameDoNotUse(std::string_view name) {
150*6777b538SAndroid Build Coastguard Worker  size_t number_loc = name.find_first_of("0123456789");
151*6777b538SAndroid Build Coastguard Worker  if (number_loc == std::string::npos) {
152*6777b538SAndroid Build Coastguard Worker    return std::nullopt;
153*6777b538SAndroid Build Coastguard Worker  }
154*6777b538SAndroid Build Coastguard Worker  size_t comma_loc = name.find(',', number_loc);
155*6777b538SAndroid Build Coastguard Worker  if (comma_loc == std::string::npos) {
156*6777b538SAndroid Build Coastguard Worker    return std::nullopt;
157*6777b538SAndroid Build Coastguard Worker  }
158*6777b538SAndroid Build Coastguard Worker
159*6777b538SAndroid Build Coastguard Worker  HardwareModelNameSplit split;
160*6777b538SAndroid Build Coastguard Worker  if (!StringToInt(name.substr(0u, comma_loc).substr(number_loc),
161*6777b538SAndroid Build Coastguard Worker                   &split.model) ||
162*6777b538SAndroid Build Coastguard Worker      !StringToInt(name.substr(comma_loc + 1), &split.variant)) {
163*6777b538SAndroid Build Coastguard Worker    return std::nullopt;
164*6777b538SAndroid Build Coastguard Worker  }
165*6777b538SAndroid Build Coastguard Worker  split.category = name.substr(0u, number_loc);
166*6777b538SAndroid Build Coastguard Worker  return split;
167*6777b538SAndroid Build Coastguard Worker}
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker// static
170*6777b538SAndroid Build Coastguard WorkerSysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
171*6777b538SAndroid Build Coastguard Worker  HardwareInfo info;
172*6777b538SAndroid Build Coastguard Worker  info.manufacturer = "Apple Inc.";
173*6777b538SAndroid Build Coastguard Worker  info.model = HardwareModelName();
174*6777b538SAndroid Build Coastguard Worker  DCHECK(IsStringUTF8(info.manufacturer));
175*6777b538SAndroid Build Coastguard Worker  DCHECK(IsStringUTF8(info.model));
176*6777b538SAndroid Build Coastguard Worker  return info;
177*6777b538SAndroid Build Coastguard Worker}
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker// static
180*6777b538SAndroid Build Coastguard Workervoid SysInfo::SetCpuSecurityMitigationsEnabled() {
181*6777b538SAndroid Build Coastguard Worker  // Setting `g_is_cpu_security_mitigation_enabled_read` after it has been read
182*6777b538SAndroid Build Coastguard Worker  // is disallowed because it could indicate that some code got a number of
183*6777b538SAndroid Build Coastguard Worker  // processor computed without all the required state.
184*6777b538SAndroid Build Coastguard Worker  CHECK(!g_is_cpu_security_mitigation_enabled_read);
185*6777b538SAndroid Build Coastguard Worker
186*6777b538SAndroid Build Coastguard Worker  g_is_cpu_security_mitigation_enabled = true;
187*6777b538SAndroid Build Coastguard Worker}
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker// static
190*6777b538SAndroid Build Coastguard Workervoid SysInfo::ResetCpuSecurityMitigationsEnabledForTesting() {
191*6777b538SAndroid Build Coastguard Worker  g_is_cpu_security_mitigation_enabled_read = false;
192*6777b538SAndroid Build Coastguard Worker  g_is_cpu_security_mitigation_enabled = false;
193*6777b538SAndroid Build Coastguard Worker}
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker}  // namespace base
196