Add support for retrieving the affinity of an EventLoop

Also rename priority to emphasize that it's a realtime priority which
only applies at runtime

Change-Id: I06f24e04d4079248c0e313299103d120842a7537
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index 316ac29..0967bb0 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -705,11 +705,22 @@
   // Sets the scheduler priority to run the event loop at.  This may not be
   // called after we go into "real-time-mode".
   virtual void SetRuntimeRealtimePriority(int priority) = 0;
-  virtual int priority() const = 0;
+  // Defaults to 0 if this loop will not run realtime.
+  virtual int runtime_realtime_priority() const = 0;
+
+  static cpu_set_t DefaultAffinity() {
+    cpu_set_t result;
+    for (int i = 0; i < CPU_SETSIZE; ++i) {
+      CPU_SET(i, &result);
+    }
+    return result;
+  }
 
   // Sets the scheduler affinity to run the event loop with. This may only be
   // called before Run().
   virtual void SetRuntimeAffinity(const cpu_set_t &cpuset) = 0;
+  // Defaults to DefaultAffinity() if this loop will not run pinned.
+  virtual const cpu_set_t &runtime_affinity() const = 0;
 
   // Fetches new messages from the provided channel (path, type).
   //
diff --git a/aos/events/event_loop_param_test.cc b/aos/events/event_loop_param_test.cc
index 0eeecf8..118b9ae 100644
--- a/aos/events/event_loop_param_test.cc
+++ b/aos/events/event_loop_param_test.cc
@@ -781,14 +781,24 @@
 // Verify that SetRuntimeRealtimePriority fails while running.
 TEST_P(AbstractEventLoopDeathTest, SetRuntimeRealtimePriority) {
   auto loop = MakePrimary();
+  EXPECT_EQ(0, loop->runtime_realtime_priority());
   // Confirm that runtime priority calls work when not realtime.
   loop->SetRuntimeRealtimePriority(5);
+  EXPECT_EQ(5, loop->runtime_realtime_priority());
 
   loop->OnRun([&]() { loop->SetRuntimeRealtimePriority(5); });
 
   EXPECT_DEATH(Run(), "realtime");
 }
 
+namespace {
+
+bool CpuSetEqual(const cpu_set_t &a, const cpu_set_t &b) {
+  return CPU_EQUAL(&a, &b);
+}
+
+}  // namespace
+
 // Verify that SetRuntimeAffinity fails while running.
 TEST_P(AbstractEventLoopDeathTest, SetRuntimeAffinity) {
   const cpu_set_t available = GetCurrentThreadAffinity();
@@ -803,8 +813,12 @@
   CHECK_NE(first_cpu, -1) << ": Default affinity has no CPUs?";
 
   auto loop = MakePrimary();
+  EXPECT_TRUE(
+      CpuSetEqual(EventLoop::DefaultAffinity(), loop->runtime_affinity()));
+  const cpu_set_t new_affinity = MakeCpusetFromCpus({first_cpu});
   // Confirm that runtime priority calls work when not running.
-  loop->SetRuntimeAffinity(MakeCpusetFromCpus({first_cpu}));
+  loop->SetRuntimeAffinity(new_affinity);
+  EXPECT_TRUE(CpuSetEqual(new_affinity, loop->runtime_affinity()));
 
   loop->OnRun(
       [&]() { loop->SetRuntimeAffinity(MakeCpusetFromCpus({first_cpu})); });
diff --git a/aos/events/shm_event_loop.cc b/aos/events/shm_event_loop.cc
index a43de78..e2a86ff 100644
--- a/aos/events/shm_event_loop.cc
+++ b/aos/events/shm_event_loop.cc
@@ -562,8 +562,9 @@
         << ": Somebody wrote outside the buffer of their message on channel "
         << configuration::CleanedChannelToString(channel());
 
-    wake_upper_.Wakeup(event_loop()->is_running() ? event_loop()->priority()
-                                                  : 0);
+    wake_upper_.Wakeup(event_loop()->is_running()
+                           ? event_loop()->runtime_realtime_priority()
+                           : 0);
     return CheckLocklessQueueResult(result);
   }
 
@@ -585,8 +586,9 @@
         << ": Somebody wrote outside the buffer of their message on "
            "channel "
         << configuration::CleanedChannelToString(channel());
-    wake_upper_.Wakeup(event_loop()->is_running() ? event_loop()->priority()
-                                                  : 0);
+    wake_upper_.Wakeup(event_loop()->is_running()
+                           ? event_loop()->runtime_realtime_priority()
+                           : 0);
 
     return CheckLocklessQueueResult(result);
   }
@@ -649,7 +651,7 @@
   void Startup(EventLoop *event_loop) override {
     event_loop_->CheckCurrentThread();
     simple_shm_fetcher_.PointAtNextQueueIndex();
-    CHECK(RegisterWakeup(event_loop->priority()));
+    CHECK(RegisterWakeup(event_loop->runtime_realtime_priority()));
   }
 
   // Returns true if there is new data available.
diff --git a/aos/events/shm_event_loop.h b/aos/events/shm_event_loop.h
index e51f21b..c182698 100644
--- a/aos/events/shm_event_loop.h
+++ b/aos/events/shm_event_loop.h
@@ -81,7 +81,8 @@
   const std::string_view name() const override { return name_; }
   const Node *node() const override { return node_; }
 
-  int priority() const override { return priority_; }
+  int runtime_realtime_priority() const override { return priority_; }
+  const cpu_set_t &runtime_affinity() const override { return affinity_; }
   const UUID &boot_uuid() const override { return boot_uuid_; }
 
   // Returns the epoll loop used to run the event loop.
@@ -141,14 +142,6 @@
 
   using EventLoop::SendTimingReport;
 
-  static cpu_set_t DefaultAffinity() {
-    cpu_set_t result;
-    for (int i = 0; i < CPU_SETSIZE; ++i) {
-      CPU_SET(i, &result);
-    }
-    return result;
-  }
-
   void CheckCurrentThread() const;
 
   void HandleEvent();
diff --git a/aos/events/simulated_event_loop.cc b/aos/events/simulated_event_loop.cc
index 0bdd711..1515e40 100644
--- a/aos/events/simulated_event_loop.cc
+++ b/aos/events/simulated_event_loop.cc
@@ -649,7 +649,7 @@
       if (log_impl_) {
         prev_logger.Swap(log_impl_);
       }
-      ScopedMarkRealtimeRestorer rt(priority() > 0);
+      ScopedMarkRealtimeRestorer rt(runtime_realtime_priority() > 0);
       SetTimerContext(monotonic_now());
       on_run();
     });
@@ -669,10 +669,12 @@
     priority_ = priority;
   }
 
-  int priority() const override { return priority_; }
+  int runtime_realtime_priority() const override { return priority_; }
+  const cpu_set_t &runtime_affinity() const override { return affinity_; }
 
-  void SetRuntimeAffinity(const cpu_set_t & /*cpuset*/) override {
+  void SetRuntimeAffinity(const cpu_set_t &affinity) override {
     CHECK(!is_running()) << ": Cannot set affinity while running.";
+    affinity_ = affinity;
   }
 
   void Setup() {
@@ -728,6 +730,7 @@
   ::std::string name_;
 
   int priority_ = 0;
+  cpu_set_t affinity_ = DefaultAffinity();
 
   std::chrono::nanoseconds send_delay_;
 
@@ -908,7 +911,8 @@
   }
 
   {
-    ScopedMarkRealtimeRestorer rt(simulated_event_loop_->priority() > 0);
+    ScopedMarkRealtimeRestorer rt(
+        simulated_event_loop_->runtime_realtime_priority() > 0);
     DoCallCallback([monotonic_now]() { return monotonic_now; }, context);
   }
 
@@ -1210,7 +1214,8 @@
   }
 
   {
-    ScopedMarkRealtimeRestorer rt(simulated_event_loop_->priority() > 0);
+    ScopedMarkRealtimeRestorer rt(
+        simulated_event_loop_->runtime_realtime_priority() > 0);
     Call([monotonic_now]() { return monotonic_now; }, monotonic_now);
   }
 }
@@ -1255,7 +1260,8 @@
   }
 
   {
-    ScopedMarkRealtimeRestorer rt(simulated_event_loop_->priority() > 0);
+    ScopedMarkRealtimeRestorer rt(
+        simulated_event_loop_->runtime_realtime_priority() > 0);
     Call([monotonic_now]() { return monotonic_now; },
          [this](monotonic_clock::time_point sleep_time) {
            Schedule(sleep_time);