// Copyright (c) 2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/file_util.h" #include "base/sys_info.h" #include "base/basictypes.h" #include #include #include #include #include #if defined(OS_MACOSX) #include #include #include #endif #if defined(OS_OPENBSD) #include #include #endif #include "base/logging.h" #include "base/string_util.h" namespace base { int SysInfo::NumberOfProcessors() { #if defined(OS_OPENBSD) int mib[] = { CTL_HW, HW_NCPU }; int ncpu; size_t size = sizeof(ncpu); if (sysctl(mib, 2, &ncpu, &size, NULL, 0) == -1) { NOTREACHED(); return 1; } return ncpu; #else // It seems that sysconf returns the number of "logical" processors on both // mac and linux. So we get the number of "online logical" processors. long res = sysconf(_SC_NPROCESSORS_ONLN); if (res == -1) { NOTREACHED(); return 1; } return static_cast(res); #endif } // static int64 SysInfo::AmountOfPhysicalMemory() { // _SC_PHYS_PAGES is not part of POSIX and not available on OS X or // FreeBSD #if defined(OS_MACOSX) struct host_basic_info hostinfo; mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; int result = host_info(mach_host_self(), HOST_BASIC_INFO, reinterpret_cast(&hostinfo), &count); DCHECK_EQ(HOST_BASIC_INFO_COUNT, count); if (result != KERN_SUCCESS) { NOTREACHED(); return 0; } return static_cast(hostinfo.max_mem); #elif defined(OS_FREEBSD) // TODO(benl): I have no idea how to get this NOTIMPLEMENTED(); return 0; #else long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); if (pages == -1 || page_size == -1) { NOTREACHED(); return 0; } return static_cast(pages) * page_size; #endif } // static int64 SysInfo::AmountOfFreeDiskSpace(const std::wstring& path) { struct statvfs stats; if (statvfs(WideToUTF8(path).c_str(), &stats) != 0) { return -1; } return static_cast(stats.f_bavail) * stats.f_frsize; } // static bool SysInfo::HasEnvVar(const wchar_t* var) { std::string var_utf8 = WideToUTF8(std::wstring(var)); return getenv(var_utf8.c_str()) != NULL; } // static std::wstring SysInfo::GetEnvVar(const wchar_t* var) { std::string var_utf8 = WideToUTF8(std::wstring(var)); char* value = getenv(var_utf8.c_str()); if (!value) { return L""; } else { return UTF8ToWide(value); } } // static std::string SysInfo::OperatingSystemName() { utsname info; if (uname(&info) < 0) { NOTREACHED(); return ""; } return std::string(info.sysname); } // static std::string SysInfo::OperatingSystemVersion() { utsname info; if (uname(&info) < 0) { NOTREACHED(); return ""; } return std::string(info.release); } // static std::string SysInfo::CPUArchitecture() { utsname info; if (uname(&info) < 0) { NOTREACHED(); return ""; } return std::string(info.machine); } // static void SysInfo::GetPrimaryDisplayDimensions(int* width, int* height) { #if defined(OS_MACOSX) CGDirectDisplayID main_display = CGMainDisplayID(); if (width) *width = CGDisplayPixelsWide(main_display); if (height) *height = CGDisplayPixelsHigh(main_display); #else // TODO(port): http://crbug.com/21732 NOTIMPLEMENTED(); if (width) *width = 0; if (height) *height = 0; #endif } // static int SysInfo::DisplayCount() { #if defined(OS_MACOSX) // Don't just return the number of online displays. It includes displays // that mirror other displays, which are not desired in the count. It's // tempting to use the count returned by CGGetActiveDisplayList, but active // displays exclude sleeping displays, and those are desired in the count. // It would be ridiculous to have this many displays connected, but // CGDirectDisplayID is just an integer, so supporting up to this many // doesn't hurt. CGDirectDisplayID online_displays[128]; CGDisplayCount online_display_count = 0; if (CGGetOnlineDisplayList(arraysize(online_displays), online_displays, &online_display_count) != kCGErrorSuccess) { // 1 is a reasonable assumption. return 1; } int display_count = 0; for (CGDisplayCount online_display_index = 0; online_display_index < online_display_count; ++online_display_index) { CGDirectDisplayID online_display = online_displays[online_display_index]; if (CGDisplayMirrorsDisplay(online_display) == kCGNullDirectDisplay) { // If this display doesn't mirror any other, include it in the count. // The primary display in a mirrored set will be counted, but those that // mirror it will not be. ++display_count; } } return display_count; #else // TODO(port): http://crbug.com/21732 NOTIMPLEMENTED(); return 1; #endif } // static size_t SysInfo::VMAllocationGranularity() { return getpagesize(); } #if defined(OS_LINUX) // static size_t SysInfo::MaxSharedMemorySize() { static size_t limit; static bool limit_valid = false; if (!limit_valid) { std::string contents; file_util::ReadFileToString(FilePath("/proc/sys/kernel/shmmax"), &contents); limit = strtoul(contents.c_str(), NULL, 0); limit_valid = true; } return limit; } #endif } // namespace base