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/atomicops.h" |
20 #include "src/base/lazy-instance.h" | 21 #include "src/base/lazy-instance.h" |
21 #include "src/base/win32-headers.h" | 22 #include "src/base/win32-headers.h" |
22 #endif | 23 #endif |
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 |
27 namespace v8 { | 28 namespace v8 { |
28 namespace base { | 29 namespace base { |
29 | 30 |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 | 428 |
428 bool IsHighResolution() override { return true; } | 429 bool IsHighResolution() override { return true; } |
429 | 430 |
430 private: | 431 private: |
431 int64_t ticks_per_second_; | 432 int64_t ticks_per_second_; |
432 }; | 433 }; |
433 | 434 |
434 | 435 |
435 class RolloverProtectedTickClock final : public TickClock { | 436 class RolloverProtectedTickClock final : public TickClock { |
436 public: | 437 public: |
437 // We initialize rollover_ms_ to 1 to ensure that we will never | 438 RolloverProtectedTickClock() : rollover_(0) {} |
438 // return 0 from TimeTicks::HighResolutionNow() and TimeTicks::Now() below. | |
439 RolloverProtectedTickClock() : last_seen_now_(0), rollover_ms_(1) {} | |
440 virtual ~RolloverProtectedTickClock() {} | 439 virtual ~RolloverProtectedTickClock() {} |
441 | 440 |
442 int64_t Now() override { | 441 int64_t Now() override { |
443 LockGuard<Mutex> lock_guard(&mutex_); | |
444 // We use timeGetTime() to implement TimeTicks::Now(), which rolls over | 442 // We use timeGetTime() to implement TimeTicks::Now(), which rolls over |
445 // every ~49.7 days. We try to track rollover ourselves, which works if | 443 // every ~49.7 days. We try to track rollover ourselves, which works if |
446 // TimeTicks::Now() is called at least every 49 days. | 444 // TimeTicks::Now() is called at least every 24 days. |
447 // Note that we do not use GetTickCount() here, since timeGetTime() gives | 445 // Note that we do not use GetTickCount() here, since timeGetTime() gives |
448 // more predictable delta values, as described here: | 446 // more predictable delta values, as described here: |
449 // http://blogs.msdn.com/b/larryosterman/archive/2009/09/02/what-s-the-diffe
rence-between-gettickcount-and-timegettime.aspx | 447 // http://blogs.msdn.com/b/larryosterman/archive/2009/09/02/what-s-the-diffe
rence-between-gettickcount-and-timegettime.aspx |
450 // timeGetTime() provides 1ms granularity when combined with | 448 // timeGetTime() provides 1ms granularity when combined with |
451 // timeBeginPeriod(). If the host application for V8 wants fast timers, it | 449 // timeBeginPeriod(). If the host application for V8 wants fast timers, it |
452 // can use timeBeginPeriod() to increase the resolution. | 450 // can use timeBeginPeriod() to increase the resolution. |
453 DWORD now = timeGetTime(); | 451 // We use a lock-free version because the sampler thread calls it |
454 if (now < last_seen_now_) { | 452 // while having the rest of the world stopped, that could cause a deadlock. |
455 rollover_ms_ += V8_INT64_C(0x100000000); // ~49.7 days. | 453 base::Atomic32 rollover = base::Acquire_Load(&rollover_); |
| 454 uint32_t now = static_cast<uint32_t>(timeGetTime()); |
| 455 if ((now >> 31) != static_cast<uint32_t>(rollover & 1)) { |
| 456 base::Release_CompareAndSwap(&rollover_, rollover, rollover + 1); |
| 457 ++rollover; |
456 } | 458 } |
457 last_seen_now_ = now; | 459 uint64_t ms = (static_cast<uint64_t>(rollover) << 31) | now; |
458 return (now + rollover_ms_) * Time::kMicrosecondsPerMillisecond; | 460 return static_cast<int64_t>(ms * Time::kMicrosecondsPerMillisecond); |
459 } | 461 } |
460 | 462 |
461 bool IsHighResolution() override { return false; } | 463 bool IsHighResolution() override { return false; } |
462 | 464 |
463 private: | 465 private: |
464 Mutex mutex_; | 466 base::Atomic32 rollover_; |
465 DWORD last_seen_now_; | |
466 int64_t rollover_ms_; | |
467 }; | 467 }; |
468 | 468 |
469 | 469 |
470 static LazyStaticInstance<RolloverProtectedTickClock, | 470 static LazyStaticInstance<RolloverProtectedTickClock, |
471 DefaultConstructTrait<RolloverProtectedTickClock>, | 471 DefaultConstructTrait<RolloverProtectedTickClock>, |
472 ThreadSafeInitOnceTrait>::type tick_clock = | 472 ThreadSafeInitOnceTrait>::type tick_clock = |
473 LAZY_STATIC_INSTANCE_INITIALIZER; | 473 LAZY_STATIC_INSTANCE_INITIALIZER; |
474 | 474 |
475 | 475 |
476 struct CreateHighResTickClockTrait { | 476 struct CreateHighResTickClockTrait { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 | 638 |
639 | 639 |
640 // static | 640 // static |
641 bool TimeTicks::KernelTimestampAvailable() { | 641 bool TimeTicks::KernelTimestampAvailable() { |
642 return kernel_tick_clock.Pointer()->Available(); | 642 return kernel_tick_clock.Pointer()->Available(); |
643 } | 643 } |
644 | 644 |
645 #endif // V8_OS_WIN | 645 #endif // V8_OS_WIN |
646 | 646 |
647 } } // namespace v8::base | 647 } } // namespace v8::base |
OLD | NEW |