blob: 7e7d799dd3b8c48f97e182487391116df4acd4c5 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
wu@webrtc.org6e6ea042012-03-12 19:42:22 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// System independant wrapper for polling elapsed time in ms and us.
12// The implementation works in the tick domain which can be mapped over to the
13// time domain.
14#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
15#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
16
17#if _WIN32
pbos@webrtc.orgacaf3a12013-05-27 15:07:45 +000018// Note: The Windows header must always be included before mmsystem.h
niklase@google.com470e71d2011-07-07 08:21:25 +000019#include <windows.h>
20#include <mmsystem.h>
21#elif WEBRTC_LINUX
22#include <ctime>
wu@webrtc.org6e6ea042012-03-12 19:42:22 +000023#elif WEBRTC_MAC
24#include <mach/mach_time.h>
25#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000026#else
27#include <sys/time.h>
28#include <time.h>
29#endif
30
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000031#include "webrtc/typedefs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000032
33namespace webrtc {
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000034
niklase@google.com470e71d2011-07-07 08:21:25 +000035class TickInterval;
36
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000037// Class representing the current time.
38class TickTime {
39 public:
40 TickTime();
pbos@webrtc.org046deb92013-04-09 09:06:11 +000041 explicit TickTime(int64_t ticks);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000042
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000043 // Current time in the tick domain.
44 static TickTime Now();
niklase@google.com470e71d2011-07-07 08:21:25 +000045
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000046 // Now in the time domain in ms.
pbos@webrtc.org046deb92013-04-09 09:06:11 +000047 static int64_t MillisecondTimestamp();
niklase@google.com470e71d2011-07-07 08:21:25 +000048
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000049 // Now in the time domain in us.
pbos@webrtc.org046deb92013-04-09 09:06:11 +000050 static int64_t MicrosecondTimestamp();
niklase@google.com470e71d2011-07-07 08:21:25 +000051
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000052 // Returns the number of ticks in the tick domain.
pbos@webrtc.org046deb92013-04-09 09:06:11 +000053 int64_t Ticks() const;
niklase@google.com470e71d2011-07-07 08:21:25 +000054
pbos@webrtc.org046deb92013-04-09 09:06:11 +000055 static int64_t MillisecondsToTicks(const int64_t ms);
niklase@google.com470e71d2011-07-07 08:21:25 +000056
pbos@webrtc.org046deb92013-04-09 09:06:11 +000057 static int64_t TicksToMilliseconds(const int64_t ticks);
niklase@google.com470e71d2011-07-07 08:21:25 +000058
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000059 // Returns a TickTime that is ticks later than the passed TickTime.
pbos@webrtc.org046deb92013-04-09 09:06:11 +000060 friend TickTime operator+(const TickTime lhs, const int64_t ticks);
61 TickTime& operator+=(const int64_t& ticks);
niklase@google.com470e71d2011-07-07 08:21:25 +000062
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000063 // Returns a TickInterval that is the difference in ticks beween rhs and lhs.
64 friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000065
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000066 // Call to engage the fake clock. This is useful for tests since relying on
67 // a real clock often makes the test flaky.
pbos@webrtc.org046deb92013-04-09 09:06:11 +000068 static void UseFakeClock(int64_t start_millisecond);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000069
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000070 // Advance the fake clock. Must be called after UseFakeClock.
pbos@webrtc.org046deb92013-04-09 09:06:11 +000071 static void AdvanceFakeClock(int64_t milliseconds);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000072
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000073 private:
pbos@webrtc.org046deb92013-04-09 09:06:11 +000074 static int64_t QueryOsForTicks();
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000075
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000076 static bool use_fake_clock_;
pbos@webrtc.org046deb92013-04-09 09:06:11 +000077 static int64_t fake_ticks_;
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +000078
pbos@webrtc.org046deb92013-04-09 09:06:11 +000079 int64_t ticks_;
niklase@google.com470e71d2011-07-07 08:21:25 +000080};
81
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000082// Represents a time delta in ticks.
83class TickInterval {
84 public:
85 TickInterval();
niklase@google.com470e71d2011-07-07 08:21:25 +000086
pbos@webrtc.org046deb92013-04-09 09:06:11 +000087 int64_t Milliseconds() const;
88 int64_t Microseconds() const;
niklase@google.com470e71d2011-07-07 08:21:25 +000089
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000090 // Returns the sum of two TickIntervals as a TickInterval.
91 friend TickInterval operator+(const TickInterval& lhs,
92 const TickInterval& rhs);
93 TickInterval& operator+=(const TickInterval& rhs);
niklase@google.com470e71d2011-07-07 08:21:25 +000094
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +000095 // Returns a TickInterval corresponding to rhs - lhs.
96 friend TickInterval operator-(const TickInterval& lhs,
97 const TickInterval& rhs);
98 TickInterval& operator-=(const TickInterval& rhs);
niklase@google.com470e71d2011-07-07 08:21:25 +000099
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000100 friend bool operator>(const TickInterval& lhs, const TickInterval& rhs);
101 friend bool operator<=(const TickInterval& lhs, const TickInterval& rhs);
102 friend bool operator<(const TickInterval& lhs, const TickInterval& rhs);
103 friend bool operator>=(const TickInterval& lhs, const TickInterval& rhs);
kjellander@webrtc.org9e7774f2011-09-23 11:33:31 +0000104
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000105 private:
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000106 explicit TickInterval(int64_t interval);
niklase@google.com470e71d2011-07-07 08:21:25 +0000107
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000108 friend class TickTime;
109 friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000110
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000111 private:
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000112 int64_t interval_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000113};
114
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000115inline TickInterval operator+(const TickInterval& lhs,
116 const TickInterval& rhs) {
117 return TickInterval(lhs.interval_ + rhs.interval_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000118}
119
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000120inline TickInterval operator-(const TickInterval& lhs,
121 const TickInterval& rhs) {
122 return TickInterval(lhs.interval_ - rhs.interval_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000123}
124
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000125inline TickInterval operator-(const TickTime& lhs, const TickTime& rhs) {
126 return TickInterval(lhs.ticks_ - rhs.ticks_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000127}
128
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000129inline TickTime operator+(const TickTime lhs, const int64_t ticks) {
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000130 TickTime time = lhs;
131 time.ticks_ += ticks;
132 return time;
niklase@google.com470e71d2011-07-07 08:21:25 +0000133}
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000134
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000135inline bool operator>(const TickInterval& lhs, const TickInterval& rhs) {
136 return lhs.interval_ > rhs.interval_;
kjellander@webrtc.org9e7774f2011-09-23 11:33:31 +0000137}
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000138
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000139inline bool operator<=(const TickInterval& lhs, const TickInterval& rhs) {
140 return lhs.interval_ <= rhs.interval_;
kjellander@webrtc.org9e7774f2011-09-23 11:33:31 +0000141}
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000142
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000143inline bool operator<(const TickInterval& lhs, const TickInterval& rhs) {
144 return lhs.interval_ <= rhs.interval_;
kjellander@webrtc.org9e7774f2011-09-23 11:33:31 +0000145}
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000146
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000147inline bool operator>=(const TickInterval& lhs, const TickInterval& rhs) {
148 return lhs.interval_ >= rhs.interval_;
kjellander@webrtc.org9e7774f2011-09-23 11:33:31 +0000149}
niklase@google.com470e71d2011-07-07 08:21:25 +0000150
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000151inline TickTime::TickTime()
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000152 : ticks_(0) {
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000153}
154
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000155inline TickTime::TickTime(int64_t ticks)
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000156 : ticks_(ticks) {
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000157}
158
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000159inline TickTime TickTime::Now() {
160 if (use_fake_clock_)
161 return TickTime(fake_ticks_);
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000162 else
163 return TickTime(QueryOsForTicks());
164}
165
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000166inline int64_t TickTime::MillisecondTimestamp() {
167 int64_t ticks = TickTime::Now().Ticks();
niklase@google.com470e71d2011-07-07 08:21:25 +0000168#if _WIN32
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000169#ifdef USE_QUERY_PERFORMANCE_COUNTER
170 LARGE_INTEGER qpfreq;
171 QueryPerformanceFrequency(&qpfreq);
172 return (ticks * 1000) / qpfreq.QuadPart;
niklase@google.com470e71d2011-07-07 08:21:25 +0000173#else
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000174 return ticks;
175#endif
176#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
177 return ticks / 1000000LL;
178#else
179 return ticks / 1000LL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000180#endif
181}
182
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000183inline int64_t TickTime::MicrosecondTimestamp() {
184 int64_t ticks = TickTime::Now().Ticks();
niklase@google.com470e71d2011-07-07 08:21:25 +0000185#if _WIN32
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000186#ifdef USE_QUERY_PERFORMANCE_COUNTER
187 LARGE_INTEGER qpfreq;
188 QueryPerformanceFrequency(&qpfreq);
189 return (ticks * 1000) / (qpfreq.QuadPart / 1000);
niklase@google.com470e71d2011-07-07 08:21:25 +0000190#else
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000191 return ticks * 1000LL;
192#endif
193#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
194 return ticks / 1000LL;
195#else
196 return ticks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000197#endif
198}
199
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000200inline int64_t TickTime::Ticks() const {
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000201 return ticks_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000202}
203
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000204inline int64_t TickTime::MillisecondsToTicks(const int64_t ms) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000205#if _WIN32
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000206#ifdef USE_QUERY_PERFORMANCE_COUNTER
207 LARGE_INTEGER qpfreq;
208 QueryPerformanceFrequency(&qpfreq);
209 return (qpfreq.QuadPart * ms) / 1000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000210#else
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000211 return ms;
212#endif
213#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
214 return ms * 1000000LL;
215#else
216 return ms * 1000LL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000217#endif
218}
219
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000220inline int64_t TickTime::TicksToMilliseconds(const int64_t ticks) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000221#if _WIN32
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000222#ifdef USE_QUERY_PERFORMANCE_COUNTER
223 LARGE_INTEGER qpfreq;
224 QueryPerformanceFrequency(&qpfreq);
225 return (ticks * 1000) / qpfreq.QuadPart;
niklase@google.com470e71d2011-07-07 08:21:25 +0000226#else
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000227 return ticks;
228#endif
229#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
230 return ticks / 1000000LL;
231#else
232 return ticks / 1000LL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000233#endif
234}
235
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000236inline TickTime& TickTime::operator+=(const int64_t& ticks) {
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000237 ticks_ += ticks;
238 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +0000239}
240
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000241inline TickInterval::TickInterval() : interval_(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000242}
243
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000244inline TickInterval::TickInterval(const int64_t interval)
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000245 : interval_(interval) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000246}
247
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000248inline int64_t TickInterval::Milliseconds() const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000249#if _WIN32
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000250#ifdef USE_QUERY_PERFORMANCE_COUNTER
251 LARGE_INTEGER qpfreq;
252 QueryPerformanceFrequency(&qpfreq);
253 return (interval_ * 1000) / qpfreq.QuadPart;
niklase@google.com470e71d2011-07-07 08:21:25 +0000254#else
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000255 // interval_ is in ms
256 return interval_;
257#endif
258#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
259 // interval_ is in ns
260 return interval_ / 1000000;
261#else
262 // interval_ is usecs
263 return interval_ / 1000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000264#endif
265}
266
pbos@webrtc.org046deb92013-04-09 09:06:11 +0000267inline int64_t TickInterval::Microseconds() const {
niklase@google.com470e71d2011-07-07 08:21:25 +0000268#if _WIN32
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000269#ifdef USE_QUERY_PERFORMANCE_COUNTER
270 LARGE_INTEGER qpfreq;
271 QueryPerformanceFrequency(&qpfreq);
272 return (interval_ * 1000000) / qpfreq.QuadPart;
niklase@google.com470e71d2011-07-07 08:21:25 +0000273#else
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000274 // interval_ is in ms
275 return interval_ * 1000LL;
276#endif
277#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
278 // interval_ is in ns
279 return interval_ / 1000;
280#else
281 // interval_ is usecs
282 return interval_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000283#endif
284}
285
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000286inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) {
287 interval_ += rhs.interval_;
288 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +0000289}
290
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000291inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) {
292 interval_ -= rhs.interval_;
293 return *this;
niklase@google.com470e71d2011-07-07 08:21:25 +0000294}
phoglund@webrtc.org4cebe6c2012-11-07 13:37:19 +0000295
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000296} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000297
phoglund@webrtc.org5c8d9d32013-01-03 09:50:17 +0000298#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_