blob: 7369a932f242a9fae5b3b00d09d389fe19afeda9 [file] [log] [blame]
#include "aos/util/phased_loop.h"
#include "glog/logging.h"
namespace aos {
namespace time {
PhasedLoop::PhasedLoop(const monotonic_clock::duration interval,
const monotonic_clock::time_point monotonic_now,
const monotonic_clock::duration offset)
: interval_(interval), offset_(offset), last_time_(offset) {
CHECK(offset >= monotonic_clock::duration(0));
CHECK(interval > monotonic_clock::duration(0));
CHECK(offset < interval);
Reset(monotonic_now);
}
void PhasedLoop::set_interval_and_offset(
const monotonic_clock::duration interval,
const monotonic_clock::duration offset) {
interval_ = interval;
offset_ = offset;
CHECK(offset_ >= monotonic_clock::duration(0));
CHECK(interval_ > monotonic_clock::duration(0));
CHECK(offset_ < interval_);
}
monotonic_clock::duration PhasedLoop::OffsetFromIntervalAndTime(
const monotonic_clock::duration interval,
const monotonic_clock::time_point monotonic_trigger) {
CHECK(interval > monotonic_clock::duration(0));
return monotonic_trigger.time_since_epoch() -
(monotonic_trigger.time_since_epoch() / interval) * interval +
((monotonic_trigger.time_since_epoch() >= monotonic_clock::zero())
? monotonic_clock::zero()
: interval);
}
int PhasedLoop::Iterate(const monotonic_clock::time_point now) {
const monotonic_clock::time_point next_time =
monotonic_clock::time_point(
(((now - offset_).time_since_epoch() + monotonic_clock::duration(1)) /
interval_) *
interval_) +
((now.time_since_epoch() < offset_) ? monotonic_clock::zero()
: interval_) +
offset_;
const monotonic_clock::duration difference = next_time - last_time_;
const int result = difference / interval_;
CHECK_EQ(
0, (next_time - offset_).time_since_epoch().count() % interval_.count());
CHECK(next_time >= now);
CHECK(next_time - now <= interval_);
last_time_ = next_time;
return result;
}
} // namespace timing
} // namespace aos