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