| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/base/platform/time.h" | 5 #include "src/base/platform/time.h" |
| 6 | 6 |
| 7 #if V8_OS_POSIX | 7 #if V8_OS_POSIX |
| 8 #include <fcntl.h> // for O_RDONLY | 8 #include <fcntl.h> // for O_RDONLY |
| 9 #include <sys/time.h> | 9 #include <sys/time.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| 11 #endif | 11 #endif |
| 12 #if V8_OS_MACOSX | 12 #if V8_OS_MACOSX |
| 13 #include <mach/mach_time.h> | 13 #include <mach/mach_time.h> |
| 14 #endif | 14 #endif |
| 15 | 15 |
| 16 #include <cstring> | 16 #include <cstring> |
| 17 #include <ostream> | 17 #include <ostream> |
| 18 | 18 |
| 19 #if V8_OS_WIN | 19 #if V8_OS_WIN |
| 20 #include "src/base/lazy-instance.h" | 20 #include "src/base/lazy-instance.h" |
| 21 #include "src/base/win32-headers.h" | 21 #include "src/base/win32-headers.h" |
| 22 #endif | 22 #endif |
| 23 #include "src/base/atomicops.h" |
| 23 #include "src/base/cpu.h" | 24 #include "src/base/cpu.h" |
| 24 #include "src/base/logging.h" | 25 #include "src/base/logging.h" |
| 25 #include "src/base/platform/platform.h" | 26 #include "src/base/platform/platform.h" |
| 26 | 27 |
| 28 // CLOCK_REALTIME_COARSE was added in Linux 2.6.32. |
| 29 #if V8_OS_LINUX && !defined(CLOCK_REALTIME_COARSE) |
| 30 #define CLOCK_REALTIME_COARSE 5 |
| 31 #endif |
| 32 |
| 27 namespace v8 { | 33 namespace v8 { |
| 28 namespace base { | 34 namespace base { |
| 29 | 35 |
| 30 TimeDelta TimeDelta::FromDays(int days) { | 36 TimeDelta TimeDelta::FromDays(int days) { |
| 31 return TimeDelta(days * Time::kMicrosecondsPerDay); | 37 return TimeDelta(days * Time::kMicrosecondsPerDay); |
| 32 } | 38 } |
| 33 | 39 |
| 34 | 40 |
| 35 TimeDelta TimeDelta::FromHours(int hours) { | 41 TimeDelta TimeDelta::FromHours(int hours) { |
| 36 return TimeDelta(hours * Time::kMicrosecondsPerHour); | 42 return TimeDelta(hours * Time::kMicrosecondsPerHour); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 } | 251 } |
| 246 uint64_t us = static_cast<uint64_t>(us_ + kTimeToEpochInMicroseconds) * 10; | 252 uint64_t us = static_cast<uint64_t>(us_ + kTimeToEpochInMicroseconds) * 10; |
| 247 ft.dwLowDateTime = static_cast<DWORD>(us); | 253 ft.dwLowDateTime = static_cast<DWORD>(us); |
| 248 ft.dwHighDateTime = static_cast<DWORD>(us >> 32); | 254 ft.dwHighDateTime = static_cast<DWORD>(us >> 32); |
| 249 return ft; | 255 return ft; |
| 250 } | 256 } |
| 251 | 257 |
| 252 #elif V8_OS_POSIX | 258 #elif V8_OS_POSIX |
| 253 | 259 |
| 254 Time Time::Now() { | 260 Time Time::Now() { |
| 261 #ifdef CLOCK_REALTIME_COARSE |
| 262 struct timespec ts; |
| 263 static const clockid_t kInvalidClockId = static_cast<clockid_t>(-1); |
| 264 static clockid_t cached_clock_id = kInvalidClockId; |
| 265 clockid_t clock_id = NoBarrier_Load(&cached_clock_id); |
| 266 if (V8_UNLIKELY(clock_id == kInvalidClockId)) { |
| 267 // Use CLOCK_REALTIME_COARSE when available (linux >= 2.6.32) and precise |
| 268 // enough. Unlike CLOCK_REALTIME, its coarse cousin is normally serviced |
| 269 // from the vDSO, without making an actual system call. |
| 270 // |
| 271 // CLOCK_REALTIME_COARSE precision is determined by CONFIG_HZ, the number |
| 272 // of ticks per second that the kernel runs at. Granularity can be as low |
| 273 // as one update every few hundred milliseconds so we need to ensure it is |
| 274 // not _too_ coarse. Most kernels are built with CONFIG_HZ=1000, providing |
| 275 // a one millisecond precision that is good enough for our purposes. |
| 276 if (clock_getres(CLOCK_REALTIME_COARSE, &ts) < 0 || ts.tv_sec > 0 || |
| 277 ts.tv_nsec > 1000 * 1000) { |
| 278 clock_id = CLOCK_REALTIME; // Not available or not suitable. |
| 279 } else { |
| 280 clock_id = CLOCK_REALTIME_COARSE; |
| 281 } |
| 282 NoBarrier_Store(&cached_clock_id, clock_id); |
| 283 } |
| 284 int result = clock_gettime(clock_id, &ts); |
| 285 DCHECK_EQ(0, result); |
| 286 USE(result); |
| 287 return FromTimespec(ts); |
| 288 #else |
| 255 struct timeval tv; | 289 struct timeval tv; |
| 256 int result = gettimeofday(&tv, NULL); | 290 int result = gettimeofday(&tv, NULL); |
| 257 DCHECK_EQ(0, result); | 291 DCHECK_EQ(0, result); |
| 258 USE(result); | 292 USE(result); |
| 259 return FromTimeval(tv); | 293 return FromTimeval(tv); |
| 294 #endif |
| 260 } | 295 } |
| 261 | 296 |
| 262 | 297 |
| 263 Time Time::NowFromSystemTime() { | 298 Time Time::NowFromSystemTime() { |
| 264 return Now(); | 299 return Now(); |
| 265 } | 300 } |
| 266 | 301 |
| 267 | 302 |
| 268 Time Time::FromTimespec(struct timespec ts) { | 303 Time Time::FromTimespec(struct timespec ts) { |
| 269 DCHECK(ts.tv_nsec >= 0); | 304 DCHECK(ts.tv_nsec >= 0); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 | 673 |
| 639 | 674 |
| 640 // static | 675 // static |
| 641 bool TimeTicks::KernelTimestampAvailable() { | 676 bool TimeTicks::KernelTimestampAvailable() { |
| 642 return kernel_tick_clock.Pointer()->Available(); | 677 return kernel_tick_clock.Pointer()->Available(); |
| 643 } | 678 } |
| 644 | 679 |
| 645 #endif // V8_OS_WIN | 680 #endif // V8_OS_WIN |
| 646 | 681 |
| 647 } } // namespace v8::base | 682 } } // namespace v8::base |
| OLD | NEW |