Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: webrtc/base/timeutils.cc

Issue 1895933003: Adding the ability to use a simulated clock for unit tests. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Responding to juberti@'s comments and adding myself as owner to ownerless TODOs. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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() {

Powered by Google App Engine
This is Rietveld 408576698