Upload upstream chromium 69.0.3497
[platform/framework/web/chromium-efl.git] / base / sys_info_posix.cc
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.
4
5 #include "base/sys_info.h"
6
7 #include <errno.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include <sys/param.h>
12 #include <sys/utsname.h>
13 #include <unistd.h>
14
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"
22
23 #if !defined(OS_FUCHSIA)
24 #include <sys/resource.h>
25 #endif
26
27 #if defined(OS_ANDROID)
28 #include <sys/vfs.h>
29 #define statvfs statfs  // Android uses a statvfs-like statfs struct and call.
30 #else
31 #include <sys/statvfs.h>
32 #endif
33
34 #if defined(OS_LINUX)
35 #include <linux/magic.h>
36 #include <sys/vfs.h>
37 #endif
38
39 namespace {
40
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.
45   //
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
49   // loading is low.
50   //
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);
57   if (res == -1) {
58     NOTREACHED();
59     return 1;
60   }
61
62   return static_cast<int>(res);
63 }
64
65 base::LazyInstance<
66     base::internal::LazySysInfoValue<int, NumberOfProcessors> >::Leaky
67     g_lazy_number_of_processors = LAZY_INSTANCE_INITIALIZER;
68 #endif  // !defined(OS_OPENBSD) && !defined(OS_FUCHSIA)
69
70 #if !defined(OS_FUCHSIA)
71 int64_t AmountOfVirtualMemory() {
72   struct rlimit limit;
73   int result = getrlimit(RLIMIT_DATA, &limit);
74   if (result != 0) {
75     NOTREACHED();
76     return 0;
77   }
78   return limit.rlim_cur == RLIM_INFINITY ? 0 : limit.rlim_cur;
79 }
80
81 base::LazyInstance<
82     base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky
83     g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER;
84 #endif  // !defined(OS_FUCHSIA)
85
86 #if defined(OS_LINUX)
87 bool IsStatsZeroIfUnlimited(const base::FilePath& path) {
88   struct statfs stats;
89
90   if (HANDLE_EINTR(statfs(path.value().c_str(), &stats)) != 0)
91     return false;
92
93   switch (stats.f_type) {
94     case TMPFS_MAGIC:
95     case HUGETLBFS_MAGIC:
96     case RAMFS_MAGIC:
97       return true;
98   }
99   return false;
100 }
101 #endif
102
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)
108     return false;
109
110 #if defined(OS_LINUX)
111   const bool zero_size_means_unlimited =
112       stats.f_blocks == 0 && IsStatsZeroIfUnlimited(path);
113 #else
114   const bool zero_size_means_unlimited = false;
115 #endif
116
117   if (available_bytes) {
118     *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;
122   }
123
124   if (total_bytes) {
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;
128   }
129   return true;
130 }
131
132 }  // namespace
133
134 namespace base {
135
136 #if !defined(OS_OPENBSD) && !defined(OS_FUCHSIA)
137 int SysInfo::NumberOfProcessors() {
138   return g_lazy_number_of_processors.Get().value();
139 }
140 #endif
141
142 #if !defined(OS_FUCHSIA)
143 // static
144 int64_t SysInfo::AmountOfVirtualMemory() {
145   return g_lazy_virtual_memory.Get().value();
146 }
147 #endif
148
149 // static
150 int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
151   AssertBlockingAllowed();
152
153   int64_t available;
154   if (!GetDiskSpaceInfo(path, &available, nullptr))
155     return -1;
156   return available;
157 }
158
159 // static
160 int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
161   AssertBlockingAllowed();
162
163   int64_t total;
164   if (!GetDiskSpaceInfo(path, nullptr, &total))
165     return -1;
166   return total;
167 }
168
169 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
170 // static
171 std::string SysInfo::OperatingSystemName() {
172   struct utsname info;
173   if (uname(&info) < 0) {
174     NOTREACHED();
175     return std::string();
176   }
177   return std::string(info.sysname);
178 }
179 #endif
180
181 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !(OS_CHROMEOS)
182 // static
183 std::string SysInfo::OperatingSystemVersion() {
184   struct utsname info;
185   if (uname(&info) < 0) {
186     NOTREACHED();
187     return std::string();
188   }
189   return std::string(info.release);
190 }
191 #endif
192
193 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
194 // static
195 void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
196                                             int32_t* minor_version,
197                                             int32_t* bugfix_version) {
198   struct utsname info;
199   if (uname(&info) < 0) {
200     NOTREACHED();
201     *major_version = 0;
202     *minor_version = 0;
203     *bugfix_version = 0;
204     return;
205   }
206   int num_read = sscanf(info.release, "%d.%d.%d", major_version, minor_version,
207                         bugfix_version);
208   if (num_read < 1)
209     *major_version = 0;
210   if (num_read < 2)
211     *minor_version = 0;
212   if (num_read < 3)
213     *bugfix_version = 0;
214 }
215 #endif
216
217 // static
218 std::string SysInfo::OperatingSystemArchitecture() {
219   struct utsname info;
220   if (uname(&info) < 0) {
221     NOTREACHED();
222     return std::string();
223   }
224   std::string arch(info.machine);
225   if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") {
226     arch = "x86";
227   } else if (arch == "amd64") {
228     arch = "x86_64";
229   } else if (std::string(info.sysname) == "AIX") {
230     arch = "ppc64";
231   }
232   return arch;
233 }
234
235 // static
236 size_t SysInfo::VMAllocationGranularity() {
237   return getpagesize();
238 }
239
240 }  // namespace base