Expose the private buffers from fetchers too
This is handy for the same use cases where getting the shared memory is:
teaching other libraries about it to optimize its usage.
Change-Id: I41657333a70c2b9c9dbf8a30f0c52251eb590ba4
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index 7634479..6cb0365 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -594,12 +594,18 @@
// watcher must exist before calling this.
WatcherState *GetWatcherState(const Channel *channel);
- // Returns a Sender's protected RawSender
+ // Returns a Sender's protected RawSender.
template <typename T>
static RawSender *GetRawSender(aos::Sender<T> *sender) {
return sender->sender_.get();
}
+ // Returns a Fetcher's protected RawFetcher.
+ template <typename T>
+ static RawFetcher *GetRawFetcher(aos::Fetcher<T> *fetcher) {
+ return fetcher->fetcher_.get();
+ }
+
// Context available for watchers, timers, and phased loops.
Context context_;
diff --git a/aos/events/shm_event_loop.cc b/aos/events/shm_event_loop.cc
index ebfcc07..1315510 100644
--- a/aos/events/shm_event_loop.cc
+++ b/aos/events/shm_event_loop.cc
@@ -316,6 +316,13 @@
return lockless_queue_memory_.GetSharedMemory();
}
+ absl::Span<char> GetPrivateMemory() const {
+ CHECK(copy_data());
+ return absl::Span<char>(
+ const_cast<SimpleShmFetcher *>(this)->data_storage_start(),
+ lockless_queue_.message_data_size());
+ }
+
private:
char *data_storage_start() {
if (!copy_data()) return nullptr;
@@ -360,6 +367,10 @@
return std::make_pair(false, monotonic_clock::min_time);
}
+ absl::Span<char> GetPrivateMemory() const {
+ return simple_shm_fetcher_.GetPrivateMemory();
+ }
+
private:
SimpleShmFetcher simple_shm_fetcher_;
};
@@ -920,6 +931,11 @@
return static_cast<const ShmSender *>(sender)->GetSharedMemory();
}
+absl::Span<char> ShmEventLoop::GetShmFetcherPrivateMemory(
+ const aos::RawFetcher *fetcher) const {
+ return static_cast<const ShmFetcher *>(fetcher)->GetPrivateMemory();
+}
+
pid_t ShmEventLoop::GetTid() { return syscall(SYS_gettid); }
} // namespace aos
diff --git a/aos/events/shm_event_loop.h b/aos/events/shm_event_loop.h
index f832242..55fc85f 100644
--- a/aos/events/shm_event_loop.h
+++ b/aos/events/shm_event_loop.h
@@ -81,12 +81,19 @@
// this.
absl::Span<char> GetWatcherSharedMemory(const Channel *channel);
- // Returns the local mapping of the shared memory used by the provided Sender
+ // Returns the local mapping of the shared memory used by the provided Sender.
template <typename T>
absl::Span<char> GetSenderSharedMemory(aos::Sender<T> *sender) const {
return GetShmSenderSharedMemory(GetRawSender(sender));
}
+ // Returns the local mapping of the private memory used by the provided
+ // Fetcher to hold messages.
+ template <typename T>
+ absl::Span<char> GetFetcherPrivateMemory(aos::Fetcher<T> *fetcher) const {
+ return GetShmFetcherPrivateMemory(GetRawFetcher(fetcher));
+ }
+
private:
friend class shm_event_loop_internal::ShmWatcherState;
friend class shm_event_loop_internal::ShmTimerHandler;
@@ -107,9 +114,13 @@
// Returns the TID of the event loop.
pid_t GetTid() override;
- // Private method to access the shared memory mapping of a ShmSender
+ // Private method to access the shared memory mapping of a ShmSender.
absl::Span<char> GetShmSenderSharedMemory(const aos::RawSender *sender) const;
+ // Private method to access the private memory mapping of a ShmFetcher.
+ absl::Span<char> GetShmFetcherPrivateMemory(
+ const aos::RawFetcher *fetcher) const;
+
std::vector<std::function<void()>> on_run_;
int priority_ = 0;
cpu_set_t affinity_ = DefaultAffinity();
diff --git a/aos/events/shm_event_loop_test.cc b/aos/events/shm_event_loop_test.cc
index 0c39704..3244c39 100644
--- a/aos/events/shm_event_loop_test.cc
+++ b/aos/events/shm_event_loop_test.cc
@@ -207,11 +207,21 @@
auto generic_loop1 = factory.MakePrimary("primary");
ShmEventLoop *const loop1 = static_cast<ShmEventLoop *>(generic_loop1.get());
- // check that GetSenderSharedMemory returns non-null/non-empty memory span
+ // check that GetSenderSharedMemory returns non-null/non-empty memory span.
auto sender = loop1->MakeSender<TestMessage>("/test");
EXPECT_FALSE(loop1->GetSenderSharedMemory(&sender).empty());
}
+TEST(ShmEventLoopTest, GetFetcherPrivateMemory) {
+ ShmEventLoopTestFactory factory;
+ auto generic_loop1 = factory.MakePrimary("primary");
+ ShmEventLoop *const loop1 = static_cast<ShmEventLoop *>(generic_loop1.get());
+
+ // check that GetFetcherPrivateMemory returns non-null/non-empty memory span.
+ auto fetcher = loop1->MakeFetcher<TestMessage>("/test");
+ EXPECT_FALSE(loop1->GetFetcherPrivateMemory(&fetcher).empty());
+}
+
// TODO(austin): Test that missing a deadline with a timer recovers as expected.
} // namespace testing