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> |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 92 |
93 | 93 |
94 int64_t TimeDelta::InNanoseconds() const { | 94 int64_t TimeDelta::InNanoseconds() const { |
95 return delta_ * Time::kNanosecondsPerMicrosecond; | 95 return delta_ * Time::kNanosecondsPerMicrosecond; |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 #if V8_OS_MACOSX | 99 #if V8_OS_MACOSX |
100 | 100 |
101 TimeDelta TimeDelta::FromMachTimespec(struct mach_timespec ts) { | 101 TimeDelta TimeDelta::FromMachTimespec(struct mach_timespec ts) { |
102 ASSERT_GE(ts.tv_nsec, 0); | 102 DCHECK_GE(ts.tv_nsec, 0); |
103 ASSERT_LT(ts.tv_nsec, | 103 DCHECK_LT(ts.tv_nsec, |
104 static_cast<long>(Time::kNanosecondsPerSecond)); // NOLINT | 104 static_cast<long>(Time::kNanosecondsPerSecond)); // NOLINT |
105 return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond + | 105 return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond + |
106 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); | 106 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); |
107 } | 107 } |
108 | 108 |
109 | 109 |
110 struct mach_timespec TimeDelta::ToMachTimespec() const { | 110 struct mach_timespec TimeDelta::ToMachTimespec() const { |
111 struct mach_timespec ts; | 111 struct mach_timespec ts; |
112 ASSERT(delta_ >= 0); | 112 DCHECK(delta_ >= 0); |
113 ts.tv_sec = delta_ / Time::kMicrosecondsPerSecond; | 113 ts.tv_sec = delta_ / Time::kMicrosecondsPerSecond; |
114 ts.tv_nsec = (delta_ % Time::kMicrosecondsPerSecond) * | 114 ts.tv_nsec = (delta_ % Time::kMicrosecondsPerSecond) * |
115 Time::kNanosecondsPerMicrosecond; | 115 Time::kNanosecondsPerMicrosecond; |
116 return ts; | 116 return ts; |
117 } | 117 } |
118 | 118 |
119 #endif // V8_OS_MACOSX | 119 #endif // V8_OS_MACOSX |
120 | 120 |
121 | 121 |
122 #if V8_OS_POSIX | 122 #if V8_OS_POSIX |
123 | 123 |
124 TimeDelta TimeDelta::FromTimespec(struct timespec ts) { | 124 TimeDelta TimeDelta::FromTimespec(struct timespec ts) { |
125 ASSERT_GE(ts.tv_nsec, 0); | 125 DCHECK_GE(ts.tv_nsec, 0); |
126 ASSERT_LT(ts.tv_nsec, | 126 DCHECK_LT(ts.tv_nsec, |
127 static_cast<long>(Time::kNanosecondsPerSecond)); // NOLINT | 127 static_cast<long>(Time::kNanosecondsPerSecond)); // NOLINT |
128 return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond + | 128 return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond + |
129 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); | 129 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 struct timespec TimeDelta::ToTimespec() const { | 133 struct timespec TimeDelta::ToTimespec() const { |
134 struct timespec ts; | 134 struct timespec ts; |
135 ts.tv_sec = delta_ / Time::kMicrosecondsPerSecond; | 135 ts.tv_sec = delta_ / Time::kMicrosecondsPerSecond; |
136 ts.tv_nsec = (delta_ % Time::kMicrosecondsPerSecond) * | 136 ts.tv_nsec = (delta_ % Time::kMicrosecondsPerSecond) * |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 ft.dwHighDateTime == std::numeric_limits<DWORD>::max()) { | 223 ft.dwHighDateTime == std::numeric_limits<DWORD>::max()) { |
224 return Max(); | 224 return Max(); |
225 } | 225 } |
226 int64_t us = (static_cast<uint64_t>(ft.dwLowDateTime) + | 226 int64_t us = (static_cast<uint64_t>(ft.dwLowDateTime) + |
227 (static_cast<uint64_t>(ft.dwHighDateTime) << 32)) / 10; | 227 (static_cast<uint64_t>(ft.dwHighDateTime) << 32)) / 10; |
228 return Time(us - kTimeToEpochInMicroseconds); | 228 return Time(us - kTimeToEpochInMicroseconds); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 FILETIME Time::ToFiletime() const { | 232 FILETIME Time::ToFiletime() const { |
233 ASSERT(us_ >= 0); | 233 DCHECK(us_ >= 0); |
234 FILETIME ft; | 234 FILETIME ft; |
235 if (IsNull()) { | 235 if (IsNull()) { |
236 ft.dwLowDateTime = 0; | 236 ft.dwLowDateTime = 0; |
237 ft.dwHighDateTime = 0; | 237 ft.dwHighDateTime = 0; |
238 return ft; | 238 return ft; |
239 } | 239 } |
240 if (IsMax()) { | 240 if (IsMax()) { |
241 ft.dwLowDateTime = std::numeric_limits<DWORD>::max(); | 241 ft.dwLowDateTime = std::numeric_limits<DWORD>::max(); |
242 ft.dwHighDateTime = std::numeric_limits<DWORD>::max(); | 242 ft.dwHighDateTime = std::numeric_limits<DWORD>::max(); |
243 return ft; | 243 return ft; |
244 } | 244 } |
245 uint64_t us = static_cast<uint64_t>(us_ + kTimeToEpochInMicroseconds) * 10; | 245 uint64_t us = static_cast<uint64_t>(us_ + kTimeToEpochInMicroseconds) * 10; |
246 ft.dwLowDateTime = static_cast<DWORD>(us); | 246 ft.dwLowDateTime = static_cast<DWORD>(us); |
247 ft.dwHighDateTime = static_cast<DWORD>(us >> 32); | 247 ft.dwHighDateTime = static_cast<DWORD>(us >> 32); |
248 return ft; | 248 return ft; |
249 } | 249 } |
250 | 250 |
251 #elif V8_OS_POSIX | 251 #elif V8_OS_POSIX |
252 | 252 |
253 Time Time::Now() { | 253 Time Time::Now() { |
254 struct timeval tv; | 254 struct timeval tv; |
255 int result = gettimeofday(&tv, NULL); | 255 int result = gettimeofday(&tv, NULL); |
256 ASSERT_EQ(0, result); | 256 DCHECK_EQ(0, result); |
257 USE(result); | 257 USE(result); |
258 return FromTimeval(tv); | 258 return FromTimeval(tv); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 Time Time::NowFromSystemTime() { | 262 Time Time::NowFromSystemTime() { |
263 return Now(); | 263 return Now(); |
264 } | 264 } |
265 | 265 |
266 | 266 |
267 Time Time::FromTimespec(struct timespec ts) { | 267 Time Time::FromTimespec(struct timespec ts) { |
268 ASSERT(ts.tv_nsec >= 0); | 268 DCHECK(ts.tv_nsec >= 0); |
269 ASSERT(ts.tv_nsec < static_cast<long>(kNanosecondsPerSecond)); // NOLINT | 269 DCHECK(ts.tv_nsec < static_cast<long>(kNanosecondsPerSecond)); // NOLINT |
270 if (ts.tv_nsec == 0 && ts.tv_sec == 0) { | 270 if (ts.tv_nsec == 0 && ts.tv_sec == 0) { |
271 return Time(); | 271 return Time(); |
272 } | 272 } |
273 if (ts.tv_nsec == static_cast<long>(kNanosecondsPerSecond - 1) && // NOLINT | 273 if (ts.tv_nsec == static_cast<long>(kNanosecondsPerSecond - 1) && // NOLINT |
274 ts.tv_sec == std::numeric_limits<time_t>::max()) { | 274 ts.tv_sec == std::numeric_limits<time_t>::max()) { |
275 return Max(); | 275 return Max(); |
276 } | 276 } |
277 return Time(ts.tv_sec * kMicrosecondsPerSecond + | 277 return Time(ts.tv_sec * kMicrosecondsPerSecond + |
278 ts.tv_nsec / kNanosecondsPerMicrosecond); | 278 ts.tv_nsec / kNanosecondsPerMicrosecond); |
279 } | 279 } |
(...skipping 11 matching lines...) Expand all Loading... |
291 ts.tv_nsec = static_cast<long>(kNanosecondsPerSecond - 1); // NOLINT | 291 ts.tv_nsec = static_cast<long>(kNanosecondsPerSecond - 1); // NOLINT |
292 return ts; | 292 return ts; |
293 } | 293 } |
294 ts.tv_sec = us_ / kMicrosecondsPerSecond; | 294 ts.tv_sec = us_ / kMicrosecondsPerSecond; |
295 ts.tv_nsec = (us_ % kMicrosecondsPerSecond) * kNanosecondsPerMicrosecond; | 295 ts.tv_nsec = (us_ % kMicrosecondsPerSecond) * kNanosecondsPerMicrosecond; |
296 return ts; | 296 return ts; |
297 } | 297 } |
298 | 298 |
299 | 299 |
300 Time Time::FromTimeval(struct timeval tv) { | 300 Time Time::FromTimeval(struct timeval tv) { |
301 ASSERT(tv.tv_usec >= 0); | 301 DCHECK(tv.tv_usec >= 0); |
302 ASSERT(tv.tv_usec < static_cast<suseconds_t>(kMicrosecondsPerSecond)); | 302 DCHECK(tv.tv_usec < static_cast<suseconds_t>(kMicrosecondsPerSecond)); |
303 if (tv.tv_usec == 0 && tv.tv_sec == 0) { | 303 if (tv.tv_usec == 0 && tv.tv_sec == 0) { |
304 return Time(); | 304 return Time(); |
305 } | 305 } |
306 if (tv.tv_usec == static_cast<suseconds_t>(kMicrosecondsPerSecond - 1) && | 306 if (tv.tv_usec == static_cast<suseconds_t>(kMicrosecondsPerSecond - 1) && |
307 tv.tv_sec == std::numeric_limits<time_t>::max()) { | 307 tv.tv_sec == std::numeric_limits<time_t>::max()) { |
308 return Max(); | 308 return Max(); |
309 } | 309 } |
310 return Time(tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec); | 310 return Time(tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec); |
311 } | 311 } |
312 | 312 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 // With recent updates on HAL and newer BIOS, QPC is getting more reliable but | 390 // With recent updates on HAL and newer BIOS, QPC is getting more reliable but |
391 // it should be used with caution. | 391 // it should be used with caution. |
392 // | 392 // |
393 // (3) System time. The system time provides a low-resolution (typically 10ms | 393 // (3) System time. The system time provides a low-resolution (typically 10ms |
394 // to 55 milliseconds) time stamp but is comparatively less expensive to | 394 // to 55 milliseconds) time stamp but is comparatively less expensive to |
395 // retrieve and more reliable. | 395 // retrieve and more reliable. |
396 class HighResolutionTickClock V8_FINAL : public TickClock { | 396 class HighResolutionTickClock V8_FINAL : public TickClock { |
397 public: | 397 public: |
398 explicit HighResolutionTickClock(int64_t ticks_per_second) | 398 explicit HighResolutionTickClock(int64_t ticks_per_second) |
399 : ticks_per_second_(ticks_per_second) { | 399 : ticks_per_second_(ticks_per_second) { |
400 ASSERT_LT(0, ticks_per_second); | 400 DCHECK_LT(0, ticks_per_second); |
401 } | 401 } |
402 virtual ~HighResolutionTickClock() {} | 402 virtual ~HighResolutionTickClock() {} |
403 | 403 |
404 virtual int64_t Now() V8_OVERRIDE { | 404 virtual int64_t Now() V8_OVERRIDE { |
405 LARGE_INTEGER now; | 405 LARGE_INTEGER now; |
406 BOOL result = QueryPerformanceCounter(&now); | 406 BOOL result = QueryPerformanceCounter(&now); |
407 ASSERT(result); | 407 DCHECK(result); |
408 USE(result); | 408 USE(result); |
409 | 409 |
410 // Intentionally calculate microseconds in a round about manner to avoid | 410 // Intentionally calculate microseconds in a round about manner to avoid |
411 // overflow and precision issues. Think twice before simplifying! | 411 // overflow and precision issues. Think twice before simplifying! |
412 int64_t whole_seconds = now.QuadPart / ticks_per_second_; | 412 int64_t whole_seconds = now.QuadPart / ticks_per_second_; |
413 int64_t leftover_ticks = now.QuadPart % ticks_per_second_; | 413 int64_t leftover_ticks = now.QuadPart % ticks_per_second_; |
414 int64_t ticks = (whole_seconds * Time::kMicrosecondsPerSecond) + | 414 int64_t ticks = (whole_seconds * Time::kMicrosecondsPerSecond) + |
415 ((leftover_ticks * Time::kMicrosecondsPerSecond) / ticks_per_second_); | 415 ((leftover_ticks * Time::kMicrosecondsPerSecond) / ticks_per_second_); |
416 | 416 |
417 // Make sure we never return 0 here, so that TimeTicks::HighResolutionNow() | 417 // Make sure we never return 0 here, so that TimeTicks::HighResolutionNow() |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 493 |
494 | 494 |
495 static LazyDynamicInstance<TickClock, CreateHighResTickClockTrait, | 495 static LazyDynamicInstance<TickClock, CreateHighResTickClockTrait, |
496 ThreadSafeInitOnceTrait>::type high_res_tick_clock = | 496 ThreadSafeInitOnceTrait>::type high_res_tick_clock = |
497 LAZY_DYNAMIC_INSTANCE_INITIALIZER; | 497 LAZY_DYNAMIC_INSTANCE_INITIALIZER; |
498 | 498 |
499 | 499 |
500 TimeTicks TimeTicks::Now() { | 500 TimeTicks TimeTicks::Now() { |
501 // Make sure we never return 0 here. | 501 // Make sure we never return 0 here. |
502 TimeTicks ticks(tick_clock.Pointer()->Now()); | 502 TimeTicks ticks(tick_clock.Pointer()->Now()); |
503 ASSERT(!ticks.IsNull()); | 503 DCHECK(!ticks.IsNull()); |
504 return ticks; | 504 return ticks; |
505 } | 505 } |
506 | 506 |
507 | 507 |
508 TimeTicks TimeTicks::HighResolutionNow() { | 508 TimeTicks TimeTicks::HighResolutionNow() { |
509 // Make sure we never return 0 here. | 509 // Make sure we never return 0 here. |
510 TimeTicks ticks(high_res_tick_clock.Pointer()->Now()); | 510 TimeTicks ticks(high_res_tick_clock.Pointer()->Now()); |
511 ASSERT(!ticks.IsNull()); | 511 DCHECK(!ticks.IsNull()); |
512 return ticks; | 512 return ticks; |
513 } | 513 } |
514 | 514 |
515 | 515 |
516 // static | 516 // static |
517 bool TimeTicks::IsHighResolutionClockWorking() { | 517 bool TimeTicks::IsHighResolutionClockWorking() { |
518 return high_res_tick_clock.Pointer()->IsHighResolution(); | 518 return high_res_tick_clock.Pointer()->IsHighResolution(); |
519 } | 519 } |
520 | 520 |
521 | 521 |
(...skipping 10 matching lines...) Expand all Loading... |
532 return HighResolutionNow(); | 532 return HighResolutionNow(); |
533 } | 533 } |
534 | 534 |
535 | 535 |
536 TimeTicks TimeTicks::HighResolutionNow() { | 536 TimeTicks TimeTicks::HighResolutionNow() { |
537 int64_t ticks; | 537 int64_t ticks; |
538 #if V8_OS_MACOSX | 538 #if V8_OS_MACOSX |
539 static struct mach_timebase_info info; | 539 static struct mach_timebase_info info; |
540 if (info.denom == 0) { | 540 if (info.denom == 0) { |
541 kern_return_t result = mach_timebase_info(&info); | 541 kern_return_t result = mach_timebase_info(&info); |
542 ASSERT_EQ(KERN_SUCCESS, result); | 542 DCHECK_EQ(KERN_SUCCESS, result); |
543 USE(result); | 543 USE(result); |
544 } | 544 } |
545 ticks = (mach_absolute_time() / Time::kNanosecondsPerMicrosecond * | 545 ticks = (mach_absolute_time() / Time::kNanosecondsPerMicrosecond * |
546 info.numer / info.denom); | 546 info.numer / info.denom); |
547 #elif V8_OS_SOLARIS | 547 #elif V8_OS_SOLARIS |
548 ticks = (gethrtime() / Time::kNanosecondsPerMicrosecond); | 548 ticks = (gethrtime() / Time::kNanosecondsPerMicrosecond); |
549 #elif V8_LIBRT_NOT_AVAILABLE | 549 #elif V8_LIBRT_NOT_AVAILABLE |
550 // TODO(bmeurer): This is a temporary hack to support cross-compiling | 550 // TODO(bmeurer): This is a temporary hack to support cross-compiling |
551 // Chrome for Android in AOSP. Remove this once AOSP is fixed, also | 551 // Chrome for Android in AOSP. Remove this once AOSP is fixed, also |
552 // cleanup the tools/gyp/v8.gyp file. | 552 // cleanup the tools/gyp/v8.gyp file. |
553 struct timeval tv; | 553 struct timeval tv; |
554 int result = gettimeofday(&tv, NULL); | 554 int result = gettimeofday(&tv, NULL); |
555 ASSERT_EQ(0, result); | 555 DCHECK_EQ(0, result); |
556 USE(result); | 556 USE(result); |
557 ticks = (tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec); | 557 ticks = (tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec); |
558 #elif V8_OS_POSIX | 558 #elif V8_OS_POSIX |
559 struct timespec ts; | 559 struct timespec ts; |
560 int result = clock_gettime(CLOCK_MONOTONIC, &ts); | 560 int result = clock_gettime(CLOCK_MONOTONIC, &ts); |
561 ASSERT_EQ(0, result); | 561 DCHECK_EQ(0, result); |
562 USE(result); | 562 USE(result); |
563 ticks = (ts.tv_sec * Time::kMicrosecondsPerSecond + | 563 ticks = (ts.tv_sec * Time::kMicrosecondsPerSecond + |
564 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); | 564 ts.tv_nsec / Time::kNanosecondsPerMicrosecond); |
565 #endif // V8_OS_MACOSX | 565 #endif // V8_OS_MACOSX |
566 // Make sure we never return 0 here. | 566 // Make sure we never return 0 here. |
567 return TimeTicks(ticks + 1); | 567 return TimeTicks(ticks + 1); |
568 } | 568 } |
569 | 569 |
570 | 570 |
571 // static | 571 // static |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 | 645 |
646 | 646 |
647 // static | 647 // static |
648 bool TimeTicks::KernelTimestampAvailable() { | 648 bool TimeTicks::KernelTimestampAvailable() { |
649 return kernel_tick_clock.Pointer()->Available(); | 649 return kernel_tick_clock.Pointer()->Available(); |
650 } | 650 } |
651 | 651 |
652 #endif // V8_OS_WIN | 652 #endif // V8_OS_WIN |
653 | 653 |
654 } } // namespace v8::base | 654 } } // namespace v8::base |
OLD | NEW |