1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
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_INCLUDE_TICK_UTIL_H_
15 #define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_TICK_UTIL_H_
16 
17 #if _WIN32
18 // Note: The Windows header must always be included before mmsystem.h
19 #include <windows.h>
20 #include <mmsystem.h>
21 #elif WEBRTC_LINUX
22 #include <time.h>
23 #elif WEBRTC_MAC
24 #include <mach/mach_time.h>
25 #include <string.h>
26 #else
27 #include <sys/time.h>
28 #include <time.h>
29 #endif
30 
31 #include "webrtc/typedefs.h"
32 
33 namespace webrtc {
34 
35 class TickInterval;
36 
37 // Class representing the current time.
38 class TickTime {
39  public:
40   TickTime();
41   explicit TickTime(int64_t ticks);
42 
43   // Current time in the tick domain.
44   static TickTime Now();
45 
46   // Now in the time domain in ms.
47   static int64_t MillisecondTimestamp();
48 
49   // Now in the time domain in us.
50   static int64_t MicrosecondTimestamp();
51 
52   // Returns the number of ticks in the tick domain.
53   int64_t Ticks() const;
54 
55   static int64_t MillisecondsToTicks(const int64_t ms);
56 
57   static int64_t TicksToMilliseconds(const int64_t ticks);
58 
59   static int64_t TicksToMicroseconds(const int64_t ticks);
60 
61   // Returns a TickTime that is ticks later than the passed TickTime.
62   friend TickTime operator+(const TickTime lhs, const int64_t ticks);
63   TickTime& operator+=(const int64_t& ticks);
64 
65   // Returns a TickInterval that is the difference in ticks beween rhs and lhs.
66   friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
67 
68  private:
69   static int64_t QueryOsForTicks();
70 
71   int64_t ticks_;
72 };
73 
74 // Represents a time delta in ticks.
75 class TickInterval {
76  public:
77   TickInterval();
78   explicit TickInterval(int64_t interval);
79 
80   int64_t Milliseconds() const;
81   int64_t Microseconds() const;
82 
83   // Returns the sum of two TickIntervals as a TickInterval.
84   friend TickInterval operator+(const TickInterval& lhs,
85                                 const TickInterval& rhs);
86   TickInterval& operator+=(const TickInterval& rhs);
87 
88   // Returns a TickInterval corresponding to rhs - lhs.
89   friend TickInterval operator-(const TickInterval& lhs,
90                                 const TickInterval& rhs);
91   TickInterval& operator-=(const TickInterval& rhs);
92 
93   friend bool operator>(const TickInterval& lhs, const TickInterval& rhs);
94   friend bool operator<=(const TickInterval& lhs, const TickInterval& rhs);
95   friend bool operator<(const TickInterval& lhs, const TickInterval& rhs);
96   friend bool operator>=(const TickInterval& lhs, const TickInterval& rhs);
97 
98  private:
99   friend class TickTime;
100   friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
101 
102  private:
103   int64_t interval_;
104 };
105 
Milliseconds()106 inline int64_t TickInterval::Milliseconds() const {
107   return TickTime::TicksToMilliseconds(interval_);
108 }
109 
Microseconds()110 inline int64_t TickInterval::Microseconds() const {
111   return TickTime::TicksToMicroseconds(interval_);
112 }
113 
114 inline TickInterval operator+(const TickInterval& lhs,
115                               const TickInterval& rhs) {
116   return TickInterval(lhs.interval_ + rhs.interval_);
117 }
118 
119 inline TickInterval operator-(const TickInterval& lhs,
120                               const TickInterval& rhs) {
121   return TickInterval(lhs.interval_ - rhs.interval_);
122 }
123 
124 inline TickInterval operator-(const TickTime& lhs, const TickTime& rhs) {
125   return TickInterval(lhs.ticks_ - rhs.ticks_);
126 }
127 
128 inline TickTime operator+(const TickTime lhs, const int64_t ticks) {
129   TickTime time = lhs;
130   time.ticks_ += ticks;
131   return time;
132 }
133 
134 inline bool operator>(const TickInterval& lhs, const TickInterval& rhs) {
135   return lhs.interval_ > rhs.interval_;
136 }
137 
138 inline bool operator<=(const TickInterval& lhs, const TickInterval& rhs) {
139   return lhs.interval_ <= rhs.interval_;
140 }
141 
142 inline bool operator<(const TickInterval& lhs, const TickInterval& rhs) {
143   return lhs.interval_ <= rhs.interval_;
144 }
145 
146 inline bool operator>=(const TickInterval& lhs, const TickInterval& rhs) {
147   return lhs.interval_ >= rhs.interval_;
148 }
149 
TickTime()150 inline TickTime::TickTime()
151     : ticks_(0) {
152 }
153 
TickTime(int64_t ticks)154 inline TickTime::TickTime(int64_t ticks)
155     : ticks_(ticks) {
156 }
157 
Now()158 inline TickTime TickTime::Now() {
159   return TickTime(QueryOsForTicks());
160 }
161 
Ticks()162 inline int64_t TickTime::Ticks() const {
163   return ticks_;
164 }
165 
166 inline TickTime& TickTime::operator+=(const int64_t& ticks) {
167   ticks_ += ticks;
168   return *this;
169 }
170 
TickInterval()171 inline TickInterval::TickInterval() : interval_(0) {
172 }
173 
TickInterval(const int64_t interval)174 inline TickInterval::TickInterval(const int64_t interval)
175   : interval_(interval) {
176 }
177 
178 inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) {
179   interval_ += rhs.interval_;
180   return *this;
181 }
182 
183 inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) {
184   interval_ -= rhs.interval_;
185   return *this;
186 }
187 
188 }  // namespace webrtc
189 
190 #endif  // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_TICK_UTIL_H_
191