Chromium Code Reviews| Index: webrtc/base/timeutils.cc |
| diff --git a/webrtc/base/timeutils.cc b/webrtc/base/timeutils.cc |
| index de3e6afb28d824ecb9dfc26f1029dd0d0958fd24..f176589638e62ffbd341deabdd8a4c594db0e0f6 100644 |
| --- a/webrtc/base/timeutils.cc |
| +++ b/webrtc/base/timeutils.cc |
| @@ -32,50 +32,75 @@ namespace rtc { |
| const uint32_t HALF = 0x80000000; |
| -uint64_t TimeNanos() { |
| - int64_t ticks = 0; |
| #if defined(WEBRTC_MAC) |
| - static mach_timebase_info_data_t timebase; |
| - if (timebase.denom == 0) { |
| - // Get the timebase if this is the first time we run. |
| - // Recommended by Apple's QA1398. |
| - if (mach_timebase_info(&timebase) != KERN_SUCCESS) { |
| - RTC_DCHECK(false); |
| +class MacClock : public ClockInterface { |
| + uint64_t TimeNanos() const override { |
| + static mach_timebase_info_data_t timebase; |
| + if (timebase.denom == 0) { |
| + // Get the timebase if this is the first time we run. |
| + // Recommended by Apple's QA1398. |
| + if (mach_timebase_info(&timebase) != KERN_SUCCESS) { |
| + RTC_DCHECK(false); |
| + } |
| } |
| + // Use timebase to convert absolute time tick units into nanoseconds. |
| + return mach_absolute_time() * timebase.numer / timebase.denom; |
| } |
| - // Use timebase to convert absolute time tick units into nanoseconds. |
| - ticks = mach_absolute_time() * timebase.numer / timebase.denom; |
| +}; |
| +const MacClock default_clock_; |
|
pthatcher1
2016/05/24 18:05:46
Is Chrome going to be OK with this? They don't al
pthatcher1
2016/05/24 18:05:46
I think it would make more sense to do a typedef M
Taylor Brandstetter
2016/05/24 21:47:59
Done.
Taylor Brandstetter
2016/05/24 21:48:00
Good catch. Fixing this would need to use some kin
|
| #elif defined(WEBRTC_POSIX) |
| - struct timespec ts; |
| - // TODO: Do we need to handle the case when CLOCK_MONOTONIC |
| - // is not supported? |
| - clock_gettime(CLOCK_MONOTONIC, &ts); |
| - ticks = kNumNanosecsPerSec * static_cast<int64_t>(ts.tv_sec) + |
| - static_cast<int64_t>(ts.tv_nsec); |
| +class PosixClock : public ClockInterface { |
| + uint64_t TimeNanos() const override { |
| + struct timespec ts; |
| + // TODO(deadbeef): Do we need to handle the case when CLOCK_MONOTONIC |
| + // is not supported? |
| + clock_gettime(CLOCK_MONOTONIC, &ts); |
| + return kNumNanosecsPerSec * static_cast<int64_t>(ts.tv_sec) + |
| + static_cast<int64_t>(ts.tv_nsec); |
| + } |
| +}; |
| +const PosixClock default_clock_; |
| #elif defined(WEBRTC_WIN) |
| - static volatile LONG last_timegettime = 0; |
| - static volatile int64_t num_wrap_timegettime = 0; |
| - volatile LONG* last_timegettime_ptr = &last_timegettime; |
| - DWORD now = timeGetTime(); |
| - // Atomically update the last gotten time |
| - DWORD old = InterlockedExchange(last_timegettime_ptr, now); |
| - if (now < old) { |
| - // If now is earlier than old, there may have been a race between |
| - // threads. |
| - // 0x0fffffff ~3.1 days, the code will not take that long to execute |
| - // so it must have been a wrap around. |
| - if (old > 0xf0000000 && now < 0x0fffffff) { |
| - num_wrap_timegettime++; |
| +class WindowsClock : public ClockInterface { |
| + uint64_t TimeNanos() const override { |
| + int64_t ticks = 0; |
| + static volatile LONG last_timegettime = 0; |
| + static volatile int64_t num_wrap_timegettime = 0; |
| + volatile LONG* last_timegettime_ptr = &last_timegettime; |
| + DWORD now = timeGetTime(); |
| + // Atomically update the last gotten time |
| + DWORD old = InterlockedExchange(last_timegettime_ptr, now); |
| + if (now < old) { |
| + // If now is earlier than old, there may have been a race between |
| + // threads. |
| + // 0x0fffffff ~3.1 days, the code will not take that long to execute |
| + // so it must have been a wrap around. |
| + if (old > 0xf0000000 && now < 0x0fffffff) { |
| + num_wrap_timegettime++; |
| + } |
| } |
| + ticks = now + (num_wrap_timegettime << 32); |
| + // TODO(deadbeef): Calculate with nanosecond precision. Otherwise, we're |
| + // just wasting a multiply and divide when doing Time() on Windows. |
| + ticks = ticks * kNumNanosecsPerMillisec; |
| + return ticks; |
| } |
| - ticks = now + (num_wrap_timegettime << 32); |
| - // TODO: Calculate with nanosecond precision. Otherwise, we're just |
| - // wasting a multiply and divide when doing Time() on Windows. |
| - ticks = ticks * kNumNanosecsPerMillisec; |
| +}; |
| +const WindowsClock default_clock_; |
| +#elif defined(WEBRTC_WIN) |
| #else |
| #error Unsupported platform. |
| #endif |
| - return ticks; |
| + |
| +const ClockInterface* clock_ = &default_clock_; |
|
pthatcher1
2016/05/24 18:05:46
I've not seen other code where we have the member
Taylor Brandstetter
2016/05/24 21:47:59
I don't remember why I named it that, but it looks
|
| + |
| +void SetClock(ClockInterface* clock) { |
| + clock_ = clock ? clock : &default_clock_; |
|
pthatcher1
2016/05/24 18:05:46
Does this take ownership of the clock? Should it
Taylor Brandstetter
2016/05/24 21:48:00
No it doesn't; I made the comment in the header fi
|
| +} |
| + |
| +uint64_t TimeNanos() { |
| + RTC_CHECK(clock_); |
| + return clock_->TimeNanos(); |
|
pthatcher1
2016/05/24 18:05:46
I think instead of having a global clock that Time
Taylor Brandstetter
2016/05/24 21:47:59
It's feasible, and it would be ideal (since it wou
|
| } |
| uint32_t Time32() { |