Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Timer.cxx
Go to the documentation of this file.
1
35#include "executor/Timer.hxx"
36#include "executor/Executor.hxx"
37#include "os/os.h"
38
44
46{
47 isExpired_ = 0;
48 long long new_period = timeout();
49 if (new_period == RESTART)
50 {
51 when_ += period_;
52 isActive_ = 1;
54 }
55 else if (new_period == DELETE)
56 {
57 delete this;
58 }
59 else if (new_period > 0)
60 {
61 start(new_period);
62 }
63}
64
65ActiveTimers::~ActiveTimers()
66{
67}
68
70{
71 if (isPending_.exchange(1) == 0)
72 {
73 executor_->add(this);
74 }
75}
76
78{
79 isPending_ = 0;
80 // Do nothing; the work of scheduling users is done in the get_next_timeout
81 // call.
82}
83
85{
87
88 QMember **last = &activeTimers_.next;
89 Timer *current_timer = static_cast<Timer *>(*last);
90 long long now = OSTime::get_monotonic();
91 bool found_timer = false;
92 while (current_timer && current_timer->when_ <= now)
93 {
94 // Deques next timer.
95 found_timer = true;
96 *last = current_timer->next;
97 current_timer->next = nullptr;
98
99 current_timer->isActive_ = 0;
100 current_timer->isExpired_ = 1;
101 // Puts it on the executor.
102 executor_->add(current_timer, current_timer->priority_);
103 // Takes the next timer.
104 current_timer = static_cast<Timer *>(*last);
105 }
106
107 if (found_timer)
108 {
109 return 0;
110 }
111 else if (current_timer)
112 {
113 long long ret = current_timer->when_ - now;
114 return ret;
115 }
116 else
117 {
118 // Wakes up the timer service every now and then. It won't make any
119 // difference.
120 return SEC_TO_NSEC(3600);
121 }
122}
123
125 OSMutexLock l(&lock_);
126
127 QMember **last = &activeTimers_.next;
128 Timer *current_timer = static_cast<Timer *>(*last);
129 return (current_timer == nullptr);
130}
131
133{
134 OSMutexLock l(&lock_);
135 insert_locked(timer);
136}
137
139{
140 HASSERT(timer);
141 HASSERT(timer->next == nullptr);
142
143 QMember **last = &activeTimers_.next;
144 Timer *current_timer = static_cast<Timer *>(*last);
145 while (current_timer && current_timer->when_ <= timer->when_)
146 {
147 last = &current_timer->next;
148 current_timer = static_cast<Timer *>(*last);
149 }
150 // Inserts into the queue.
151 timer->next = current_timer;
152 *last = timer;
153
154 // This will wake up the executor, which will schedule all expired timers
155 // and recompute sleep length.
156 notify();
157}
158
160{
161 HASSERT(timer);
162 // Removes the timer from the queue.
163 QMember **last = &activeTimers_.next;
164 while (*last && *last != timer)
165 {
166 last = &((*last)->next);
167 }
168 HASSERT(*last == timer);
169 *last = timer->next;
170 timer->next = nullptr;
171}
172
174{
175 HASSERT(timer);
176 OSMutexLock l(&lock_);
177 remove_locked(timer);
178 insert_locked(timer);
179}
180
182{
183 HASSERT(timer);
184 OSMutexLock l(&lock_);
185 remove_locked(timer);
186 timer->isActive_ = 0;
187}
ExecutorBase * executor_
Parent.
Definition Timer.hxx:117
void run() override
Callback from the executor.
Definition Timer.cxx:77
void remove_timer(::Timer *timer)
Deletes an already scheduled but not yet expired timer.
Definition Timer.cxx:181
void remove_locked(::Timer *timer)
Removes a timer from the active list.
Definition Timer.cxx:159
void insert_locked(::Timer *timer)
Inserts a timer into the active list.
Definition Timer.cxx:138
std::atomic_uint_least8_t isPending_
1 if we in the executor's queue.
Definition Timer.hxx:123
void schedule_timer(::Timer *timer)
Adds a new timer to the active timer list.
Definition Timer.cxx:132
long long get_next_timeout()
Tell when the first timer will expire.
Definition Timer.cxx:84
bool empty()
Definition Timer.cxx:124
void update_timer(::Timer *timer)
Updates the expiration time of an already scheduled timer.
Definition Timer.cxx:173
void notify() override
Notification callback from the timer.
Definition Timer.cxx:69
OSMutex lock_
Protects the timer list.
Definition Timer.hxx:119
QMember activeTimers_
List of timers that are scheduled.
Definition Timer.hxx:121
virtual void add(Executable *action, unsigned priority=UINT_MAX)=0
Send a message to this Executor's queue.
Class to allow convenient locking and unlocking of mutexes in a C context.
Definition OS.hxx:494
static long long get_monotonic()
Get the monotonic time since the system started.
Definition OS.hxx:560
Essentially a "next" pointer container.
Definition QMember.hxx:42
QMember * next
pointer to the next member in the queue
Definition QMember.hxx:65
A timer that can schedule itself to run on an executor at specified times in the future.
Definition Timer.hxx:134
~Timer()
Destructor.
Definition Timer.cxx:39
@ RESTART
Restart the timer with existing period.
Definition Timer.hxx:162
@ DELETE
delete the timer, use with extreme caution
Definition Timer.hxx:163
unsigned isActive_
true when the timer is in the active timers list
Definition Timer.hxx:306
void start(long long period=-1)
Starts a timer.
Definition Timer.hxx:185
void run() override
Callback from the executor when this timer is scheduled.
Definition Timer.cxx:45
ActiveTimers * activeTimers_
Points to the executor's timer structure.
Definition Timer.hxx:298
long long period_
period in nanoseconds for timer
Definition Timer.hxx:304
long long when_
when in nanoseconds timer should expire
Definition Timer.hxx:302
unsigned isExpired_
True when the timer is in the pending executables list of the Executor.
Definition Timer.hxx:309
virtual long long timeout()=0
Clients of timer should override this function.
unsigned priority_
what priority to schedule this timer at
Definition Timer.hxx:300
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define SEC_TO_NSEC(_sec)
Convert a second value to a nanosecond value.
Definition os.h:286