Add SetRuntimeRealtimePriority
This lets us move the concept of priority into the event loop rather
than trying to manage it elsewhere. Also add tests to confirm I got
them all.
Change-Id: Iba2651778e8d1eb88dedf71d0efdf05dfc999f2d
diff --git a/aos/events/shm-event-loop_test.cc b/aos/events/shm-event-loop_test.cc
index 0878e12..efa8545 100644
--- a/aos/events/shm-event-loop_test.cc
+++ b/aos/events/shm-event-loop_test.cc
@@ -7,6 +7,7 @@
namespace aos {
namespace testing {
namespace {
+namespace chrono = ::std::chrono;
class ShmEventLoopTestFactory : public EventLoopTestFactory {
public:
@@ -46,42 +47,55 @@
} // namespace
-// Tests that FetchNext behaves correctly when we get two messages in the queue
-// but don't consume the first until after the second has been sent.
-// This cannot be abstracted to AbstractEventLoopTest because not all
-// event loops currently support FetchNext().
-TEST(ShmEventLoopTest, FetchNextTest) {
- ::aos::testing::TestSharedMemory my_shm;
-
- ShmEventLoop send_loop;
- ShmEventLoop fetch_loop;
- auto sender = send_loop.MakeSender<TestMessage>("/test");
- Fetcher<TestMessage> fetcher = fetch_loop.MakeFetcher<TestMessage>("/test");
-
- {
- auto msg = sender.MakeMessage();
- msg->msg_value = 100;
- ASSERT_TRUE(msg.Send());
+bool IsRealtime() {
+ int scheduler;
+ if ((scheduler = sched_getscheduler(0)) == -1) {
+ PLOG(FATAL, "sched_getscheduler(0) failed\n");
}
+ LOG(INFO, "scheduler is %d\n", scheduler);
+ return scheduler == SCHED_FIFO || scheduler == SCHED_RR;
+}
- {
+// Tests that every handler type is realtime and runs. There are threads
+// involved and it's easy to miss one.
+TEST(ShmEventLoopTest, AllHandlersAreRealtime) {
+ ShmEventLoopTestFactory factory;
+ auto loop = factory.MakePrimary();
+ auto loop2 = factory.Make();
+
+ loop->SetRuntimeRealtimePriority(1);
+
+ auto sender = loop2->MakeSender<TestMessage>("/test");
+
+ bool did_onrun = false;
+ bool did_timer = false;
+ bool did_watcher = false;
+
+ auto timer = loop->AddTimer([&did_timer, &loop]() {
+ EXPECT_TRUE(IsRealtime());
+ did_timer = true;
+ loop->Exit();
+ });
+
+ loop->MakeWatcher("/test", [&did_watcher](const TestMessage &) {
+ EXPECT_TRUE(IsRealtime());
+ did_watcher = true;
+ });
+
+ loop->OnRun([&loop, &did_onrun, &sender, timer]() {
+ EXPECT_TRUE(IsRealtime());
+ did_onrun = true;
+ timer->Setup(loop->monotonic_now() + chrono::milliseconds(100));
auto msg = sender.MakeMessage();
msg->msg_value = 200;
- ASSERT_TRUE(msg.Send());
- }
+ msg.Send();
+ });
- ASSERT_TRUE(fetcher.FetchNext());
- ASSERT_NE(nullptr, fetcher.get());
- EXPECT_EQ(100, fetcher->msg_value);
+ factory.Run();
- ASSERT_TRUE(fetcher.FetchNext());
- ASSERT_NE(nullptr, fetcher.get());
- EXPECT_EQ(200, fetcher->msg_value);
-
- // When we run off the end of the queue, expect to still have the old message:
- ASSERT_FALSE(fetcher.FetchNext());
- ASSERT_NE(nullptr, fetcher.get());
- EXPECT_EQ(200, fetcher->msg_value);
+ EXPECT_TRUE(did_onrun);
+ EXPECT_TRUE(did_timer);
+ EXPECT_TRUE(did_watcher);
}
} // namespace testing
} // namespace aos