Home | History | Annotate | Download | only in interface
      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_INTERFACE_TICK_UTIL_H_
     15 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_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   // Returns a TickTime that is ticks later than the passed TickTime.
     60   friend TickTime operator+(const TickTime lhs, const int64_t ticks);
     61   TickTime& operator+=(const int64_t& ticks);
     62 
     63   // Returns a TickInterval that is the difference in ticks beween rhs and lhs.
     64   friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
     65 
     66   // Call to engage the fake clock. This is useful for tests since relying on
     67   // a real clock often makes the test flaky.
     68   static void UseFakeClock(int64_t start_millisecond);
     69 
     70   // Advance the fake clock. Must be called after UseFakeClock.
     71   static void AdvanceFakeClock(int64_t milliseconds);
     72 
     73  private:
     74   static int64_t QueryOsForTicks();
     75 
     76   static bool use_fake_clock_;
     77   static int64_t fake_ticks_;
     78 
     79   int64_t ticks_;
     80 };
     81 
     82 // Represents a time delta in ticks.
     83 class TickInterval {
     84  public:
     85   TickInterval();
     86 
     87   int64_t Milliseconds() const;
     88   int64_t Microseconds() const;
     89 
     90   // 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);
     94 
     95   // Returns a TickInterval corresponding to rhs - lhs.
     96   friend TickInterval operator-(const TickInterval& lhs,
     97                                 const TickInterval& rhs);
     98   TickInterval& operator-=(const TickInterval& rhs);
     99 
    100   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);
    104 
    105  private:
    106   explicit TickInterval(int64_t interval);
    107 
    108   friend class TickTime;
    109   friend TickInterval operator-(const TickTime& lhs, const TickTime& rhs);
    110 
    111  private:
    112   int64_t interval_;
    113 };
    114 
    115 inline TickInterval operator+(const TickInterval& lhs,
    116                               const TickInterval& rhs) {
    117   return TickInterval(lhs.interval_ + rhs.interval_);
    118 }
    119 
    120 inline TickInterval operator-(const TickInterval& lhs,
    121                               const TickInterval& rhs) {
    122   return TickInterval(lhs.interval_ - rhs.interval_);
    123 }
    124 
    125 inline TickInterval operator-(const TickTime& lhs, const TickTime& rhs) {
    126   return TickInterval(lhs.ticks_ - rhs.ticks_);
    127 }
    128 
    129 inline TickTime operator+(const TickTime lhs, const int64_t ticks) {
    130   TickTime time = lhs;
    131   time.ticks_ += ticks;
    132   return time;
    133 }
    134 
    135 inline bool operator>(const TickInterval& lhs, const TickInterval& rhs) {
    136   return lhs.interval_ > rhs.interval_;
    137 }
    138 
    139 inline bool operator<=(const TickInterval& lhs, const TickInterval& rhs) {
    140   return lhs.interval_ <= rhs.interval_;
    141 }
    142 
    143 inline bool operator<(const TickInterval& lhs, const TickInterval& rhs) {
    144   return lhs.interval_ <= rhs.interval_;
    145 }
    146 
    147 inline bool operator>=(const TickInterval& lhs, const TickInterval& rhs) {
    148   return lhs.interval_ >= rhs.interval_;
    149 }
    150 
    151 inline TickTime::TickTime()
    152     : ticks_(0) {
    153 }
    154 
    155 inline TickTime::TickTime(int64_t ticks)
    156     : ticks_(ticks) {
    157 }
    158 
    159 inline TickTime TickTime::Now() {
    160   if (use_fake_clock_)
    161     return TickTime(fake_ticks_);
    162   else
    163     return TickTime(QueryOsForTicks());
    164 }
    165 
    166 inline int64_t TickTime::MillisecondTimestamp() {
    167   int64_t ticks = TickTime::Now().Ticks();
    168 #if _WIN32
    169 #ifdef USE_QUERY_PERFORMANCE_COUNTER
    170   LARGE_INTEGER qpfreq;
    171   QueryPerformanceFrequency(&qpfreq);
    172   return (ticks * 1000) / qpfreq.QuadPart;
    173 #else
    174   return ticks;
    175 #endif
    176 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
    177   return ticks / 1000000LL;
    178 #else
    179   return ticks / 1000LL;
    180 #endif
    181 }
    182 
    183 inline int64_t TickTime::MicrosecondTimestamp() {
    184   int64_t ticks = TickTime::Now().Ticks();
    185 #if _WIN32
    186 #ifdef USE_QUERY_PERFORMANCE_COUNTER
    187   LARGE_INTEGER qpfreq;
    188   QueryPerformanceFrequency(&qpfreq);
    189   return (ticks * 1000) / (qpfreq.QuadPart / 1000);
    190 #else
    191   return ticks * 1000LL;
    192 #endif
    193 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
    194   return ticks / 1000LL;
    195 #else
    196   return ticks;
    197 #endif
    198 }
    199 
    200 inline int64_t TickTime::Ticks() const {
    201   return ticks_;
    202 }
    203 
    204 inline int64_t TickTime::MillisecondsToTicks(const int64_t ms) {
    205 #if _WIN32
    206 #ifdef USE_QUERY_PERFORMANCE_COUNTER
    207   LARGE_INTEGER qpfreq;
    208   QueryPerformanceFrequency(&qpfreq);
    209   return (qpfreq.QuadPart * ms) / 1000;
    210 #else
    211   return ms;
    212 #endif
    213 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
    214   return ms * 1000000LL;
    215 #else
    216   return ms * 1000LL;
    217 #endif
    218 }
    219 
    220 inline int64_t TickTime::TicksToMilliseconds(const int64_t ticks) {
    221 #if _WIN32
    222 #ifdef USE_QUERY_PERFORMANCE_COUNTER
    223   LARGE_INTEGER qpfreq;
    224   QueryPerformanceFrequency(&qpfreq);
    225   return (ticks * 1000) / qpfreq.QuadPart;
    226 #else
    227   return ticks;
    228 #endif
    229 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
    230   return ticks / 1000000LL;
    231 #else
    232   return ticks / 1000LL;
    233 #endif
    234 }
    235 
    236 inline TickTime& TickTime::operator+=(const int64_t& ticks) {
    237   ticks_ += ticks;
    238   return *this;
    239 }
    240 
    241 inline TickInterval::TickInterval() : interval_(0) {
    242 }
    243 
    244 inline TickInterval::TickInterval(const int64_t interval)
    245   : interval_(interval) {
    246 }
    247 
    248 inline int64_t TickInterval::Milliseconds() const {
    249 #if _WIN32
    250 #ifdef USE_QUERY_PERFORMANCE_COUNTER
    251   LARGE_INTEGER qpfreq;
    252   QueryPerformanceFrequency(&qpfreq);
    253   return (interval_ * 1000) / qpfreq.QuadPart;
    254 #else
    255   // 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;
    264 #endif
    265 }
    266 
    267 inline int64_t TickInterval::Microseconds() const {
    268 #if _WIN32
    269 #ifdef USE_QUERY_PERFORMANCE_COUNTER
    270   LARGE_INTEGER qpfreq;
    271   QueryPerformanceFrequency(&qpfreq);
    272   return (interval_ * 1000000) / qpfreq.QuadPart;
    273 #else
    274   // 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_;
    283 #endif
    284 }
    285 
    286 inline TickInterval& TickInterval::operator+=(const TickInterval& rhs) {
    287   interval_ += rhs.interval_;
    288   return *this;
    289 }
    290 
    291 inline TickInterval& TickInterval::operator-=(const TickInterval& rhs) {
    292   interval_ -= rhs.interval_;
    293   return *this;
    294 }
    295 
    296 }  // namespace webrtc
    297 
    298 #endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TICK_UTIL_H_
    299