Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit369b1ab

Browse files
committed
Use CAS to minimize critical sections.
1 parentb6ec857 commit369b1ab

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

‎cores/esp8266/Schedule.cpp‎

Lines 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
structscheduled_fn_t
@@ -47,7 +48,7 @@ struct recurrent_fn_t
4748
staticrecurrent_fn_t* rFirst =nullptr;
4849
staticrecurrent_fn_t* rLast =nullptr;
4950
// The target time for scheduling the next timed recurrent function
50-
staticdecltype(micros()) rTarget;
51+
staticstd::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
constauto now =micros();
138138
constauto itemRemaining = item->callNow.remaining();
139-
constauto remaining = rTarget - now;
140-
if (!rFirst || (remaining <= HALF_MAX_MICROS && remaining > itemRemaining))
139+
for (auto _rTarget = rTarget.load(); ;)
141140
{
142-
rTarget = now + itemRemaining;
141+
constauto 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
constauto now =micros();
163-
constauto remaining = rTarget - now;
167+
constauto 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
constauto now =micros();
275276
constauto currentRemaining = current->callNow.remaining();
276-
constauto remaining = rTarget - now;
277-
if (remaining <= HALF_MAX_MICROS && remaining > currentRemaining)
277+
for (auto _rTarget = rTarget.load(); ;)
278278
{
279-
rTarget = now + currentRemaining;
279+
constauto 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)

[8]ページ先頭

©2009-2025 Movatter.jp