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/cpu.h" | 23 #include "src/base/cpu.h" |
24 #include "src/base/logging.h" | 24 #include "src/base/logging.h" |
25 #include "src/base/platform/platform.h" | 25 #include "src/base/platform/platform.h" |
26 | 26 |
27 // CLOCK_REALTIME_COARSE was added in Linux 2.6.32. | |
28 #if V8_OS_LINUX && !defined(CLOCK_REALTIME_COARSE) | |
29 #define CLOCK_REALTIME_COARSE 5 | |
30 #endif | |
31 | |
32 namespace v8 { | 27 namespace v8 { |
33 namespace base { | 28 namespace base { |
34 | 29 |
35 TimeDelta TimeDelta::FromDays(int days) { | 30 TimeDelta TimeDelta::FromDays(int days) { |
36 return TimeDelta(days * Time::kMicrosecondsPerDay); | 31 return TimeDelta(days * Time::kMicrosecondsPerDay); |
37 } | 32 } |
38 | 33 |
39 | 34 |
40 TimeDelta TimeDelta::FromHours(int hours) { | 35 TimeDelta TimeDelta::FromHours(int hours) { |
41 return TimeDelta(hours * Time::kMicrosecondsPerHour); | 36 return TimeDelta(hours * Time::kMicrosecondsPerHour); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 } | 245 } |
251 uint64_t us = static_cast<uint64_t>(us_ + kTimeToEpochInMicroseconds) * 10; | 246 uint64_t us = static_cast<uint64_t>(us_ + kTimeToEpochInMicroseconds) * 10; |
252 ft.dwLowDateTime = static_cast<DWORD>(us); | 247 ft.dwLowDateTime = static_cast<DWORD>(us); |
253 ft.dwHighDateTime = static_cast<DWORD>(us >> 32); | 248 ft.dwHighDateTime = static_cast<DWORD>(us >> 32); |
254 return ft; | 249 return ft; |
255 } | 250 } |
256 | 251 |
257 #elif V8_OS_POSIX | 252 #elif V8_OS_POSIX |
258 | 253 |
259 Time Time::Now() { | 254 Time Time::Now() { |
260 #ifdef CLOCK_REALTIME_COARSE | |
261 struct timespec ts; | |
262 // clockid_t is an int32_t; loads and stores are atomic. | |
263 static const clockid_t kInvalidClockId = static_cast<clockid_t>(-1); | |
264 static clockid_t clock_id = kInvalidClockId; | |
265 if (V8_UNLIKELY(clock_id == kInvalidClockId)) { | |
266 // CLOCK_REALTIME_COARSE is not supported on Linux kernels < 2.6.32. | |
267 // Probe the kernel to see if it's available and has <= 1 ms resolution. | |
268 // | |
269 // CLOCK_REALTIME_COARSE, unlike CLOCK_REALTIME, can often be serviced | |
270 // entirely from the vDSO without the need to make a system call. | |
271 // It can have a dramatic impact on applications that frequently | |
272 // query the current time. | |
273 // | |
274 // One caveat is that CLOCK_REALTIME_COARSE is tied to CONFIG_HZ, the | |
275 // number of ticks per second that the kernel runs at. Its granularity | |
276 // can be as low as one update every 300 ms so we need to make sure that | |
277 // it is accurate enough. Fortunately, many if not most kernels are built | |
278 // with CONFIG_HZ=1000, giving it a one millisecond precision and that is | |
279 // good enough for our purposes. | |
280 if (clock_getres(CLOCK_REALTIME_COARSE, &ts) < 0 || ts.tv_sec > 0 || | |
281 ts.tv_nsec > 1000 * 1000) { | |
282 clock_id = CLOCK_REALTIME; // Not available or not suitable. | |
283 } else { | |
284 clock_id = CLOCK_REALTIME_COARSE; | |
285 } | |
286 } | |
287 int result = clock_gettime(clock_id, &ts); | |
288 DCHECK_EQ(0, result); | |
289 USE(result); | |
290 return FromTimespec(ts); | |
291 #else | |
292 struct timeval tv; | 255 struct timeval tv; |
293 int result = gettimeofday(&tv, NULL); | 256 int result = gettimeofday(&tv, NULL); |
294 DCHECK_EQ(0, result); | 257 DCHECK_EQ(0, result); |
295 USE(result); | 258 USE(result); |
296 return FromTimeval(tv); | 259 return FromTimeval(tv); |
297 #endif | |
298 } | 260 } |
299 | 261 |
300 | 262 |
301 Time Time::NowFromSystemTime() { | 263 Time Time::NowFromSystemTime() { |
302 return Now(); | 264 return Now(); |
303 } | 265 } |
304 | 266 |
305 | 267 |
306 Time Time::FromTimespec(struct timespec ts) { | 268 Time Time::FromTimespec(struct timespec ts) { |
307 DCHECK(ts.tv_nsec >= 0); | 269 DCHECK(ts.tv_nsec >= 0); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 | 638 |
677 | 639 |
678 // static | 640 // static |
679 bool TimeTicks::KernelTimestampAvailable() { | 641 bool TimeTicks::KernelTimestampAvailable() { |
680 return kernel_tick_clock.Pointer()->Available(); | 642 return kernel_tick_clock.Pointer()->Available(); |
681 } | 643 } |
682 | 644 |
683 #endif // V8_OS_WIN | 645 #endif // V8_OS_WIN |
684 | 646 |
685 } } // namespace v8::base | 647 } } // namespace v8::base |
OLD | NEW |