1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/sys_info.h" 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <errno.h> 8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h> 9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stdint.h> 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <string.h> 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <sys/param.h> 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <sys/resource.h> 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <sys/utsname.h> 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <unistd.h> 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/files/file_util.h" 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/lazy_instance.h" 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/logging.h" 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/strings/utf_string_conversions.h" 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/sys_info_internal.h" 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/threading/thread_restrictions.h" 22cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "build/build_config.h" 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_ANDROID) 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <sys/vfs.h> 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define statvfs statfs // Android uses a statvfs-like statfs struct and call. 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#else 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <sys/statvfs.h> 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace { 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(OS_OPENBSD) 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratint NumberOfProcessors() { 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // sysconf returns the number of "logical" (not "physical") processors on both 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Mac and Linux. So we get the number of max available "logical" processors. 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Note that the number of "currently online" processors may be fewer than the 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // returned value of NumberOfProcessors(). On some platforms, the kernel may 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // make some processors offline intermittently, to save power when system 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // loading is low. 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // One common use case that needs to know the processor count is to create 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // optimal number of threads for optimization. It should make plan according 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // to the number of "max available" processors instead of "currently online" 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // ones. The kernel should be smart enough to make all processors online when 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // it has sufficient number of threads waiting to run. 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat long res = sysconf(_SC_NPROCESSORS_CONF); 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (res == -1) { 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return 1; 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return static_cast<int>(res); 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbase::LazyInstance< 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat base::internal::LazySysInfoValue<int, NumberOfProcessors> >::Leaky 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat g_lazy_number_of_processors = LAZY_INSTANCE_INITIALIZER; 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 62cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoint64_t AmountOfVirtualMemory() { 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct rlimit limit; 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int result = getrlimit(RLIMIT_DATA, &limit); 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (result != 0) { 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return 0; 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return limit.rlim_cur == RLIM_INFINITY ? 0 : limit.rlim_cur; 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbase::LazyInstance< 73cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER; 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(OS_OPENBSD) 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratint SysInfo::NumberOfProcessors() { 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return g_lazy_number_of_processors.Get().value(); 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 87cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoint64_t SysInfo::AmountOfVirtualMemory() { 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return g_lazy_virtual_memory.Get().value(); 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 92cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoint64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) { 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat base::ThreadRestrictions::AssertIOAllowed(); 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct statvfs stats; 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0) 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return -1; 98cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko return static_cast<int64_t>(stats.f_bavail) * stats.f_frsize; 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(OS_MACOSX) && !defined(OS_ANDROID) 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string SysInfo::OperatingSystemName() { 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct utsname info; 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (uname(&info) < 0) { 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return std::string(); 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return std::string(info.sysname); 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(OS_MACOSX) && !defined(OS_ANDROID) 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string SysInfo::OperatingSystemVersion() { 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct utsname info; 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (uname(&info) < 0) { 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return std::string(); 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return std::string(info.release); 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string SysInfo::OperatingSystemArchitecture() { 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat struct utsname info; 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (uname(&info) < 0) { 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return std::string(); 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::string arch(info.machine); 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (arch == "i386" || arch == "i486" || arch == "i586" || arch == "i686") { 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat arch = "x86"; 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } else if (arch == "amd64") { 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat arch = "x86_64"; 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return arch; 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratsize_t SysInfo::VMAllocationGranularity() { 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return getpagesize(); 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 147