1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef API_NETEQ_TICK_TIMER_H_ 12*d9f75844SAndroid Build Coastguard Worker #define API_NETEQ_TICK_TIMER_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <memory> 17*d9f75844SAndroid Build Coastguard Worker 18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h" 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Worker // Implements a time counter. The counter is advanced with the Increment() 23*d9f75844SAndroid Build Coastguard Worker // methods, and is queried with the ticks() accessor. It is assumed that one 24*d9f75844SAndroid Build Coastguard Worker // "tick" of the counter corresponds to 10 ms. 25*d9f75844SAndroid Build Coastguard Worker // A TickTimer object can provide two types of associated time-measuring 26*d9f75844SAndroid Build Coastguard Worker // objects: Stopwatch and Countdown. 27*d9f75844SAndroid Build Coastguard Worker class TickTimer { 28*d9f75844SAndroid Build Coastguard Worker public: 29*d9f75844SAndroid Build Coastguard Worker // Stopwatch measures time elapsed since it was started, by querying the 30*d9f75844SAndroid Build Coastguard Worker // associated TickTimer for the current time. The intended use is to request a 31*d9f75844SAndroid Build Coastguard Worker // new Stopwatch object from a TickTimer object with the GetNewStopwatch() 32*d9f75844SAndroid Build Coastguard Worker // method. Note: since the Stopwatch object contains a reference to the 33*d9f75844SAndroid Build Coastguard Worker // TickTimer it is associated with, it cannot outlive the TickTimer. 34*d9f75844SAndroid Build Coastguard Worker class Stopwatch { 35*d9f75844SAndroid Build Coastguard Worker public: 36*d9f75844SAndroid Build Coastguard Worker explicit Stopwatch(const TickTimer& ticktimer); 37*d9f75844SAndroid Build Coastguard Worker ElapsedTicks()38*d9f75844SAndroid Build Coastguard Worker uint64_t ElapsedTicks() const { return ticktimer_.ticks() - starttick_; } 39*d9f75844SAndroid Build Coastguard Worker ElapsedMs()40*d9f75844SAndroid Build Coastguard Worker uint64_t ElapsedMs() const { 41*d9f75844SAndroid Build Coastguard Worker const uint64_t elapsed_ticks = ticktimer_.ticks() - starttick_; 42*d9f75844SAndroid Build Coastguard Worker const int ms_per_tick = ticktimer_.ms_per_tick(); 43*d9f75844SAndroid Build Coastguard Worker return elapsed_ticks < UINT64_MAX / ms_per_tick 44*d9f75844SAndroid Build Coastguard Worker ? elapsed_ticks * ms_per_tick 45*d9f75844SAndroid Build Coastguard Worker : UINT64_MAX; 46*d9f75844SAndroid Build Coastguard Worker } 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker private: 49*d9f75844SAndroid Build Coastguard Worker const TickTimer& ticktimer_; 50*d9f75844SAndroid Build Coastguard Worker const uint64_t starttick_; 51*d9f75844SAndroid Build Coastguard Worker }; 52*d9f75844SAndroid Build Coastguard Worker 53*d9f75844SAndroid Build Coastguard Worker // Countdown counts down from a given start value with each tick of the 54*d9f75844SAndroid Build Coastguard Worker // associated TickTimer, until zero is reached. The Finished() method will 55*d9f75844SAndroid Build Coastguard Worker // return true if zero has been reached, false otherwise. The intended use is 56*d9f75844SAndroid Build Coastguard Worker // to request a new Countdown object from a TickTimer object with the 57*d9f75844SAndroid Build Coastguard Worker // GetNewCountdown() method. Note: since the Countdown object contains a 58*d9f75844SAndroid Build Coastguard Worker // reference to the TickTimer it is associated with, it cannot outlive the 59*d9f75844SAndroid Build Coastguard Worker // TickTimer. 60*d9f75844SAndroid Build Coastguard Worker class Countdown { 61*d9f75844SAndroid Build Coastguard Worker public: 62*d9f75844SAndroid Build Coastguard Worker Countdown(const TickTimer& ticktimer, uint64_t ticks_to_count); 63*d9f75844SAndroid Build Coastguard Worker 64*d9f75844SAndroid Build Coastguard Worker ~Countdown(); 65*d9f75844SAndroid Build Coastguard Worker Finished()66*d9f75844SAndroid Build Coastguard Worker bool Finished() const { 67*d9f75844SAndroid Build Coastguard Worker return stopwatch_->ElapsedTicks() >= ticks_to_count_; 68*d9f75844SAndroid Build Coastguard Worker } 69*d9f75844SAndroid Build Coastguard Worker 70*d9f75844SAndroid Build Coastguard Worker private: 71*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<Stopwatch> stopwatch_; 72*d9f75844SAndroid Build Coastguard Worker const uint64_t ticks_to_count_; 73*d9f75844SAndroid Build Coastguard Worker }; 74*d9f75844SAndroid Build Coastguard Worker TickTimer()75*d9f75844SAndroid Build Coastguard Worker TickTimer() : TickTimer(10) {} TickTimer(int ms_per_tick)76*d9f75844SAndroid Build Coastguard Worker explicit TickTimer(int ms_per_tick) : ms_per_tick_(ms_per_tick) { 77*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_GT(ms_per_tick_, 0); 78*d9f75844SAndroid Build Coastguard Worker } 79*d9f75844SAndroid Build Coastguard Worker 80*d9f75844SAndroid Build Coastguard Worker TickTimer(const TickTimer&) = delete; 81*d9f75844SAndroid Build Coastguard Worker TickTimer& operator=(const TickTimer&) = delete; 82*d9f75844SAndroid Build Coastguard Worker Increment()83*d9f75844SAndroid Build Coastguard Worker void Increment() { ++ticks_; } 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker // Mainly intended for testing. Increment(uint64_t x)86*d9f75844SAndroid Build Coastguard Worker void Increment(uint64_t x) { ticks_ += x; } 87*d9f75844SAndroid Build Coastguard Worker ticks()88*d9f75844SAndroid Build Coastguard Worker uint64_t ticks() const { return ticks_; } 89*d9f75844SAndroid Build Coastguard Worker ms_per_tick()90*d9f75844SAndroid Build Coastguard Worker int ms_per_tick() const { return ms_per_tick_; } 91*d9f75844SAndroid Build Coastguard Worker 92*d9f75844SAndroid Build Coastguard Worker // Returns a new Stopwatch object, based on the current TickTimer. Note that 93*d9f75844SAndroid Build Coastguard Worker // the new Stopwatch object contains a reference to the current TickTimer, 94*d9f75844SAndroid Build Coastguard Worker // and must therefore not outlive the TickTimer. GetNewStopwatch()95*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Stopwatch> GetNewStopwatch() const { 96*d9f75844SAndroid Build Coastguard Worker return std::unique_ptr<Stopwatch>(new Stopwatch(*this)); 97*d9f75844SAndroid Build Coastguard Worker } 98*d9f75844SAndroid Build Coastguard Worker 99*d9f75844SAndroid Build Coastguard Worker // Returns a new Countdown object, based on the current TickTimer. Note that 100*d9f75844SAndroid Build Coastguard Worker // the new Countdown object contains a reference to the current TickTimer, 101*d9f75844SAndroid Build Coastguard Worker // and must therefore not outlive the TickTimer. GetNewCountdown(uint64_t ticks_to_count)102*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<Countdown> GetNewCountdown(uint64_t ticks_to_count) const { 103*d9f75844SAndroid Build Coastguard Worker return std::unique_ptr<Countdown>(new Countdown(*this, ticks_to_count)); 104*d9f75844SAndroid Build Coastguard Worker } 105*d9f75844SAndroid Build Coastguard Worker 106*d9f75844SAndroid Build Coastguard Worker private: 107*d9f75844SAndroid Build Coastguard Worker uint64_t ticks_ = 0; 108*d9f75844SAndroid Build Coastguard Worker const int ms_per_tick_; 109*d9f75844SAndroid Build Coastguard Worker }; 110*d9f75844SAndroid Build Coastguard Worker 111*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 112*d9f75844SAndroid Build Coastguard Worker #endif // API_NETEQ_TICK_TIMER_H_ 113