blob: 8dabcb5c4c38c980d9cbd887832226195edcba78 [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#ifndef AOS_EVENTS_SHM_EVENT_LOOP_H_
2#define AOS_EVENTS_SHM_EVENT_LOOP_H_
3
Alex Perrycb7da4b2019-08-28 19:35:56 -07004#include <vector>
5
Brian Silverman5120afb2020-01-31 17:44:35 -08006#include "absl/types/span.h"
7
Alex Perrycb7da4b2019-08-28 19:35:56 -07008#include "aos/events/epoll.h"
9#include "aos/events/event_loop.h"
Austin Schuh39788ff2019-12-01 18:22:57 -080010#include "aos/events/event_loop_generated.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070011
Jim Ostrowski2192ddb2020-06-24 19:07:31 -070012DECLARE_string(application_name);
13DECLARE_string(shm_base);
14
Alex Perrycb7da4b2019-08-28 19:35:56 -070015namespace aos {
Brian Silverman148d43d2020-06-07 18:19:22 -050016namespace shm_event_loop_internal {
Alex Perrycb7da4b2019-08-28 19:35:56 -070017
Brian Silverman148d43d2020-06-07 18:19:22 -050018class ShmWatcherState;
19class ShmTimerHandler;
20class ShmPhasedLoopHandler;
Austin Schuh39788ff2019-12-01 18:22:57 -080021class ShmSender;
Austin Schuh432784f2020-06-23 17:27:35 -070022class SimpleShmFetcher;
Austin Schuh39788ff2019-12-01 18:22:57 -080023class ShmFetcher;
Alex Perrycb7da4b2019-08-28 19:35:56 -070024
Brian Silverman148d43d2020-06-07 18:19:22 -050025} // namespace shm_event_loop_internal
Alex Perrycb7da4b2019-08-28 19:35:56 -070026
Brian Silverman4f4e0612020-08-12 19:54:41 -070027// Concrete implementation of EventLoop that is built from queues running out of
28// shared memory.
Alex Perrycb7da4b2019-08-28 19:35:56 -070029//
Austin Schuh39788ff2019-12-01 18:22:57 -080030// TODO(austin): Timing reports break multiple threads. Need to add back in a
31// mutex.
32// This object must be interacted with from one thread, but the Senders
33// and Fetchers may be used from multiple threads afterwords (as long as their
Alex Perrycb7da4b2019-08-28 19:35:56 -070034// destructors are called back in one thread again)
35class ShmEventLoop : public EventLoop {
36 public:
37 ShmEventLoop(const Configuration *configuration);
38 ~ShmEventLoop() override;
39
Austin Schuh39788ff2019-12-01 18:22:57 -080040 // Runs the event loop until Exit is called, or ^C is caught.
41 void Run();
42 // Exits the event loop. Async safe.
43 void Exit();
44
Alex Perrycb7da4b2019-08-28 19:35:56 -070045 aos::monotonic_clock::time_point monotonic_now() override {
46 return aos::monotonic_clock::now();
47 }
48 aos::realtime_clock::time_point realtime_now() override {
49 return aos::realtime_clock::now();
50 }
51
52 std::unique_ptr<RawSender> MakeRawSender(const Channel *channel) override;
53 std::unique_ptr<RawFetcher> MakeRawFetcher(const Channel *channel) override;
54
55 void MakeRawWatcher(
56 const Channel *channel,
57 std::function<void(const Context &context, const void *message)> watcher)
58 override;
Brian Silverman6b8a3c32020-03-06 11:26:14 -080059 void MakeRawNoArgWatcher(
60 const Channel *channel,
61 std::function<void(const Context &context)> watcher) override;
Alex Perrycb7da4b2019-08-28 19:35:56 -070062
63 TimerHandler *AddTimer(std::function<void()> callback) override;
Brian Silverman148d43d2020-06-07 18:19:22 -050064 PhasedLoopHandler *AddPhasedLoop(std::function<void(int)> callback,
65 const monotonic_clock::duration interval,
66 const monotonic_clock::duration offset =
67 std::chrono::seconds(0)) override;
Alex Perrycb7da4b2019-08-28 19:35:56 -070068
69 void OnRun(std::function<void()> on_run) override;
Alex Perrycb7da4b2019-08-28 19:35:56 -070070
71 void SetRuntimeRealtimePriority(int priority) override;
Brian Silverman6a54ff32020-04-28 16:41:39 -070072 void SetRuntimeAffinity(const cpu_set_t &cpuset) override;
Alex Perrycb7da4b2019-08-28 19:35:56 -070073
James Kuszmaul57c2baa2020-01-19 14:52:52 -080074 void set_name(const std::string_view name) override;
James Kuszmaul3ae42262019-11-08 12:33:41 -080075 const std::string_view name() const override { return name_; }
Austin Schuh217a9782019-12-21 23:02:50 -080076 const Node *node() const override { return node_; }
Alex Perrycb7da4b2019-08-28 19:35:56 -070077
Austin Schuh39788ff2019-12-01 18:22:57 -080078 int priority() const override { return priority_; }
Alex Perrycb7da4b2019-08-28 19:35:56 -070079
Brian Silverman5120afb2020-01-31 17:44:35 -080080 // Returns the epoll loop used to run the event loop.
Austin Schuhe84c3ed2019-12-14 15:29:48 -080081 internal::EPoll *epoll() { return &epoll_; }
82
Brian Silverman5120afb2020-01-31 17:44:35 -080083 // Returns the local mapping of the shared memory used by the watcher on the
84 // specified channel. A watcher must be created on this channel before calling
85 // this.
Brian Silvermana5450a92020-08-12 19:59:57 -070086 absl::Span<const char> GetWatcherSharedMemory(const Channel *channel);
Brian Silverman5120afb2020-01-31 17:44:35 -080087
Brian Silverman6d2b3592020-06-18 14:40:15 -070088 // Returns the local mapping of the shared memory used by the provided Sender.
Brian Silverman5120afb2020-01-31 17:44:35 -080089 template <typename T>
90 absl::Span<char> GetSenderSharedMemory(aos::Sender<T> *sender) const {
91 return GetShmSenderSharedMemory(GetRawSender(sender));
92 }
93
Brian Silverman6d2b3592020-06-18 14:40:15 -070094 // Returns the local mapping of the private memory used by the provided
95 // Fetcher to hold messages.
Brian Silvermana5450a92020-08-12 19:59:57 -070096 //
97 // Note that this may be the entire shared memory region held by this fetcher,
98 // depending on its channel's read_method.
Brian Silverman6d2b3592020-06-18 14:40:15 -070099 template <typename T>
Brian Silvermana5450a92020-08-12 19:59:57 -0700100 absl::Span<const char> GetFetcherPrivateMemory(
101 aos::Fetcher<T> *fetcher) const {
Brian Silverman6d2b3592020-06-18 14:40:15 -0700102 return GetShmFetcherPrivateMemory(GetRawFetcher(fetcher));
103 }
104
Brian Silverman4f4e0612020-08-12 19:54:41 -0700105 int NumberBuffers(const Channel *channel) override;
106
Alex Perrycb7da4b2019-08-28 19:35:56 -0700107 private:
Brian Silverman148d43d2020-06-07 18:19:22 -0500108 friend class shm_event_loop_internal::ShmWatcherState;
109 friend class shm_event_loop_internal::ShmTimerHandler;
110 friend class shm_event_loop_internal::ShmPhasedLoopHandler;
111 friend class shm_event_loop_internal::ShmSender;
Austin Schuh432784f2020-06-23 17:27:35 -0700112 friend class shm_event_loop_internal::SimpleShmFetcher;
Brian Silverman148d43d2020-06-07 18:19:22 -0500113 friend class shm_event_loop_internal::ShmFetcher;
Austin Schuh39788ff2019-12-01 18:22:57 -0800114
Austin Schuh432784f2020-06-23 17:27:35 -0700115 using EventLoop::SendTimingReport;
116
Brian Silverman6a54ff32020-04-28 16:41:39 -0700117 static cpu_set_t DefaultAffinity() {
118 cpu_set_t result;
119 for (int i = 0; i < CPU_SETSIZE; ++i) {
120 CPU_SET(i, &result);
121 }
122 return result;
123 }
124
Austin Schuh7d87b672019-12-01 20:23:49 -0800125 void HandleEvent();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700126
Austin Schuh39788ff2019-12-01 18:22:57 -0800127 // Returns the TID of the event loop.
128 pid_t GetTid() override;
129
Brian Silverman6d2b3592020-06-18 14:40:15 -0700130 // Private method to access the shared memory mapping of a ShmSender.
Brian Silverman5120afb2020-01-31 17:44:35 -0800131 absl::Span<char> GetShmSenderSharedMemory(const aos::RawSender *sender) const;
132
Brian Silverman6d2b3592020-06-18 14:40:15 -0700133 // Private method to access the private memory mapping of a ShmFetcher.
Brian Silvermana5450a92020-08-12 19:59:57 -0700134 absl::Span<const char> GetShmFetcherPrivateMemory(
Brian Silverman6d2b3592020-06-18 14:40:15 -0700135 const aos::RawFetcher *fetcher) const;
136
Alex Perrycb7da4b2019-08-28 19:35:56 -0700137 std::vector<std::function<void()>> on_run_;
138 int priority_ = 0;
Brian Silverman6a54ff32020-04-28 16:41:39 -0700139 cpu_set_t affinity_ = DefaultAffinity();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700140 std::string name_;
Austin Schuh217a9782019-12-21 23:02:50 -0800141 const Node *const node_;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700142
143 internal::EPoll epoll_;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700144};
145
Alex Perrycb7da4b2019-08-28 19:35:56 -0700146} // namespace aos
147
148#endif // AOS_EVENTS_SHM_EVENT_LOOP_H_