Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
RefreshLoop.hxx
Go to the documentation of this file.
1
34#ifndef _OPENLCB_REFRESHLOOP_HXX_
35#define _OPENLCB_REFRESHLOOP_HXX_
36
37#include <vector>
38
40#include "executor/Timer.hxx"
42
43namespace openlcb
44{
45
49{
50public:
54 virtual void poll_33hz(WriteHelper *helper, Notifiable *done) = 0;
55};
56
62class RefreshLoop : public StateFlowBase, private Atomic
63{
64public:
72 template <class Container = std::initializer_list<Polling*> >
73 RefreshLoop(Node *node, const Container &members)
74 : StateFlowBase(node->iface())
75 , timer_(this)
77 , members_(members.begin(), members.end())
78 {
80 }
81
84 void stop()
85 {
88 }
89
95 void add_member(Polling *new_member)
96 {
97 AtomicHolder h(this);
98 members_.push_back(new_member);
99 }
100
104 {
106 nextMember_ = 0;
107 // If we have overflowed our timer, this call will happen immediately.
109 STATE(call_members));
110 }
111
112 Action call_members()
113 {
114 while (true)
115 {
116 Polling* member = nullptr;
117 {
118 AtomicHolder h(this);
119 if (nextMember_ >= members_.size())
120 {
122 }
123 member = members_[nextMember_];
124 ++nextMember_;
125 }
126 bn_.reset(this);
127 member->poll_33hz(&helper_, bn_.new_child());
129 {
130 // The polling member called done notifiable inline. Short
131 // circuits the yield to the executor.
132 continue;
133 }
134 bn_.maybe_done();
135 return wait();
136 }
137 }
138
139private:
145 long long lastTimeout_;
149 typedef vector<Polling*> members_type;
153 unsigned nextMember_;
154};
155
156} // namespace openlcb
157
158#endif // _OPENLCB_REFRESHLOOP_HXX_
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Definition StateFlow.hxx:61
See OSMutexLock in os/OS.hxx.
Definition Atomic.hxx:153
Lightweight locking class for protecting small critical sections.
Definition Atomic.hxx:130
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
BarrierNotifiable * reset(Notifiable *done)
Resets the barrier. Returns &*this. Asserts that is_done().
void maybe_done()
When there are no more child tasks to add, call maybe_done().
BarrierNotifiable * new_child()
Call this for each child task.
bool abort_if_almost_done()
Checks if there is exactly one outstanding notification left in the barrier.
An object that can schedule itself on an executor to run.
Return type for a state flow callback.
Use this timer class to deliver the timeout notification to a stateflow.
Base class for state machines.
void start_flow(Callback c)
Resets the flow to the specified state and starts it.
Action wait()
Wait for an asynchronous call.
Action call_immediately(Callback c)
Imediately call the next state upon return.
Action set_terminated()
Sets the flow to terminated state.
Action sleep_and_call(::Timer *timer, long long timeout_nsec, Callback c)
Suspends execution of this control flow for a specified time.
void ensure_triggered()
Triggers the timer if it is not expired yet.
Definition Timer.hxx:249
Base class for NMRAnet nodes conforming to the asynchronous interface.
Definition Node.hxx:52
Abstract base class for components that need repeated execution (with a specified frequency,...
virtual void poll_33hz(WriteHelper *helper, Notifiable *done)=0
This function will be called approximately 33 times per second by the refresh loop.
State flow that calls a set of Polling objects at a regular interval.
members_type members_
The actual members.
RefreshLoop(Node *node, const Container &members)
Constructor.
StateFlowTimer timer_
Helper object for sleeps.
vector< Polling * > members_type
Data structure type for storing the polling members.
long long lastTimeout_
Rolling clock of when the next wakeup should happen.
void stop()
Stops the refresh loop.
void add_member(Polling *new_member)
Adds a new member to the polling loop.
Action wait_for_tick()
State which gets called after the loop is complete.
unsigned nextMember_
Index for iterating through the members list.
WriteHelper helper_
Message write buffer that is passed to each polling object.
BarrierNotifiable bn_
Controllable notifier to be passed into the polling objects.
A statically allocated buffer for sending one message to the OpenLCB bus.
long long os_get_time_monotonic(void)
Get the monotonic time since the system started.
Definition os.c:571
#define MSEC_TO_NSEC(_msec)
Convert a millisecond value to a nanosecond value.
Definition os.h:268