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:
Coroiu Cristina 2017-12-21 20:59:02 +02:00
parent 7b5bcc482d
commit 72aaaf526b
14 changed files with 721 additions and 0 deletions

View File

@ -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',

View 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

View 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_

View File

@ -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 {

View File

@ -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)
{

View File

@ -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

View 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_

View 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

View 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

View 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

View File

@ -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;

View File

@ -197,4 +197,9 @@ TimeTicks TimeTicks::Now() {
return TimeTicks(absolute_micro);
}
// static
TimeTicks TimeTicks::HighResNow() {
return Now();
}
} // namespace base

View File

@ -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();
}

View File

@ -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;