1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/sys_info.h"
11 #include <sys/param.h>
12 #include <sys/utsname.h>
15 #include "base/files/file_util.h"
16 #include "base/lazy_instance.h"
17 #include "base/logging.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/sys_info_internal.h"
20 #include "base/threading/thread_restrictions.h"
21 #include "build/build_config.h"
23 #if !defined(OS_FUCHSIA)
24 #include <sys/resource.h>
27 #if defined(OS_ANDROID)
29 #define statvfs statfs // Android uses a statvfs-like statfs struct and call.
31 #include <sys/statvfs.h>
35 #include <linux/magic.h>
41 #if !defined(OS_OPENBSD) && !defined(OS_FUCHSIA)
42 int NumberOfProcessors() {
43 // sysconf returns the number of "logical" (not "physical") processors on both
44 // Mac and Linux. So we get the number of max available "logical" processors.
46 // Note that the number of "currently online" processors may be fewer than the
47 // returned value of NumberOfProcessors(). On some platforms, the kernel may
48 // make some processors offline intermittently, to save power when system
51 // One common use case that needs to know the processor count is to create
52 // optimal number of threads for optimization. It should make plan according
53 // to the number of "max available" processors instead of "currently online"
54 // ones. The kernel should be smart enough to make all processors online when
55 // it has sufficient number of threads waiting to run.
56 long res = sysconf(_SC_NPROCESSORS_CONF);
62 return static_cast<int>(res);
66 base::internal::LazySysInfoValue<int, NumberOfProcessors> >::Leaky
67 g_lazy_number_of_processors = LAZY_INSTANCE_INITIALIZER;
68 #endif // !defined(OS_OPENBSD) && !defined(OS_FUCHSIA)
70 #if !defined(OS_FUCHSIA)
71 int64_t AmountOfVirtualMemory() {
73 int result = getrlimit(RLIMIT_DATA, &limit);
78 return limit.rlim_cur == RLIM_INFINITY ? 0 : limit.rlim_cur;
82 base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky
83 g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER;
84 #endif // !defined(OS_FUCHSIA)
87 bool IsStatsZeroIfUnlimited(const base::FilePath& path) {
90 if (HANDLE_EINTR(statfs(path.value().c_str(), &stats)) != 0)
93 switch (stats.f_type) {
103 bool GetDiskSpaceInfo(const base::FilePath& path,
104 int64_t* available_bytes,
105 int64_t* total_bytes) {
106 struct statvfs stats;
107 if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0)
110 #if defined(OS_LINUX)
111 const bool zero_size_means_unlimited =
112 stats.f_blocks == 0 && IsStatsZeroIfUnlimited(path);
114 const bool zero_size_means_unlimited = false;
117 if (available_bytes) {
119 zero_size_means_unlimited
120 ? std::numeric_limits<int64_t>::max()
121 : static_cast<int64_t>(stats.f_bavail) * stats.f_frsize;
125 *total_bytes = zero_size_means_unlimited
126 ? std::numeric_limits<int64_t>::max()
127 : static_cast<int64_t>(stats.f_blocks) * stats.f_frsize;
136 #if !defined(OS_OPENBSD) && !defined(OS_FUCHSIA)
137 int SysInfo::NumberOfProcessors() {
138 return g_lazy_number_of_processors.Get().value();
142 #if !defined(OS_FUCHSIA)
144 int64_t SysInfo::AmountOfVirtualMemory() {
145 return g_lazy_virtual_memory.Get().value();
150 int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
151 AssertBlockingAllowed();
154 if (!GetDiskSpaceInfo(path, &available, nullptr))
160 int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
161 AssertBlockingAllowed();
164 if (!GetDiskSpaceInfo(path, nullptr, &total))
169 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
171 std::string SysInfo::OperatingSystemName() {
173 if (uname(&info) < 0) {
175 return std::string();
177 return std::string(info.sysname);
181 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !(OS_CHROMEOS)
183 std::string SysInfo::OperatingSystemVersion() {
185 if (uname(&info) < 0) {
187 return std::string();
189 return std::string(info.release);
193 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
195 void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
196 int32_t* minor_version,
197 int32_t* bugfix_version) {
199 if (uname(&info) < 0) {
206 int num_read = sscanf(info.release, "%d.%d.%d", major_version, minor_version,
218 std::string SysInfo::OperatingSystemArchitecture() {
220 if (uname(&info) < 0) {
222 return std::string();
224 std::string arch(info.machine);
225 if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") {
227 } else if (arch == "amd64") {
229 } else if (std::string(info.sysname) == "AIX") {
236 size_t SysInfo::VMAllocationGranularity() {
237 return getpagesize();