blob: 7369a932f242a9fae5b3b00d09d389fe19afeda9 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/util/phased_loop.h"
brians343bc112013-02-10 01:53:46 +00002
Austin Schuhf257f3c2019-10-27 21:00:43 -07003#include "glog/logging.h"
4
brians343bc112013-02-10 01:53:46 +00005namespace aos {
6namespace time {
7
Austin Schuhf257f3c2019-10-27 21:00:43 -07008PhasedLoop::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
18void 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
28monotonic_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 Schuh8aec1ed2016-05-01 13:29:20 -070039int 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 Silvermandcaa3f72015-11-29 05:32:08 +000048
Austin Schuh8aec1ed2016-05-01 13:29:20 -070049 const monotonic_clock::duration difference = next_time - last_time_;
50 const int result = difference / interval_;
Austin Schuh8aec1ed2016-05-01 13:29:20 -070051 CHECK_EQ(
52 0, (next_time - offset_).time_since_epoch().count() % interval_.count());
Austin Schuhf257f3c2019-10-27 21:00:43 -070053 CHECK(next_time >= now);
54 CHECK(next_time - now <= interval_);
Brian Silvermandcaa3f72015-11-29 05:32:08 +000055 last_time_ = next_time;
56 return result;
57}
58
brians343bc112013-02-10 01:53:46 +000059} // namespace timing
60} // namespace aos