diff --git a/webrtc/system_wrappers/interface/tick_util.h b/webrtc/system_wrappers/interface/tick_util.h index 019c80036..acd16a523 100644 --- a/webrtc/system_wrappers/interface/tick_util.h +++ b/webrtc/system_wrappers/interface/tick_util.h @@ -15,6 +15,7 @@ #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ #if _WIN32 +// Note: These includes must be in this order since mmsystem depends on windows. #include #include #elif WEBRTC_LINUX @@ -27,359 +28,339 @@ #include #endif -#include "typedefs.h" +#include "webrtc/typedefs.h" namespace webrtc { + class TickInterval; -// Class representing the current time. This class is immutable. -class TickTime -{ -public: - TickTime(); - explicit TickTime(WebRtc_Word64 ticks); +// Class representing the current time. +class TickTime { + public: + TickTime(); + explicit TickTime(WebRtc_Word64 ticks); - // Current time in the tick domain. - static TickTime Now(); + // Current time in the tick domain. + static TickTime Now(); - // Now in the time domain in ms. - static WebRtc_Word64 MillisecondTimestamp(); + // Now in the time domain in ms. + static WebRtc_Word64 MillisecondTimestamp(); - // Now in the time domain in us. - static WebRtc_Word64 MicrosecondTimestamp(); + // Now in the time domain in us. + static WebRtc_Word64 MicrosecondTimestamp(); - // Returns the number of ticks in the tick domain. - WebRtc_Word64 Ticks() const; + // Returns the number of ticks in the tick domain. + WebRtc_Word64 Ticks() const; - static WebRtc_Word64 MillisecondsToTicks(const WebRtc_Word64 ms); + static WebRtc_Word64 MillisecondsToTicks(const WebRtc_Word64 ms); - static WebRtc_Word64 TicksToMilliseconds(const WebRtc_Word64 ticks); + static WebRtc_Word64 TicksToMilliseconds(const WebRtc_Word64 ticks); - // Returns a TickTime that is ticks later than the passed TickTime - friend TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks); - TickTime& operator+=(const WebRtc_Word64& ticks); + // Returns a TickTime that is ticks later than the passed TickTime. + friend TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks); + TickTime& operator+=(const WebRtc_Word64& ticks); - // Returns a TickInterval that is the difference in ticks beween rhs and lhs - friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs); + // Returns a TickInterval that is the difference in ticks beween rhs and lhs. + friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs); - // Call to engage the fake clock. This is useful for tests since relying on - // a real clock often makes the test flaky. - static void UseFakeClock(WebRtc_Word64 start_millisecond); + // Call to engage the fake clock. This is useful for tests since relying on + // a real clock often makes the test flaky. + static void UseFakeClock(WebRtc_Word64 start_millisecond); - // Advance the fake clock. Must be called after UseFakeClock. - static void AdvanceFakeClock(WebRtc_Word64 milliseconds); + // Advance the fake clock. Must be called after UseFakeClock. + static void AdvanceFakeClock(WebRtc_Word64 milliseconds); -private: - static WebRtc_Word64 QueryOsForTicks(); + private: + static WebRtc_Word64 QueryOsForTicks(); - static bool _use_fake_clock; - static WebRtc_Word64 _fake_ticks; + static bool use_fake_clock_; + static WebRtc_Word64 fake_ticks_; - WebRtc_Word64 _ticks; + WebRtc_Word64 ticks_; }; -// Reperesents a time delta in ticks. This class is immutable. -class TickInterval -{ -public: - TickInterval(); +// Represents a time delta in ticks. +class TickInterval { + public: + TickInterval(); - WebRtc_Word64 Milliseconds() const; - WebRtc_Word64 Microseconds() const; + WebRtc_Word64 Milliseconds() const; + WebRtc_Word64 Microseconds() const; - // Returns the sum of two TickIntervals as a TickInterval - friend TickInterval operator+(const TickInterval& lhs, - const TickInterval& rhs); - TickInterval& operator+=(const TickInterval& rhs); + // Returns the sum of two TickIntervals as a TickInterval. + friend TickInterval operator+(const TickInterval& lhs, + const TickInterval& rhs); + TickInterval& operator+=(const TickInterval& rhs); - // Returns a TickInterval corresponding to rhs - lhs - friend TickInterval operator-(const TickInterval& lhs, - const TickInterval& rhs); - TickInterval& operator-=(const TickInterval& rhs); + // Returns a TickInterval corresponding to rhs - lhs. + friend TickInterval operator-(const TickInterval& lhs, + const TickInterval& rhs); + TickInterval& operator-=(const TickInterval& rhs); - friend bool operator>(const TickInterval& lhs, const TickInterval& rhs); - friend bool operator<=(const TickInterval& lhs, const TickInterval& rhs); - friend bool operator<(const TickInterval& lhs, const TickInterval& rhs); - friend bool operator>=(const TickInterval& lhs, const TickInterval& rhs); + friend bool operator>(const TickInterval& lhs, const TickInterval& rhs); + friend bool operator<=(const TickInterval& lhs, const TickInterval& rhs); + friend bool operator<(const TickInterval& lhs, const TickInterval& rhs); + friend bool operator>=(const TickInterval& lhs, const TickInterval& rhs); -private: - TickInterval(WebRtc_Word64 interval); + private: + explicit TickInterval(WebRtc_Word64 interval); - friend class TickTime; - friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs); + friend class TickTime; + friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs); -private: - WebRtc_Word64 _interval; + private: + WebRtc_Word64 interval_; }; -inline TickInterval operator+(const TickInterval& lhs, const TickInterval& rhs) -{ - return TickInterval(lhs._interval + rhs._interval); +inline TickInterval operator+(const TickInterval& lhs, + const TickInterval& rhs) { + return TickInterval(lhs.interval_ + rhs.interval_); } -inline TickInterval operator-(const TickInterval& lhs, const TickInterval& rhs) -{ - return TickInterval(lhs._interval - rhs._interval); +inline TickInterval operator-(const TickInterval& lhs, + const TickInterval& rhs) { + return TickInterval(lhs.interval_ - rhs.interval_); } -inline TickInterval operator-(const TickTime& lhs,const TickTime& rhs) -{ - return TickInterval(lhs._ticks - rhs._ticks); +inline TickInterval operator-(const TickTime& lhs, const TickTime& rhs) { + return TickInterval(lhs.ticks_ - rhs.ticks_); } -inline TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks) -{ - TickTime time = lhs; - time._ticks += ticks; - return time; +inline TickTime operator+(const TickTime lhs, const WebRtc_Word64 ticks) { + TickTime time = lhs; + time.ticks_ += ticks; + return time; } -inline bool operator>(const TickInterval& lhs, const TickInterval& rhs) -{ - return lhs._interval > rhs._interval; +inline bool operator>(const TickInterval& lhs, const TickInterval& rhs) { + return lhs.interval_ > rhs.interval_; } -inline bool operator<=(const TickInterval& lhs, const TickInterval& rhs) -{ - return lhs._interval <= rhs._interval; +inline bool operator<=(const TickInterval& lhs, const TickInterval& rhs) { + return lhs.interval_ <= rhs.interval_; } -inline bool operator<(const TickInterval& lhs, const TickInterval& rhs) -{ - return lhs._interval <= rhs._interval; +inline bool operator<(const TickInterval& lhs, const TickInterval& rhs) { + return lhs.interval_ <= rhs.interval_; } -inline bool operator>=(const TickInterval& lhs, const TickInterval& rhs) -{ - return lhs._interval >= rhs._interval; +inline bool operator>=(const TickInterval& lhs, const TickInterval& rhs) { + return lhs.interval_ >= rhs.interval_; } inline TickTime::TickTime() - : _ticks(0) { + : ticks_(0) { } inline TickTime::TickTime(WebRtc_Word64 ticks) - : _ticks(ticks) { + : ticks_(ticks) { } -inline TickTime TickTime::Now() -{ - if (_use_fake_clock) - return TickTime(_fake_ticks); +inline TickTime TickTime::Now() { + if (use_fake_clock_) + return TickTime(fake_ticks_); else return TickTime(QueryOsForTicks()); } inline WebRtc_Word64 TickTime::QueryOsForTicks() { - TickTime result; + TickTime result; #if _WIN32 - // TODO(wu): Remove QueryPerformanceCounter implementation. - #ifdef USE_QUERY_PERFORMANCE_COUNTER - // QueryPerformanceCounter returns the value from the TSC which is - // incremented at the CPU frequency. The algorithm used requires - // the CPU frequency to be constant. Technology like speed stepping - // which has variable CPU frequency will therefore yield unpredictable, - // incorrect time estimations. - LARGE_INTEGER qpcnt; - QueryPerformanceCounter(&qpcnt); - result._ticks = qpcnt.QuadPart; - #else - static volatile LONG lastTimeGetTime = 0; - static volatile WebRtc_Word64 numWrapTimeGetTime = 0; - volatile LONG* lastTimeGetTimePtr = &lastTimeGetTime; - DWORD now = timeGetTime(); - // Atomically update the last gotten time - DWORD old = InterlockedExchange(lastTimeGetTimePtr, 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) - { - numWrapTimeGetTime++; - } - } - result._ticks = now + (numWrapTimeGetTime<<32); - #endif -#elif defined(WEBRTC_LINUX) - struct timespec ts; - // TODO(wu): Remove CLOCK_REALTIME implementation. - #ifdef WEBRTC_CLOCK_TYPE_REALTIME - clock_gettime(CLOCK_REALTIME, &ts); - #else - clock_gettime(CLOCK_MONOTONIC, &ts); - #endif - result._ticks = 1000000000LL * static_cast(ts.tv_sec) + static_cast(ts.tv_nsec); -#elif 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. - kern_return_t retval = mach_timebase_info(&timebase); - if (retval != KERN_SUCCESS) { - // TODO(wu): Implement CHECK similar to chrome for all the platforms. - // Then replace this with a CHECK(retval == KERN_SUCCESS); -#ifndef WEBRTC_IOS - asm("int3"); + // TODO(wu): Remove QueryPerformanceCounter implementation. +#ifdef USE_QUERY_PERFORMANCE_COUNTER + // QueryPerformanceCounter returns the value from the TSC which is + // incremented at the CPU frequency. The algorithm used requires + // the CPU frequency to be constant. Technology like speed stepping + // which has variable CPU frequency will therefore yield unpredictable, + // incorrect time estimations. + LARGE_INTEGER qpcnt; + QueryPerformanceCounter(&qpcnt); + result.ticks_ = qpcnt.QuadPart; #else - __builtin_trap(); -#endif // WEBRTC_IOS - } + static volatile LONG last_time_get_time = 0; + static volatile WebRtc_Word64 num_wrap_time_get_time = 0; + volatile LONG* last_time_get_time_ptr = &last_time_get_time; + DWORD now = timeGetTime(); + // Atomically update the last gotten time + DWORD old = InterlockedExchange(last_time_get_time_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_time_get_time++; } - // Use timebase to convert absolute time tick units into nanoseconds. - result._ticks = mach_absolute_time() * timebase.numer / timebase.denom; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - result._ticks = 1000000LL * static_cast(tv.tv_sec) + static_cast(tv.tv_usec); + } + result.ticks_ = now + (num_wrap_time_get_time << 32); #endif - return result._ticks; +#elif defined(WEBRTC_LINUX) + struct timespec ts; + // TODO(wu): Remove CLOCK_REALTIME implementation. +#ifdef WEBRTC_CLOCK_TYPE_REALTIME + clock_gettime(CLOCK_REALTIME, &ts); +#else + clock_gettime(CLOCK_MONOTONIC, &ts); +#endif + result.ticks_ = 1000000000LL * static_cast(ts.tv_sec) + + static_cast(ts.tv_nsec); +#elif 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. + kern_return_t retval = mach_timebase_info(&timebase); + if (retval != KERN_SUCCESS) { + // TODO(wu): Implement CHECK similar to chrome for all the platforms. + // Then replace this with a CHECK(retval == KERN_SUCCESS); +#ifndef WEBRTC_IOS + asm("int3"); +#else + __builtin_trap(); +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ + } + } + // Use timebase to convert absolute time tick units into nanoseconds. + result.ticks_ = mach_absolute_time() * timebase.numer / timebase.denom; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + result.ticks_ = 1000000LL * static_cast(tv.tv_sec) + + static_cast(tv.tv_usec); +#endif + return result.ticks_; } -inline WebRtc_Word64 TickTime::MillisecondTimestamp() -{ +inline WebRtc_Word64 TickTime::MillisecondTimestamp() { WebRtc_Word64 ticks = TickTime::Now().Ticks(); #if _WIN32 - #ifdef USE_QUERY_PERFORMANCE_COUNTER - LARGE_INTEGER qpfreq; - QueryPerformanceFrequency(&qpfreq); - return (ticks * 1000) / qpfreq.QuadPart; - #else - return ticks; - #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - return ticks / 1000000LL; +#ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (ticks * 1000) / qpfreq.QuadPart; #else - return ticks / 1000LL; + return ticks; +#endif +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + return ticks / 1000000LL; +#else + return ticks / 1000LL; #endif } -inline WebRtc_Word64 TickTime::MicrosecondTimestamp() -{ +inline WebRtc_Word64 TickTime::MicrosecondTimestamp() { WebRtc_Word64 ticks = TickTime::Now().Ticks(); #if _WIN32 - #ifdef USE_QUERY_PERFORMANCE_COUNTER - LARGE_INTEGER qpfreq; - QueryPerformanceFrequency(&qpfreq); - return (ticks * 1000) / (qpfreq.QuadPart/1000); - #else - return ticks *1000LL; - #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - return ticks / 1000LL; +#ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (ticks * 1000) / (qpfreq.QuadPart / 1000); #else - return ticks; + return ticks * 1000LL; +#endif +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + return ticks / 1000LL; +#else + return ticks; #endif } -inline WebRtc_Word64 TickTime::Ticks() const -{ - return _ticks; +inline WebRtc_Word64 TickTime::Ticks() const { + return ticks_; } -inline WebRtc_Word64 TickTime::MillisecondsToTicks(const WebRtc_Word64 ms) -{ +inline WebRtc_Word64 TickTime::MillisecondsToTicks(const WebRtc_Word64 ms) { #if _WIN32 - #ifdef USE_QUERY_PERFORMANCE_COUNTER - LARGE_INTEGER qpfreq; - QueryPerformanceFrequency(&qpfreq); - return (qpfreq.QuadPart * ms) / 1000; - #else - return ms; - #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - return ms * 1000000LL; +#ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (qpfreq.QuadPart * ms) / 1000; #else - return ms * 1000LL; + return ms; +#endif +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + return ms * 1000000LL; +#else + return ms * 1000LL; #endif } -inline WebRtc_Word64 TickTime::TicksToMilliseconds(const WebRtc_Word64 ticks) -{ +inline WebRtc_Word64 TickTime::TicksToMilliseconds(const WebRtc_Word64 ticks) { #if _WIN32 - #ifdef USE_QUERY_PERFORMANCE_COUNTER - LARGE_INTEGER qpfreq; - QueryPerformanceFrequency(&qpfreq); - return (ticks * 1000) / qpfreq.QuadPart; - #else - return ticks; - #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - return ticks / 1000000LL; +#ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (ticks * 1000) / qpfreq.QuadPart; #else - return ticks / 1000LL; + return ticks; +#endif +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + return ticks / 1000000LL; +#else + return ticks / 1000LL; #endif } -inline TickTime& TickTime::operator+=(const WebRtc_Word64& ticks) -{ - _ticks += ticks; - return *this; +inline TickTime& TickTime::operator+=(const WebRtc_Word64& ticks) { + ticks_ += ticks; + return *this; } -inline TickInterval::TickInterval() : _interval(0) -{ +inline TickInterval::TickInterval() : interval_(0) { } inline TickInterval::TickInterval(const WebRtc_Word64 interval) - : _interval(interval) -{ + : interval_(interval) { } -inline WebRtc_Word64 TickInterval::Milliseconds() const -{ +inline WebRtc_Word64 TickInterval::Milliseconds() const { #if _WIN32 - #ifdef USE_QUERY_PERFORMANCE_COUNTER - LARGE_INTEGER qpfreq; - QueryPerformanceFrequency(&qpfreq); - return (_interval * 1000) / qpfreq.QuadPart; - #else - // _interval is in ms - return _interval; - #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - // _interval is in ns - return _interval / 1000000; +#ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (interval_ * 1000) / qpfreq.QuadPart; #else - // _interval is usecs - return _interval / 1000; + // interval_ is in ms + return interval_; +#endif +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + // interval_ is in ns + return interval_ / 1000000; +#else + // interval_ is usecs + return interval_ / 1000; #endif } -inline WebRtc_Word64 TickInterval::Microseconds() const -{ +inline WebRtc_Word64 TickInterval::Microseconds() const { #if _WIN32 - #ifdef USE_QUERY_PERFORMANCE_COUNTER - LARGE_INTEGER qpfreq; - QueryPerformanceFrequency(&qpfreq); - return (_interval * 1000000) / qpfreq.QuadPart; - #else - // _interval is in ms - return _interval *1000LL; - #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - // _interval is in ns - return _interval / 1000; +#ifdef USE_QUERY_PERFORMANCE_COUNTER + LARGE_INTEGER qpfreq; + QueryPerformanceFrequency(&qpfreq); + return (interval_ * 1000000) / qpfreq.QuadPart; #else - // _interval is usecs - return _interval; + // interval_ is in ms + return interval_ * 1000LL; +#endif +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + // interval_ is in ns + return interval_ / 1000; +#else + // interval_ is usecs + return interval_; #endif } -inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) -{ - _interval += rhs._interval; - return *this; +inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) { + interval_ += rhs.interval_; + return *this; } -inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) -{ - _interval -= rhs._interval; - return *this; +inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) { + interval_ -= rhs.interval_; + return *this; } -} // namespace webrtc +} // namespace webrtc -#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ +#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_ diff --git a/webrtc/system_wrappers/source/tick_util.cc b/webrtc/system_wrappers/source/tick_util.cc index b6ebc11a8..a9957568c 100644 --- a/webrtc/system_wrappers/source/tick_util.cc +++ b/webrtc/system_wrappers/source/tick_util.cc @@ -8,23 +8,23 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "system_wrappers/interface/tick_util.h" +#include "webrtc/system_wrappers/interface/tick_util.h" #include namespace webrtc { -bool TickTime::_use_fake_clock = false; -WebRtc_Word64 TickTime::_fake_ticks = 0; +bool TickTime::use_fake_clock_ = false; +WebRtc_Word64 TickTime::fake_ticks_ = 0; void TickTime::UseFakeClock(WebRtc_Word64 start_millisecond) { - _use_fake_clock = true; - _fake_ticks = MillisecondsToTicks(start_millisecond); + use_fake_clock_ = true; + fake_ticks_ = MillisecondsToTicks(start_millisecond); } void TickTime::AdvanceFakeClock(WebRtc_Word64 milliseconds) { - assert(_use_fake_clock); - _fake_ticks += MillisecondsToTicks(milliseconds); + assert(use_fake_clock_); + fake_ticks_ += MillisecondsToTicks(milliseconds); } } // namespace webrtc