Converted PhasedLoop over to monotonic_clock.
Change-Id: Ic8857c4412abb7c19dd3df4aaa5f6c8aa74e9dc6
diff --git a/aos/common/util/phased_loop.cc b/aos/common/util/phased_loop.cc
index b5804c8..9c81ffb 100644
--- a/aos/common/util/phased_loop.cc
+++ b/aos/common/util/phased_loop.cc
@@ -10,15 +10,21 @@
frequency + Time::InUS(offset));
}
-int PhasedLoop::Iterate(const Time &now) {
- const Time next_time = Time::InNS(((now - offset_).ToNSec() + 1) /
- interval_.ToNSec() * interval_.ToNSec()) +
- ((now < offset_) ? Time::kZero : interval_) + offset_;
+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 Time difference = next_time - last_time_;
- const int result = difference.ToNSec() / interval_.ToNSec();
+ const monotonic_clock::duration difference = next_time - last_time_;
+ const int result = difference / interval_;
CHECK_EQ(difference, interval_ * result);
- CHECK_EQ(0, (next_time - offset_).ToNSec() % interval_.ToNSec());
+ CHECK_EQ(
+ 0, (next_time - offset_).time_since_epoch().count() % interval_.count());
CHECK_GE(next_time, now);
CHECK_LE(next_time - now, interval_);
last_time_ = next_time;
diff --git a/aos/common/util/phased_loop.h b/aos/common/util/phased_loop.h
index fc0f247..7614ed2 100644
--- a/aos/common/util/phased_loop.h
+++ b/aos/common/util/phased_loop.h
@@ -22,40 +22,47 @@
// ...
// 10000.1s
// offset must be >= Time::kZero and < interval.
- PhasedLoop(const Time &interval, const Time &offset = Time::kZero)
+ PhasedLoop(
+ const monotonic_clock::duration interval,
+ const monotonic_clock::duration offset = monotonic_clock::duration(0))
: interval_(interval), offset_(offset), last_time_(offset) {
- CHECK_GE(offset, Time::kZero);
- CHECK_GT(interval, Time::kZero);
+ CHECK_GE(offset, monotonic_clock::duration(0));
+ CHECK_GT(interval, monotonic_clock::duration(0));
CHECK_LT(offset, interval);
Reset();
}
// Resets the count of skipped iterations.
- // Iterate(now) will return 1 and set sleep_time() to something within
- // interval of now.
- void Reset(const Time &now = Time::Now()) { Iterate(now - interval_); }
+ // Iterate(monotonic_now) will return 1 and set sleep_time() to something
+ // within interval of monotonic_now.
+ void Reset(const monotonic_clock::time_point monotonic_now =
+ monotonic_clock::now()) {
+ Iterate(monotonic_now - interval_);
+ }
- // Calculates the next time to run after now.
+ // Calculates the next time to run after monotonic_now.
// The result can be retrieved with sleep_time().
// Returns the number of iterations which have passed (1 if this is called
- // often enough). This can be < 1 iff now goes backwards between calls.
- int Iterate(const Time &now = Time::Now());
+ // often enough). This can be < 1 iff monotonic_now goes backwards between
+ // calls.
+ int Iterate(const monotonic_clock::time_point monotonic_now =
+ monotonic_clock::now());
// Sleeps until the next time and returns the number of iterations which have
// passed.
int SleepUntilNext() {
- const int r = Iterate(Time::Now());
- SleepUntil(sleep_time());
+ const int r = Iterate(monotonic_clock::now());
+ ::std::this_thread::sleep_until(sleep_time());
return r;
}
- const Time &sleep_time() const { return last_time_; }
+ monotonic_clock::time_point sleep_time() const { return last_time_; }
private:
- const Time interval_, offset_;
+ const monotonic_clock::duration interval_, offset_;
// The time we most recently slept until.
- Time last_time_ = Time::kZero;
+ monotonic_clock::time_point last_time_ = monotonic_clock::epoch();
};
} // namespace time
diff --git a/aos/common/util/phased_loop_test.cc b/aos/common/util/phased_loop_test.cc
index 1641a92..b013c2e 100644
--- a/aos/common/util/phased_loop_test.cc
+++ b/aos/common/util/phased_loop_test.cc
@@ -8,111 +8,115 @@
namespace time {
namespace testing {
+using ::std::chrono::milliseconds;
+
class PhasedLoopTest : public ::testing::Test {
protected:
- PhasedLoopTest() {
- ::aos::testing::EnableTestLogging();
- }
+ PhasedLoopTest() { ::aos::testing::EnableTestLogging(); }
};
typedef PhasedLoopTest PhasedLoopDeathTest;
+monotonic_clock::time_point InMs(int ms) {
+ return monotonic_clock::time_point(::std::chrono::milliseconds(ms));
+}
+
TEST_F(PhasedLoopTest, Reset) {
{
- PhasedLoop loop(Time::InMS(100), Time::kZero);
+ PhasedLoop loop(milliseconds(100), milliseconds(0));
- loop.Reset(Time::kZero);
- EXPECT_EQ(Time::InMS(0), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::kZero));
- EXPECT_EQ(Time::InMS(100), loop.sleep_time());
+ loop.Reset(monotonic_clock::epoch());
+ EXPECT_EQ(InMs(0), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(monotonic_clock::epoch()));
+ EXPECT_EQ(InMs(100), loop.sleep_time());
- loop.Reset(Time::InMS(99));
- EXPECT_EQ(Time::InMS(0), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(99)));
- EXPECT_EQ(Time::InMS(100), loop.sleep_time());
+ loop.Reset(InMs(99));
+ EXPECT_EQ(InMs(0), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(99)));
+ EXPECT_EQ(InMs(100), loop.sleep_time());
- loop.Reset(Time::InMS(100));
- EXPECT_EQ(Time::InMS(100), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(199)));
- EXPECT_EQ(Time::InMS(200), loop.sleep_time());
+ loop.Reset(InMs(100));
+ EXPECT_EQ(InMs(100), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(199)));
+ EXPECT_EQ(InMs(200), loop.sleep_time());
- loop.Reset(Time::InMS(101));
- EXPECT_EQ(Time::InMS(100), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(101)));
- EXPECT_EQ(Time::InMS(200), loop.sleep_time());
+ loop.Reset(InMs(101));
+ EXPECT_EQ(InMs(100), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(101)));
+ EXPECT_EQ(InMs(200), loop.sleep_time());
}
{
- PhasedLoop loop(Time::InMS(100), Time::InMS(1));
- loop.Reset(Time::kZero);
- EXPECT_EQ(Time::InMS(-99), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::kZero));
- EXPECT_EQ(Time::InMS(1), loop.sleep_time());
+ PhasedLoop loop(milliseconds(100), milliseconds(1));
+ loop.Reset(monotonic_clock::epoch());
+ EXPECT_EQ(InMs(-99), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(monotonic_clock::epoch()));
+ EXPECT_EQ(InMs(1), loop.sleep_time());
}
{
- PhasedLoop loop(Time::InMS(100), Time::InMS(99));
+ PhasedLoop loop(milliseconds(100), milliseconds(99));
- loop.Reset(Time::kZero);
- EXPECT_EQ(Time::InMS(-1), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::kZero));
- EXPECT_EQ(Time::InMS(99), loop.sleep_time());
+ loop.Reset(monotonic_clock::epoch());
+ EXPECT_EQ(InMs(-1), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(monotonic_clock::epoch()));
+ EXPECT_EQ(InMs(99), loop.sleep_time());
- loop.Reset(Time::InMS(98));
- EXPECT_EQ(Time::InMS(-1), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(98)));
- EXPECT_EQ(Time::InMS(99), loop.sleep_time());
+ loop.Reset(InMs(98));
+ EXPECT_EQ(InMs(-1), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(98)));
+ EXPECT_EQ(InMs(99), loop.sleep_time());
- loop.Reset(Time::InMS(99));
- EXPECT_EQ(Time::InMS(99), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(99)));
- EXPECT_EQ(Time::InMS(199), loop.sleep_time());
+ loop.Reset(InMs(99));
+ EXPECT_EQ(InMs(99), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(99)));
+ EXPECT_EQ(InMs(199), loop.sleep_time());
- loop.Reset(Time::InMS(100));
- EXPECT_EQ(Time::InMS(99), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(100)));
- EXPECT_EQ(Time::InMS(199), loop.sleep_time());
+ loop.Reset(InMs(100));
+ EXPECT_EQ(InMs(99), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(100)));
+ EXPECT_EQ(InMs(199), loop.sleep_time());
}
}
TEST_F(PhasedLoopTest, Iterate) {
{
- PhasedLoop loop(Time::InMS(100), Time::InMS(99));
- loop.Reset(Time::kZero);
- EXPECT_EQ(1, loop.Iterate(Time::kZero));
- EXPECT_EQ(Time::InMS(99), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(100)));
- EXPECT_EQ(Time::InMS(199), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(100)));
- EXPECT_EQ(Time::InMS(199), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(101)));
- EXPECT_EQ(Time::InMS(199), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(198)));
- EXPECT_EQ(Time::InMS(199), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(199)));
- EXPECT_EQ(Time::InMS(299), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(300)));
- EXPECT_EQ(Time::InMS(399), loop.sleep_time());
- EXPECT_EQ(3, loop.Iterate(Time::InMS(600)));
- EXPECT_EQ(Time::InMS(699), loop.sleep_time());
+ PhasedLoop loop(milliseconds(100), milliseconds(99));
+ loop.Reset(monotonic_clock::epoch());
+ EXPECT_EQ(1, loop.Iterate(monotonic_clock::epoch()));
+ EXPECT_EQ(InMs(99), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(100)));
+ EXPECT_EQ(InMs(199), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(100)));
+ EXPECT_EQ(InMs(199), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(101)));
+ EXPECT_EQ(InMs(199), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(198)));
+ EXPECT_EQ(InMs(199), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(199)));
+ EXPECT_EQ(InMs(299), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(300)));
+ EXPECT_EQ(InMs(399), loop.sleep_time());
+ EXPECT_EQ(3, loop.Iterate(InMs(600)));
+ EXPECT_EQ(InMs(699), loop.sleep_time());
}
{
- PhasedLoop loop(Time::InMS(100), Time::InMS(1));
- loop.Reset(Time::kZero);
- EXPECT_EQ(1, loop.Iterate(Time::kZero));
- EXPECT_EQ(Time::InMS(1), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(100)));
- EXPECT_EQ(Time::InMS(101), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(100)));
- EXPECT_EQ(Time::InMS(101), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(103)));
- EXPECT_EQ(Time::InMS(201), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(198)));
- EXPECT_EQ(Time::InMS(201), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(200)));
- EXPECT_EQ(Time::InMS(201), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(201)));
- EXPECT_EQ(Time::InMS(301), loop.sleep_time());
- EXPECT_EQ(3, loop.Iterate(Time::InMS(600)));
- EXPECT_EQ(Time::InMS(601), loop.sleep_time());
+ PhasedLoop loop(milliseconds(100), milliseconds(1));
+ loop.Reset(monotonic_clock::epoch());
+ EXPECT_EQ(1, loop.Iterate(monotonic_clock::epoch()));
+ EXPECT_EQ(InMs(1), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(100)));
+ EXPECT_EQ(InMs(101), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(100)));
+ EXPECT_EQ(InMs(101), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(103)));
+ EXPECT_EQ(InMs(201), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(198)));
+ EXPECT_EQ(InMs(201), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(200)));
+ EXPECT_EQ(InMs(201), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(201)));
+ EXPECT_EQ(InMs(301), loop.sleep_time());
+ EXPECT_EQ(3, loop.Iterate(InMs(600)));
+ EXPECT_EQ(InMs(601), loop.sleep_time());
}
}
@@ -120,40 +124,42 @@
// This seems like a rare case at first, but starting from zero needs to
// work, which means negatives should too.
TEST_F(PhasedLoopTest, CrossingZero) {
- PhasedLoop loop(Time::InMS(100), Time::InMS(1));
- loop.Reset(Time::InMS(-1000));
- EXPECT_EQ(Time::InMS(-1099), loop.sleep_time());
- EXPECT_EQ(9, loop.Iterate(Time::InMS(-250)));
- EXPECT_EQ(Time::InMS(-199), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(-199)));
- EXPECT_EQ(Time::InMS(-99), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(-90)));
- EXPECT_EQ(Time::InMS(1), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(0)));
- EXPECT_EQ(Time::InMS(1), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(1)));
- EXPECT_EQ(Time::InMS(101), loop.sleep_time());
+ PhasedLoop loop(milliseconds(100), milliseconds(1));
+ loop.Reset(InMs(-1000));
+ EXPECT_EQ(InMs(-1099), loop.sleep_time());
+ EXPECT_EQ(9, loop.Iterate(InMs(-250)));
+ EXPECT_EQ(InMs(-199), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(-199)));
+ EXPECT_EQ(InMs(-99), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(-90)));
+ EXPECT_EQ(InMs(1), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(0)));
+ EXPECT_EQ(InMs(1), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(1)));
+ EXPECT_EQ(InMs(101), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(2)));
- EXPECT_EQ(Time::InMS(101), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(2)));
+ EXPECT_EQ(InMs(101), loop.sleep_time());
- EXPECT_EQ(-2, loop.Iterate(Time::InMS(-101)));
- EXPECT_EQ(Time::InMS(-99), loop.sleep_time());
- EXPECT_EQ(1, loop.Iterate(Time::InMS(-99)));
- EXPECT_EQ(Time::InMS(1), loop.sleep_time());
+ EXPECT_EQ(-2, loop.Iterate(InMs(-101)));
+ EXPECT_EQ(InMs(-99), loop.sleep_time());
+ EXPECT_EQ(1, loop.Iterate(InMs(-99)));
+ EXPECT_EQ(InMs(1), loop.sleep_time());
- EXPECT_EQ(0, loop.Iterate(Time::InMS(-99)));
- EXPECT_EQ(Time::InMS(1), loop.sleep_time());
+ EXPECT_EQ(0, loop.Iterate(InMs(-99)));
+ EXPECT_EQ(InMs(1), loop.sleep_time());
}
// Tests that passing invalid values to the constructor dies correctly.
TEST_F(PhasedLoopDeathTest, InvalidValues) {
- EXPECT_DEATH(PhasedLoop(Time::InMS(1), Time::InMS(2)), ".*offset<interval.*");
- EXPECT_DEATH(PhasedLoop(Time::InMS(1), Time::InMS(1)), ".*offset<interval.*");
- EXPECT_DEATH(PhasedLoop(Time::InMS(1), Time::InMS(-1)),
- ".*offset>=Time::kZero.*");
- EXPECT_DEATH(PhasedLoop(Time::InMS(0), Time::InMS(0)),
- ".*interval>Time::kZero.*");
+ EXPECT_DEATH(PhasedLoop(milliseconds(1), milliseconds(2)),
+ ".*offset<interval.*");
+ EXPECT_DEATH(PhasedLoop(milliseconds(1), milliseconds(1)),
+ ".*offset<interval.*");
+ EXPECT_DEATH(PhasedLoop(milliseconds(1), milliseconds(-1)),
+ ".*offset>=monotonic_clock::duration\\(0\\).*");
+ EXPECT_DEATH(PhasedLoop(milliseconds(0), milliseconds(0)),
+ ".*interval>monotonic_clock::duration\\(0\\).*");
}
} // namespace testing