Commit 537ed750 authored by ben's avatar ben Committed by Commit bot

Use CLOCK_REALTIME_COARSE when available.

On systems that have CLOCK_REALTIME_COARSE with good enough resolution, we can
avoid making a system call to get the current time; it's serviced from the vDSO.

BUG=
LOG=N

Review URL: https://codereview.chromium.org/1125003002

Cr-Commit-Position: refs/heads/master@{#28280}
parent 4b056526
......@@ -24,6 +24,11 @@
#include "src/base/logging.h"
#include "src/base/platform/platform.h"
// CLOCK_REALTIME_COARSE was added in Linux 2.6.32.
#if V8_OS_LINUX && !defined(CLOCK_REALTIME_COARSE)
#define CLOCK_REALTIME_COARSE 5
#endif
namespace v8 {
namespace base {
......@@ -252,11 +257,44 @@ FILETIME Time::ToFiletime() const {
#elif V8_OS_POSIX
Time Time::Now() {
#ifdef CLOCK_REALTIME_COARSE
struct timespec ts;
// clockid_t is an int32_t; loads and stores are atomic.
static const clockid_t kInvalidClockId = static_cast<clockid_t>(-1);
static clockid_t clock_id = kInvalidClockId;
if (V8_UNLIKELY(clock_id == kInvalidClockId)) {
// CLOCK_REALTIME_COARSE is not supported on Linux kernels < 2.6.32.
// Probe the kernel to see if it's available and has <= 1 ms resolution.
//
// CLOCK_REALTIME_COARSE, unlike CLOCK_REALTIME, can often be serviced
// entirely from the vDSO without the need to make a system call.
// It can have a dramatic impact on applications that frequently
// query the current time.
//
// One caveat is that CLOCK_REALTIME_COARSE is tied to CONFIG_HZ, the
// number of ticks per second that the kernel runs at. Its granularity
// can be as low as one update every 300 ms so we need to make sure that
// it is accurate enough. Fortunately, many if not most kernels are built
// with CONFIG_HZ=1000, giving it a one millisecond precision and that is
// good enough for our purposes.
if (clock_getres(CLOCK_REALTIME_COARSE, &ts) < 0 || ts.tv_sec > 0 ||
ts.tv_nsec > 1000 * 1000) {
clock_id = CLOCK_REALTIME; // Not available or not suitable.
} else {
clock_id = CLOCK_REALTIME_COARSE;
}
}
int result = clock_gettime(clock_id, &ts);
DCHECK_EQ(0, result);
USE(result);
return FromTimespec(ts);
#else
struct timeval tv;
int result = gettimeofday(&tv, NULL);
DCHECK_EQ(0, result);
USE(result);
return FromTimeval(tv);
#endif
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment