John Park | 33858a3 | 2018-09-28 23:05:48 -0700 | [diff] [blame] | 1 | #include "aos/util/phased_loop.h" |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 2 | |
Austin Schuh | f257f3c | 2019-10-27 21:00:43 -0700 | [diff] [blame^] | 3 | #include "glog/logging.h" |
| 4 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 5 | namespace aos { |
| 6 | namespace time { |
| 7 | |
Austin Schuh | f257f3c | 2019-10-27 21:00:43 -0700 | [diff] [blame^] | 8 | PhasedLoop::PhasedLoop(const monotonic_clock::duration interval, |
| 9 | const monotonic_clock::time_point monotonic_now, |
| 10 | const monotonic_clock::duration offset) |
| 11 | : interval_(interval), offset_(offset), last_time_(offset) { |
| 12 | CHECK(offset >= monotonic_clock::duration(0)); |
| 13 | CHECK(interval > monotonic_clock::duration(0)); |
| 14 | CHECK(offset < interval); |
| 15 | Reset(monotonic_now); |
| 16 | } |
| 17 | |
| 18 | void PhasedLoop::set_interval_and_offset( |
| 19 | const monotonic_clock::duration interval, |
| 20 | const monotonic_clock::duration offset) { |
| 21 | interval_ = interval; |
| 22 | offset_ = offset; |
| 23 | CHECK(offset_ >= monotonic_clock::duration(0)); |
| 24 | CHECK(interval_ > monotonic_clock::duration(0)); |
| 25 | CHECK(offset_ < interval_); |
| 26 | } |
| 27 | |
| 28 | monotonic_clock::duration PhasedLoop::OffsetFromIntervalAndTime( |
| 29 | const monotonic_clock::duration interval, |
| 30 | const monotonic_clock::time_point monotonic_trigger) { |
| 31 | CHECK(interval > monotonic_clock::duration(0)); |
| 32 | return monotonic_trigger.time_since_epoch() - |
| 33 | (monotonic_trigger.time_since_epoch() / interval) * interval + |
| 34 | ((monotonic_trigger.time_since_epoch() >= monotonic_clock::zero()) |
| 35 | ? monotonic_clock::zero() |
| 36 | : interval); |
| 37 | } |
| 38 | |
Austin Schuh | 8aec1ed | 2016-05-01 13:29:20 -0700 | [diff] [blame] | 39 | int PhasedLoop::Iterate(const monotonic_clock::time_point now) { |
| 40 | const monotonic_clock::time_point next_time = |
| 41 | monotonic_clock::time_point( |
| 42 | (((now - offset_).time_since_epoch() + monotonic_clock::duration(1)) / |
| 43 | interval_) * |
| 44 | interval_) + |
| 45 | ((now.time_since_epoch() < offset_) ? monotonic_clock::zero() |
| 46 | : interval_) + |
| 47 | offset_; |
Brian Silverman | dcaa3f7 | 2015-11-29 05:32:08 +0000 | [diff] [blame] | 48 | |
Austin Schuh | 8aec1ed | 2016-05-01 13:29:20 -0700 | [diff] [blame] | 49 | const monotonic_clock::duration difference = next_time - last_time_; |
| 50 | const int result = difference / interval_; |
Austin Schuh | 8aec1ed | 2016-05-01 13:29:20 -0700 | [diff] [blame] | 51 | CHECK_EQ( |
| 52 | 0, (next_time - offset_).time_since_epoch().count() % interval_.count()); |
Austin Schuh | f257f3c | 2019-10-27 21:00:43 -0700 | [diff] [blame^] | 53 | CHECK(next_time >= now); |
| 54 | CHECK(next_time - now <= interval_); |
Brian Silverman | dcaa3f7 | 2015-11-29 05:32:08 +0000 | [diff] [blame] | 55 | last_time_ = next_time; |
| 56 | return result; |
| 57 | } |
| 58 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 59 | } // namespace timing |
| 60 | } // namespace aos |