mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Backed out 3 changesets (bug 1426513) for bustage at /src/base/process_util_posix.cc r=backout on a CLOSED TREE
Backed out changeset 693bb500fc25 (bug 1426513) Backed out changeset 64021383118d (bug 1426513) Backed out changeset 9d80a554866c (bug 1426513)
This commit is contained in:
parent
7b5bcc482d
commit
72aaaf526b
@ -35,6 +35,7 @@ UNIFIED_SOURCES += [
|
||||
if os_win:
|
||||
SOURCES += [
|
||||
'src/base/condition_variable_win.cc',
|
||||
'src/base/cpu.cc',
|
||||
'src/base/file_util_win.cc',
|
||||
'src/base/lock_impl_win.cc',
|
||||
'src/base/message_pump_win.cc',
|
||||
@ -43,6 +44,7 @@ if os_win:
|
||||
'src/base/process_util_win.cc',
|
||||
'src/base/rand_util_win.cc',
|
||||
'src/base/shared_memory_win.cc',
|
||||
'src/base/sys_info_win.cc',
|
||||
'src/base/sys_string_conversions_win.cc',
|
||||
'src/base/thread_local_win.cc',
|
||||
'src/base/time_win.cc',
|
||||
@ -67,6 +69,7 @@ if os_posix:
|
||||
'src/base/rand_util_posix.cc',
|
||||
'src/base/shared_memory_posix.cc',
|
||||
'src/base/string16.cc',
|
||||
'src/base/sys_info_posix.cc',
|
||||
'src/base/thread_local_posix.cc',
|
||||
'src/base/waitable_event_posix.cc',
|
||||
'src/chrome/common/file_descriptor_set_posix.cc',
|
||||
@ -82,6 +85,7 @@ if os_macosx:
|
||||
'src/base/message_pump_mac.mm',
|
||||
'src/base/process_util_mac.mm',
|
||||
'src/base/scoped_nsautorelease_pool.mm',
|
||||
'src/base/sys_info_mac.cc',
|
||||
'src/base/sys_string_conversions_mac.mm',
|
||||
'src/base/time_mac.cc',
|
||||
'src/chrome/common/mach_ipc_mac.mm',
|
||||
|
56
ipc/chromium/src/base/cpu.cc
Normal file
56
ipc/chromium/src/base/cpu.cc
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2006-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/cpu.h"
|
||||
#include <intrin.h>
|
||||
#include <string>
|
||||
|
||||
namespace base {
|
||||
|
||||
CPU::CPU()
|
||||
: type_(0),
|
||||
family_(0),
|
||||
model_(0),
|
||||
stepping_(0),
|
||||
ext_model_(0),
|
||||
ext_family_(0),
|
||||
cpu_vendor_("unknown") {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CPU::Initialize() {
|
||||
int cpu_info[4] = {-1};
|
||||
char cpu_string[0x20];
|
||||
|
||||
// __cpuid with an InfoType argument of 0 returns the number of
|
||||
// valid Ids in CPUInfo[0] and the CPU identification string in
|
||||
// the other three array elements. The CPU identification string is
|
||||
// not in linear order. The code below arranges the information
|
||||
// in a human readable form.
|
||||
//
|
||||
// More info can be found here:
|
||||
// http://msdn.microsoft.com/en-us/library/hskdteyh.aspx
|
||||
__cpuid(cpu_info, 0);
|
||||
int num_ids = cpu_info[0];
|
||||
memset(cpu_string, 0, sizeof(cpu_string));
|
||||
*(reinterpret_cast<int*>(cpu_string)) = cpu_info[1];
|
||||
*(reinterpret_cast<int*>(cpu_string+4)) = cpu_info[3];
|
||||
*(reinterpret_cast<int*>(cpu_string+8)) = cpu_info[2];
|
||||
|
||||
// Interpret CPU feature information.
|
||||
if (num_ids > 0) {
|
||||
__cpuid(cpu_info, 1);
|
||||
stepping_ = cpu_info[0] & 0xf;
|
||||
model_ = (cpu_info[0] >> 4) & 0xf;
|
||||
family_ = (cpu_info[0] >> 8) & 0xf;
|
||||
type_ = (cpu_info[0] >> 12) & 0x3;
|
||||
ext_model_ = (cpu_info[0] >> 16) & 0xf;
|
||||
ext_family_ = (cpu_info[0] >> 20) & 0xff;
|
||||
cpu_vendor_ = cpu_string;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
44
ipc/chromium/src/base/cpu.h
Normal file
44
ipc/chromium/src/base/cpu.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2006-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.
|
||||
|
||||
#ifndef BASE_CPU_H_
|
||||
#define BASE_CPU_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace base {
|
||||
|
||||
// Query information about the processor.
|
||||
class CPU {
|
||||
public:
|
||||
// Constructor
|
||||
CPU();
|
||||
|
||||
// Accessors for CPU information.
|
||||
const std::string& vendor_name() const { return cpu_vendor_; }
|
||||
int stepping() const { return stepping_; }
|
||||
int model() const { return model_; }
|
||||
int family() const { return family_; }
|
||||
int type() const { return type_; }
|
||||
int extended_model() const { return ext_model_; }
|
||||
int extended_family() const { return ext_family_; }
|
||||
|
||||
private:
|
||||
// Query the processor for CPUID information.
|
||||
void Initialize();
|
||||
|
||||
int type_; // process type
|
||||
int family_; // family of the processor
|
||||
int model_; // model of processor
|
||||
int stepping_; // processor revision number
|
||||
int ext_model_;
|
||||
int ext_family_;
|
||||
std::string cpu_vendor_;
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_CPU_H_
|
@ -167,6 +167,15 @@ bool LaunchApp(const CommandLine& cl,
|
||||
const LaunchOptions&,
|
||||
ProcessHandle* process_handle);
|
||||
|
||||
// Used to filter processes by process ID.
|
||||
class ProcessFilter {
|
||||
public:
|
||||
// Returns true to indicate set-inclusion and false otherwise. This method
|
||||
// should not have side-effects and should be idempotent.
|
||||
virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0;
|
||||
virtual ~ProcessFilter() { }
|
||||
};
|
||||
|
||||
// Attempts to kill the process identified by the given process
|
||||
// entry structure, giving it the specified exit code. If |wait| is true, wait
|
||||
// for the process to be actually terminated before returning.
|
||||
@ -182,6 +191,40 @@ bool KillProcess(ProcessHandle process, int exit_code, bool wait);
|
||||
// a different manner on POSIX.
|
||||
bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
|
||||
|
||||
// Provides performance metrics for a specified process (CPU usage, memory and
|
||||
// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
|
||||
// for a specific process, then access the information with the different get
|
||||
// methods.
|
||||
class ProcessMetrics {
|
||||
public:
|
||||
// Creates a ProcessMetrics for the specified process.
|
||||
// The caller owns the returned object.
|
||||
static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
|
||||
|
||||
~ProcessMetrics();
|
||||
|
||||
// Returns the CPU usage in percent since the last time this method was
|
||||
// called. The first time this method is called it returns 0 and will return
|
||||
// the actual CPU info on subsequent calls.
|
||||
// Note that on multi-processor machines, the CPU usage value is for all
|
||||
// CPUs. So if you have 2 CPUs and your process is using all the cycles
|
||||
// of 1 CPU and not the other CPU, this method returns 50.
|
||||
int GetCPUUsage();
|
||||
|
||||
private:
|
||||
explicit ProcessMetrics(ProcessHandle process);
|
||||
|
||||
ProcessHandle process_;
|
||||
|
||||
int processor_count_;
|
||||
|
||||
// Used to store the previous times so we can compute the CPU usage.
|
||||
int64_t last_time_;
|
||||
int64_t last_system_time_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/platform_thread.h"
|
||||
#include "base/process_util.h"
|
||||
#include "base/sys_info.h"
|
||||
#include "base/time.h"
|
||||
#include "base/waitable_event.h"
|
||||
#include "base/dir_reader_posix.h"
|
||||
@ -248,6 +249,19 @@ void SetAllFDsToCloseOnExec() {
|
||||
}
|
||||
}
|
||||
|
||||
ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process),
|
||||
last_time_(0),
|
||||
last_system_time_(0) {
|
||||
processor_count_ = base::SysInfo::NumberOfProcessors();
|
||||
}
|
||||
|
||||
// static
|
||||
ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
|
||||
return new ProcessMetrics(process);
|
||||
}
|
||||
|
||||
ProcessMetrics::~ProcessMetrics() { }
|
||||
|
||||
bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
|
||||
int status;
|
||||
const int result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
|
||||
@ -303,6 +317,45 @@ int64_t TimeValToMicroseconds(const struct timeval& tv) {
|
||||
|
||||
}
|
||||
|
||||
int ProcessMetrics::GetCPUUsage() {
|
||||
struct timeval now;
|
||||
struct rusage usage;
|
||||
|
||||
int retval = gettimeofday(&now, NULL);
|
||||
if (retval)
|
||||
return 0;
|
||||
retval = getrusage(RUSAGE_SELF, &usage);
|
||||
if (retval)
|
||||
return 0;
|
||||
|
||||
int64_t system_time = (TimeValToMicroseconds(usage.ru_stime) +
|
||||
TimeValToMicroseconds(usage.ru_utime)) /
|
||||
processor_count_;
|
||||
int64_t time = TimeValToMicroseconds(now);
|
||||
|
||||
if ((last_system_time_ == 0) || (last_time_ == 0)) {
|
||||
// First call, just set the last values.
|
||||
last_system_time_ = system_time;
|
||||
last_time_ = time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t system_time_delta = system_time - last_system_time_;
|
||||
int64_t time_delta = time - last_time_;
|
||||
DCHECK(time_delta != 0);
|
||||
if (time_delta == 0)
|
||||
return 0;
|
||||
|
||||
// We add time_delta / 2 so the result is rounded.
|
||||
int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) /
|
||||
time_delta);
|
||||
|
||||
last_system_time_ = system_time;
|
||||
last_time_ = time;
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
void
|
||||
FreeEnvVarsArray::operator()(char** array)
|
||||
{
|
||||
|
@ -402,4 +402,72 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ProcesMetrics
|
||||
|
||||
ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process),
|
||||
last_time_(0),
|
||||
last_system_time_(0) {
|
||||
SYSTEM_INFO system_info;
|
||||
GetSystemInfo(&system_info);
|
||||
processor_count_ = system_info.dwNumberOfProcessors;
|
||||
}
|
||||
|
||||
// static
|
||||
ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
|
||||
return new ProcessMetrics(process);
|
||||
}
|
||||
|
||||
ProcessMetrics::~ProcessMetrics() { }
|
||||
|
||||
static uint64_t FileTimeToUTC(const FILETIME& ftime) {
|
||||
LARGE_INTEGER li;
|
||||
li.LowPart = ftime.dwLowDateTime;
|
||||
li.HighPart = ftime.dwHighDateTime;
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
int ProcessMetrics::GetCPUUsage() {
|
||||
FILETIME now;
|
||||
FILETIME creation_time;
|
||||
FILETIME exit_time;
|
||||
FILETIME kernel_time;
|
||||
FILETIME user_time;
|
||||
|
||||
GetSystemTimeAsFileTime(&now);
|
||||
|
||||
if (!GetProcessTimes(process_, &creation_time, &exit_time,
|
||||
&kernel_time, &user_time)) {
|
||||
// We don't assert here because in some cases (such as in the Task Manager)
|
||||
// we may call this function on a process that has just exited but we have
|
||||
// not yet received the notification.
|
||||
return 0;
|
||||
}
|
||||
int64_t system_time = (FileTimeToUTC(kernel_time) + FileTimeToUTC(user_time)) /
|
||||
processor_count_;
|
||||
int64_t time = FileTimeToUTC(now);
|
||||
|
||||
if ((last_system_time_ == 0) || (last_time_ == 0)) {
|
||||
// First call, just set the last values.
|
||||
last_system_time_ = system_time;
|
||||
last_time_ = time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t system_time_delta = system_time - last_system_time_;
|
||||
int64_t time_delta = time - last_time_;
|
||||
DCHECK(time_delta != 0);
|
||||
if (time_delta == 0)
|
||||
return 0;
|
||||
|
||||
// We add time_delta / 2 so the result is rounded.
|
||||
int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) /
|
||||
time_delta);
|
||||
|
||||
last_system_time_ = system_time;
|
||||
last_time_ = time;
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
65
ipc/chromium/src/base/sys_info.h
Normal file
65
ipc/chromium/src/base/sys_info.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// 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.
|
||||
|
||||
#ifndef BASE_SYS_INFO_H_
|
||||
#define BASE_SYS_INFO_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace base {
|
||||
|
||||
class SysInfo {
|
||||
public:
|
||||
// Return the number of logical processors/cores on the current machine.
|
||||
// WARNING: On POSIX, this method uses static variables and is not threadsafe
|
||||
// until it's been initialized by being called once without a race.
|
||||
static int NumberOfProcessors();
|
||||
|
||||
// Return the number of bytes of physical memory on the current machine.
|
||||
static int64_t AmountOfPhysicalMemory();
|
||||
|
||||
// Return the number of megabytes of physical memory on the current machine.
|
||||
static int AmountOfPhysicalMemoryMB() {
|
||||
return static_cast<int>(AmountOfPhysicalMemory() / 1024 / 1024);
|
||||
}
|
||||
|
||||
// Return the available disk space in bytes on the volume containing |path|,
|
||||
// or -1 on failure.
|
||||
static int64_t AmountOfFreeDiskSpace(const std::wstring& path);
|
||||
|
||||
// Return true if the given environment variable is defined.
|
||||
// TODO: find a better place for HasEnvVar.
|
||||
static bool HasEnvVar(const wchar_t* var);
|
||||
|
||||
// Return the value of the given environment variable
|
||||
// or an empty string if not defined.
|
||||
// TODO: find a better place for GetEnvVar.
|
||||
static std::wstring GetEnvVar(const wchar_t* var);
|
||||
|
||||
// Returns the name of the host operating system.
|
||||
static std::string OperatingSystemName();
|
||||
|
||||
// Returns the CPU architecture of the system. Exact return value may differ
|
||||
// across platforms.
|
||||
static std::string CPUArchitecture();
|
||||
|
||||
// Returns the pixel dimensions of the primary display via the
|
||||
// width and height parameters.
|
||||
static void GetPrimaryDisplayDimensions(int* width, int* height);
|
||||
|
||||
// Return the number of displays.
|
||||
static int DisplayCount();
|
||||
|
||||
// Return the smallest amount of memory (in bytes) which the VM system will
|
||||
// allocate.
|
||||
static size_t VMAllocationGranularity();
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_SYS_INFO_H_
|
13
ipc/chromium/src/base/sys_info_mac.cc
Normal file
13
ipc/chromium/src/base/sys_info_mac.cc
Normal file
@ -0,0 +1,13 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2009 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/sys_info.h"
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
namespace base {
|
||||
|
||||
} // namespace base
|
158
ipc/chromium/src/base/sys_info_posix.cc
Normal file
158
ipc/chromium/src/base/sys_info_posix.cc
Normal file
@ -0,0 +1,158 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// 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/sys_info.h"
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifndef ANDROID
|
||||
#include <sys/statvfs.h>
|
||||
#endif
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/mach_init.h>
|
||||
#endif
|
||||
|
||||
#if defined(OS_NETBSD)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
int SysInfo::NumberOfProcessors() {
|
||||
// It seems that sysconf returns the number of "logical" processors on both
|
||||
// mac and linux. So we get the number of "online logical" processors.
|
||||
#ifdef _SC_NPROCESSORS_ONLN
|
||||
static long res = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#else
|
||||
static long res = 1;
|
||||
#endif
|
||||
if (res == -1) {
|
||||
NOTREACHED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return static_cast<int>(res);
|
||||
}
|
||||
|
||||
// static
|
||||
int64_t SysInfo::AmountOfPhysicalMemory() {
|
||||
// _SC_PHYS_PAGES is not part of POSIX and not available on OS X
|
||||
#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<host_info_t>(&hostinfo),
|
||||
&count);
|
||||
DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
|
||||
if (result != KERN_SUCCESS) {
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<int64_t>(hostinfo.max_mem);
|
||||
#elif defined(OS_NETBSD)
|
||||
int mib[2];
|
||||
int rc;
|
||||
int64_t memSize;
|
||||
size_t len = sizeof(memSize);
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_PHYSMEM64;
|
||||
rc = sysctl( mib, 2, &memSize, &len, NULL, 0 );
|
||||
if (-1 != rc) {
|
||||
return memSize;
|
||||
}
|
||||
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<int64_t>(pages) * page_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
int64_t SysInfo::AmountOfFreeDiskSpace(const std::wstring& path) {
|
||||
#ifndef ANDROID
|
||||
struct statvfs stats;
|
||||
if (statvfs(WideToUTF8(path).c_str(), &stats) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int64_t>(stats.f_bavail) * stats.f_frsize;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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() {
|
||||
struct utsname info;
|
||||
if (uname(&info) < 0) {
|
||||
NOTREACHED();
|
||||
return "";
|
||||
}
|
||||
return std::string(info.sysname);
|
||||
}
|
||||
|
||||
// static
|
||||
std::string SysInfo::CPUArchitecture() {
|
||||
struct utsname info;
|
||||
if (uname(&info) < 0) {
|
||||
NOTREACHED();
|
||||
return "";
|
||||
}
|
||||
return std::string(info.machine);
|
||||
}
|
||||
|
||||
// static
|
||||
void SysInfo::GetPrimaryDisplayDimensions(int* width, int* height) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
// static
|
||||
int SysInfo::DisplayCount() {
|
||||
NOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// static
|
||||
size_t SysInfo::VMAllocationGranularity() {
|
||||
return getpagesize();
|
||||
}
|
||||
|
||||
} // namespace base
|
100
ipc/chromium/src/base/sys_info_win.cc
Normal file
100
ipc/chromium/src/base/sys_info_win.cc
Normal file
@ -0,0 +1,100 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// 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/sys_info.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
// static
|
||||
int SysInfo::NumberOfProcessors() {
|
||||
SYSTEM_INFO info;
|
||||
GetSystemInfo(&info);
|
||||
return static_cast<int>(info.dwNumberOfProcessors);
|
||||
}
|
||||
|
||||
// static
|
||||
int64_t SysInfo::AmountOfPhysicalMemory() {
|
||||
MEMORYSTATUSEX memory_info;
|
||||
memory_info.dwLength = sizeof(memory_info);
|
||||
if (!GlobalMemoryStatusEx(&memory_info)) {
|
||||
NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t rv = static_cast<int64_t>(memory_info.ullTotalPhys);
|
||||
if (rv < 0)
|
||||
rv = kint64max;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
int64_t SysInfo::AmountOfFreeDiskSpace(const std::wstring& path) {
|
||||
ULARGE_INTEGER available, total, free;
|
||||
if (!GetDiskFreeSpaceExW(path.c_str(), &available, &total, &free)) {
|
||||
return -1;
|
||||
}
|
||||
int64_t rv = static_cast<int64_t>(available.QuadPart);
|
||||
if (rv < 0)
|
||||
rv = kint64max;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
bool SysInfo::HasEnvVar(const wchar_t* var) {
|
||||
return GetEnvironmentVariable(var, NULL, 0) != 0;
|
||||
}
|
||||
|
||||
// static
|
||||
std::wstring SysInfo::GetEnvVar(const wchar_t* var) {
|
||||
DWORD value_length = GetEnvironmentVariable(var, NULL, 0);
|
||||
if (value_length == 0) {
|
||||
return L"";
|
||||
}
|
||||
mozilla::UniquePtr<wchar_t[]> value(new wchar_t[value_length]);
|
||||
GetEnvironmentVariable(var, value.get(), value_length);
|
||||
return std::wstring(value.get());
|
||||
}
|
||||
|
||||
// static
|
||||
std::string SysInfo::OperatingSystemName() {
|
||||
return "Windows NT";
|
||||
}
|
||||
|
||||
// static
|
||||
std::string SysInfo::CPUArchitecture() {
|
||||
// TODO: Make this vary when we support any other architectures.
|
||||
return "x86";
|
||||
}
|
||||
|
||||
// static
|
||||
void SysInfo::GetPrimaryDisplayDimensions(int* width, int* height) {
|
||||
if (width)
|
||||
*width = GetSystemMetrics(SM_CXSCREEN);
|
||||
|
||||
if (height)
|
||||
*height = GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
// static
|
||||
int SysInfo::DisplayCount() {
|
||||
return GetSystemMetrics(SM_CMONITORS);
|
||||
}
|
||||
|
||||
// static
|
||||
size_t SysInfo::VMAllocationGranularity() {
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
|
||||
return sysinfo.dwAllocationGranularity;
|
||||
}
|
||||
|
||||
} // namespace base
|
@ -395,6 +395,12 @@ class TimeTicks {
|
||||
// on hardware/operating system configuration.
|
||||
static TimeTicks Now();
|
||||
|
||||
// Returns a platform-dependent high-resolution tick count. Implementation
|
||||
// is hardware dependent and may or may not return sub-millisecond
|
||||
// resolution. THIS CALL IS GENERALLY MUCH MORE EXPENSIVE THAN Now() AND
|
||||
// SHOULD ONLY BE USED WHEN IT IS REALLY NEEDED.
|
||||
static TimeTicks HighResNow();
|
||||
|
||||
// Returns true if this object has not been initialized.
|
||||
bool is_null() const {
|
||||
return ticks_ == 0;
|
||||
|
@ -197,4 +197,9 @@ TimeTicks TimeTicks::Now() {
|
||||
return TimeTicks(absolute_micro);
|
||||
}
|
||||
|
||||
// static
|
||||
TimeTicks TimeTicks::HighResNow() {
|
||||
return Now();
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "base/basictypes.h"
|
||||
#include "base/lock.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/cpu.h"
|
||||
#include "base/singleton.h"
|
||||
#include "mozilla/Casting.h"
|
||||
|
||||
@ -255,6 +256,105 @@ class NowSingleton {
|
||||
DISALLOW_COPY_AND_ASSIGN(NowSingleton);
|
||||
};
|
||||
|
||||
// Overview of time counters:
|
||||
// (1) CPU cycle counter. (Retrieved via RDTSC)
|
||||
// The CPU counter provides the highest resolution time stamp and is the least
|
||||
// expensive to retrieve. However, the CPU counter is unreliable and should not
|
||||
// be used in production. Its biggest issue is that it is per processor and it
|
||||
// is not synchronized between processors. Also, on some computers, the counters
|
||||
// will change frequency due to thermal and power changes, and stop in some
|
||||
// states.
|
||||
//
|
||||
// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
|
||||
// resolution (100 nanoseconds) time stamp but is comparatively more expensive
|
||||
// to retrieve. What QueryPerformanceCounter actually does is up to the HAL.
|
||||
// (with some help from ACPI).
|
||||
// According to http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx
|
||||
// in the worst case, it gets the counter from the rollover interrupt on the
|
||||
// programmable interrupt timer. In best cases, the HAL may conclude that the
|
||||
// RDTSC counter runs at a constant frequency, then it uses that instead. On
|
||||
// multiprocessor machines, it will try to verify the values returned from
|
||||
// RDTSC on each processor are consistent with each other, and apply a handful
|
||||
// of workarounds for known buggy hardware. In other words, QPC is supposed to
|
||||
// give consistent result on a multiprocessor computer, but it is unreliable in
|
||||
// reality due to bugs in BIOS or HAL on some, especially old computers.
|
||||
// With recent updates on HAL and newer BIOS, QPC is getting more reliable but
|
||||
// it should be used with caution.
|
||||
//
|
||||
// (3) System time. The system time provides a low-resolution (typically 10ms
|
||||
// to 55 milliseconds) time stamp but is comparatively less expensive to
|
||||
// retrieve and more reliable.
|
||||
class HighResNowSingleton {
|
||||
public:
|
||||
HighResNowSingleton()
|
||||
: ticks_per_microsecond_(0.0),
|
||||
skew_(0) {
|
||||
InitializeClock();
|
||||
|
||||
// On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
|
||||
// unreliable. Fallback to low-res clock.
|
||||
base::CPU cpu;
|
||||
if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15)
|
||||
DisableHighResClock();
|
||||
}
|
||||
|
||||
bool IsUsingHighResClock() {
|
||||
return ticks_per_microsecond_ != 0.0;
|
||||
}
|
||||
|
||||
void DisableHighResClock() {
|
||||
ticks_per_microsecond_ = 0.0;
|
||||
}
|
||||
|
||||
TimeDelta Now() {
|
||||
// Our maximum tolerance for QPC drifting.
|
||||
const int kMaxTimeDrift = 50 * Time::kMicrosecondsPerMillisecond;
|
||||
|
||||
if (IsUsingHighResClock()) {
|
||||
int64_t now = UnreliableNow();
|
||||
|
||||
// Verify that QPC does not seem to drift.
|
||||
DCHECK(now - ReliableNow() - skew_ < kMaxTimeDrift);
|
||||
|
||||
return TimeDelta::FromMicroseconds(now);
|
||||
}
|
||||
|
||||
// Just fallback to the slower clock.
|
||||
return Singleton<NowSingleton>::get()->Now();
|
||||
}
|
||||
|
||||
private:
|
||||
// Synchronize the QPC clock with GetSystemTimeAsFileTime.
|
||||
void InitializeClock() {
|
||||
LARGE_INTEGER ticks_per_sec = {{0}};
|
||||
if (!QueryPerformanceFrequency(&ticks_per_sec))
|
||||
return; // Broken, we don't guarantee this function works.
|
||||
ticks_per_microsecond_ = static_cast<float>(ticks_per_sec.QuadPart) /
|
||||
static_cast<float>(Time::kMicrosecondsPerSecond);
|
||||
|
||||
skew_ = UnreliableNow() - ReliableNow();
|
||||
}
|
||||
|
||||
// Get the number of microseconds since boot in a reliable fashion
|
||||
int64_t UnreliableNow() {
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
return static_cast<int64_t>(now.QuadPart / ticks_per_microsecond_);
|
||||
}
|
||||
|
||||
// Get the number of microseconds since boot in a reliable fashion
|
||||
int64_t ReliableNow() {
|
||||
return Singleton<NowSingleton>::get()->Now().InMicroseconds();
|
||||
}
|
||||
|
||||
// Cached clock frequency -> microseconds. This assumes that the clock
|
||||
// frequency is faster than one microsecond (which is 1MHz, should be OK).
|
||||
float ticks_per_microsecond_; // 0 indicates QPF failed and we're broken.
|
||||
int64_t skew_; // Skew between lo-res and hi-res clocks (for debugging).
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HighResNowSingleton);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
@ -269,3 +369,8 @@ TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
|
||||
TimeTicks TimeTicks::Now() {
|
||||
return TimeTicks() + Singleton<NowSingleton>::get()->Now();
|
||||
}
|
||||
|
||||
// static
|
||||
TimeTicks TimeTicks::HighResNow() {
|
||||
return TimeTicks() + Singleton<HighResNowSingleton>::get()->Now();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "base/object_watcher.h"
|
||||
#include "base/sys_info.h"
|
||||
|
||||
// Maximum amount of time (in milliseconds) to wait for the process to exit.
|
||||
static const int kWaitInterval = 2000;
|
||||
|
Loading…
Reference in New Issue
Block a user