• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/resource.h>
13 #include <sys/utsname.h>
14 #include <unistd.h>
15 
16 #include "base/files/file_util.h"
17 #include "base/lazy_instance.h"
18 #include "base/logging.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/sys_info_internal.h"
21 #include "base/threading/thread_restrictions.h"
22 #include "build/build_config.h"
23 
24 #if defined(OS_ANDROID)
25 #include <sys/vfs.h>
26 #define statvfs statfs  // Android uses a statvfs-like statfs struct and call.
27 #else
28 #include <sys/statvfs.h>
29 #endif
30 
31 namespace {
32 
33 #if !defined(OS_OPENBSD)
NumberOfProcessors()34 int NumberOfProcessors() {
35   // sysconf returns the number of "logical" (not "physical") processors on both
36   // Mac and Linux.  So we get the number of max available "logical" processors.
37   //
38   // Note that the number of "currently online" processors may be fewer than the
39   // returned value of NumberOfProcessors(). On some platforms, the kernel may
40   // make some processors offline intermittently, to save power when system
41   // loading is low.
42   //
43   // One common use case that needs to know the processor count is to create
44   // optimal number of threads for optimization. It should make plan according
45   // to the number of "max available" processors instead of "currently online"
46   // ones. The kernel should be smart enough to make all processors online when
47   // it has sufficient number of threads waiting to run.
48   long res = sysconf(_SC_NPROCESSORS_CONF);
49   if (res == -1) {
50     NOTREACHED();
51     return 1;
52   }
53 
54   return static_cast<int>(res);
55 }
56 
57 base::LazyInstance<
58     base::internal::LazySysInfoValue<int, NumberOfProcessors> >::Leaky
59     g_lazy_number_of_processors = LAZY_INSTANCE_INITIALIZER;
60 #endif
61 
AmountOfVirtualMemory()62 int64_t AmountOfVirtualMemory() {
63   struct rlimit limit;
64   int result = getrlimit(RLIMIT_DATA, &limit);
65   if (result != 0) {
66     NOTREACHED();
67     return 0;
68   }
69   return limit.rlim_cur == RLIM_INFINITY ? 0 : limit.rlim_cur;
70 }
71 
72 base::LazyInstance<
73     base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky
74     g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER;
75 
GetDiskSpaceInfo(const base::FilePath & path,int64_t * available_bytes,int64_t * total_bytes)76 bool GetDiskSpaceInfo(const base::FilePath& path,
77                       int64_t* available_bytes,
78                       int64_t* total_bytes) {
79   struct statvfs stats;
80   if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0)
81     return false;
82 
83   if (available_bytes)
84     *available_bytes = static_cast<int64_t>(stats.f_bavail) * stats.f_frsize;
85   if (total_bytes)
86     *total_bytes = static_cast<int64_t>(stats.f_blocks) * stats.f_frsize;
87   return true;
88 }
89 
90 }  // namespace
91 
92 namespace base {
93 
94 #if !defined(OS_OPENBSD)
NumberOfProcessors()95 int SysInfo::NumberOfProcessors() {
96   return g_lazy_number_of_processors.Get().value();
97 }
98 #endif
99 
100 // static
AmountOfVirtualMemory()101 int64_t SysInfo::AmountOfVirtualMemory() {
102   return g_lazy_virtual_memory.Get().value();
103 }
104 
105 // static
AmountOfFreeDiskSpace(const FilePath & path)106 int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
107   base::ThreadRestrictions::AssertIOAllowed();
108 
109   int64_t available;
110   if (!GetDiskSpaceInfo(path, &available, nullptr))
111     return -1;
112   return available;
113 }
114 
115 // static
AmountOfTotalDiskSpace(const FilePath & path)116 int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
117   base::ThreadRestrictions::AssertIOAllowed();
118 
119   int64_t total;
120   if (!GetDiskSpaceInfo(path, nullptr, &total))
121     return -1;
122   return total;
123 }
124 
125 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
126 // static
OperatingSystemName()127 std::string SysInfo::OperatingSystemName() {
128   struct utsname info;
129   if (uname(&info) < 0) {
130     NOTREACHED();
131     return std::string();
132   }
133   return std::string(info.sysname);
134 }
135 #endif
136 
137 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
138 // static
OperatingSystemVersion()139 std::string SysInfo::OperatingSystemVersion() {
140   struct utsname info;
141   if (uname(&info) < 0) {
142     NOTREACHED();
143     return std::string();
144   }
145   return std::string(info.release);
146 }
147 #endif
148 
149 // static
OperatingSystemArchitecture()150 std::string SysInfo::OperatingSystemArchitecture() {
151   struct utsname info;
152   if (uname(&info) < 0) {
153     NOTREACHED();
154     return std::string();
155   }
156   std::string arch(info.machine);
157   if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") {
158     arch = "x86";
159   } else if (arch == "amd64") {
160     arch = "x86_64";
161   }
162   return arch;
163 }
164 
165 // static
VMAllocationGranularity()166 size_t SysInfo::VMAllocationGranularity() {
167   return getpagesize();
168 }
169 
170 }  // namespace base
171