Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b3b4aa0

Browse filesBrowse files
committed
Use CAS to minimize critical sections.
1 parent 861cf02 commit b3b4aa0
Copy full SHA for b3b4aa0

File tree

Expand file treeCollapse file tree

1 file changed

+22
-15
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+22
-15
lines changed

‎cores/esp8266/Schedule.cpp

Copy file name to clipboardExpand all lines: cores/esp8266/Schedule.cpp
+22-15Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "Schedule.h"
2222
#include "PolledTimeout.h"
2323
#include "interrupts.h"
24+
#include <atomic>
2425

2526
typedef std::function<void(void)> mSchedFuncT;
2627
struct scheduled_fn_t
@@ -47,7 +48,7 @@ struct recurrent_fn_t
4748
static recurrent_fn_t* rFirst = nullptr;
4849
static recurrent_fn_t* rLast = nullptr;
4950
// The target time for scheduling the next timed recurrent function
50-
static decltype(micros()) rTarget;
51+
static std::atomic<decltype(micros())> rTarget;
5152

5253
// As 32 bit unsigned integer, micros() rolls over every 71.6 minutes.
5354
// For unambiguous earlier/later order between two timestamps,
@@ -133,13 +134,17 @@ bool schedule_recurrent_function_us(const std::function<bool(void)>& fn,
133134

134135
esp8266::InterruptLock lockAllInterruptsInThisScope;
135136

136-
// prevent new item overwriting an already expired rTarget.
137137
const auto now = micros();
138138
const auto itemRemaining = item->callNow.remaining();
139-
const auto remaining = rTarget - now;
140-
if (!rFirst || (remaining <= HALF_MAX_MICROS && remaining > itemRemaining))
139+
for (auto _rTarget = rTarget.load(); ;)
141140
{
142-
rTarget = now + itemRemaining;
141+
const auto remaining = _rTarget - now;
142+
if (!rFirst || (remaining <= HALF_MAX_MICROS && remaining > itemRemaining))
143+
{
144+
// if (!rTarget.compare_exchange_weak(_rTarget, now + itemRemaining)) continue;
145+
rTarget = now + itemRemaining; // interrupt lock is active, no ABA issue
146+
}
147+
break;
143148
}
144149

145150
if (rLast)
@@ -158,9 +163,8 @@ bool schedule_recurrent_function_us(const std::function<bool(void)>& fn,
158163
decltype(micros()) get_scheduled_recurrent_delay_us()
159164
{
160165
if (!rFirst) return HALF_MAX_MICROS;
161-
// handle already expired rTarget.
162166
const auto now = micros();
163-
const auto remaining = rTarget - now;
167+
const auto remaining = rTarget.load() - now;
164168
return (remaining <= HALF_MAX_MICROS) ? remaining : 0;
165169
}
166170

@@ -233,9 +237,9 @@ void run_scheduled_recurrent_functions()
233237
recurrent_fn_t* prev = nullptr;
234238
bool done;
235239

240+
rTarget.store(micros() + HALF_MAX_MICROS);
236241
// prevent scheduling of new functions during this run
237242
stop = rLast;
238-
rTarget = micros() + HALF_MAX_MICROS;
239243

240244
do
241245
{
@@ -268,17 +272,20 @@ void run_scheduled_recurrent_functions()
268272
}
269273
else
270274
{
271-
esp8266::InterruptLock lockAllInterruptsInThisScope;
272-
273-
// prevent current item overwriting an already expired rTarget.
274275
const auto now = micros();
275276
const auto currentRemaining = current->callNow.remaining();
276-
const auto remaining = rTarget - now;
277-
if (remaining <= HALF_MAX_MICROS && remaining > currentRemaining)
277+
for (auto _rTarget = rTarget.load(); ;)
278278
{
279-
rTarget = now + currentRemaining;
279+
const auto remaining = _rTarget - now;
280+
if (remaining <= HALF_MAX_MICROS && remaining > currentRemaining)
281+
{
282+
// if (!rTarget.compare_exchange_weak(_rTarget, now + currentRemaining)) continue;
283+
esp8266::InterruptLock lockAllInterruptsInThisScope;
284+
if (rTarget != _rTarget) { _rTarget = rTarget; continue; }
285+
rTarget = now + currentRemaining;
286+
}
287+
break;
280288
}
281-
282289
prev = current;
283290
current = current->mNext;
284291
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.