aboutsummaryrefslogtreecommitdiff
path: root/src/system_wrappers/interface/tick_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/system_wrappers/interface/tick_util.h')
-rw-r--r--src/system_wrappers/interface/tick_util.h304
1 files changed, 304 insertions, 0 deletions
diff --git a/src/system_wrappers/interface/tick_util.h b/src/system_wrappers/interface/tick_util.h
new file mode 100644
index 0000000000..4c280677b5
--- /dev/null
+++ b/src/system_wrappers/interface/tick_util.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// System independant wrapper for polling elapsed time in ms and us.
+// The implementation works in the tick domain which can be mapped over to the
+// time domain.
+#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
+#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
+
+#if _WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#elif WEBRTC_LINUX
+#include <ctime>
+#else
+#include <sys/time.h>
+#include <time.h>
+#endif
+
+#include "typedefs.h"
+
+namespace webrtc {
+class TickInterval;
+
+class TickTime
+{
+public:
+ // 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 us.
+ static WebRtc_Word64 MicrosecondTimestamp();
+
+ WebRtc_Word64 Ticks() const;
+
+ static WebRtc_Word64 MillisecondsToTicks(const WebRtc_Word64 ms);
+
+ 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& rhs);
+
+
+ // Returns a TickInterval that is the difference in ticks beween rhs and lhs
+ friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
+private:
+ WebRtc_Word64 _ticks;
+};
+
+class TickInterval
+{
+public:
+ TickInterval();
+
+ 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 a TickInterval corresponding to rhs - lhs
+ friend TickInterval operator-(const TickInterval& lhs,
+ const TickInterval& rhs);
+ TickInterval& operator+=(const TickInterval& rhs);
+
+private:
+ TickInterval(WebRtc_Word64 interval);
+
+ friend class TickTime;
+ friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
+
+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 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 TickTime::Now()
+{
+ TickTime result;
+#if _WIN32
+ #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;
+ #ifdef WEBRTC_CLOCK_TYPE_REALTIME
+ clock_gettime(CLOCK_REALTIME, &ts);
+ #else
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ #endif
+ result._ticks = 1000000000LL * static_cast<WebRtc_Word64>(ts.tv_sec) + static_cast<WebRtc_Word64>(ts.tv_nsec);
+#else
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ result._ticks = 1000000LL * static_cast<WebRtc_Word64>(tv.tv_sec) + static_cast<WebRtc_Word64>(tv.tv_usec);
+#endif
+ return result;
+}
+
+inline WebRtc_Word64 TickTime::MillisecondTimestamp()
+{
+ TickTime now = TickTime::Now();
+#if _WIN32
+ #ifdef USE_QUERY_PERFORMANCE_COUNTER
+ LARGE_INTEGER qpfreq;
+ QueryPerformanceFrequency(&qpfreq);
+ return (now._ticks * 1000) / qpfreq.QuadPart;
+ #else
+ return now._ticks;
+ #endif
+#elif WEBRTC_LINUX
+ return now._ticks / 1000000LL;
+#else
+ return now._ticks / 1000LL;
+#endif
+}
+
+inline WebRtc_Word64 TickTime::MicrosecondTimestamp()
+{
+ TickTime now = TickTime::Now();
+
+#if _WIN32
+ #ifdef USE_QUERY_PERFORMANCE_COUNTER
+ LARGE_INTEGER qpfreq;
+ QueryPerformanceFrequency(&qpfreq);
+ return (now._ticks * 1000) / (qpfreq.QuadPart/1000);
+ #else
+ return now._ticks *1000LL;
+ #endif
+#elif WEBRTC_LINUX
+ return now._ticks / 1000LL;
+#else
+ return now._ticks;
+#endif
+}
+
+inline WebRtc_Word64 TickTime::Ticks() const
+{
+ return _ticks;
+}
+
+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 WEBRTC_LINUX
+ return ms * 1000000LL;
+#else
+ return ms * 1000LL;
+#endif
+}
+
+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 WEBRTC_LINUX
+ return ticks / 1000000LL;
+#else
+ return ticks / 1000LL;
+#endif
+}
+
+inline TickTime& TickTime::operator+=(const WebRtc_Word64& ticks)
+{
+ _ticks += ticks;
+ return *this;
+}
+
+inline TickInterval::TickInterval() : _interval(0)
+{
+}
+
+inline TickInterval::TickInterval(const WebRtc_Word64 interval)
+ : _interval(interval)
+{
+}
+
+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 WEBRTC_LINUX
+ // _interval is in ns
+ return _interval / 1000000;
+#else
+ // _interval is usecs
+ return _interval / 1000;
+#endif
+}
+
+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 WEBRTC_LINUX
+ // _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;
+}
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_