Skip to content

Commit 3b315d8

Browse files
committed
Finalize scheduled recurrent function delay logic.
1 parent d13651d commit 3b315d8

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

cores/esp8266/Schedule.cpp

+20-7
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct recurrent_fn_t
4747

4848
static recurrent_fn_t* rFirst = nullptr;
4949
static recurrent_fn_t* rLast = nullptr;
50-
static uint32_t rScheduleTarget = 0;
50+
static uint32_t rTarget;
5151

5252
// Returns a pointer to an unused sched_fn_t,
5353
// or if none are available allocates a new one,
@@ -118,10 +118,13 @@ bool schedule_recurrent_function_us(const std::function<bool(void)>& fn,
118118

119119
item->mFunc = fn;
120120
item->alarm = alarm;
121-
// if (!rScheduleTarget || rScheduleTarget > item.callNow.remaining())
122-
// {
123-
// rScheduleTarget = item.callNow.remaining();
124-
// }
121+
122+
// prevent new item overwriting an already expired rTarget.
123+
const int32_t rRemaining = rTarget - millis();
124+
if (!rFirst || (rRemaining > 0 && static_cast<uint32_t>(rRemaining) > item->callNow.remaining()))
125+
{
126+
rTarget = millis() + item->callNow.remaining();
127+
}
125128

126129
esp8266::InterruptLock lockAllInterruptsInThisScope;
127130

@@ -138,9 +141,12 @@ bool schedule_recurrent_function_us(const std::function<bool(void)>& fn,
138141
return true;
139142
}
140143

141-
uint32_t compute_scheduled_recurrent_grain()
144+
uint32_t get_scheduled_recurrent_delay()
142145
{
143-
return 0;
146+
if (!rFirst) return ~static_cast<uint32_t>(0);
147+
// handle already expired rTarget.
148+
const int32_t rRemaining = rTarget - millis();
149+
return (rRemaining > 0) ? static_cast<uint32_t>(rRemaining) : 0;
144150
}
145151

146152
void run_scheduled_functions()
@@ -203,6 +209,7 @@ void run_scheduled_recurrent_functions()
203209
fence = true;
204210
}
205211

212+
rTarget = millis() + current->callNow.remaining();
206213
recurrent_fn_t* prev = nullptr;
207214
// prevent scheduling of new functions during this run
208215
auto stop = rLast;
@@ -241,6 +248,12 @@ void run_scheduled_recurrent_functions()
241248
{
242249
prev = current;
243250
current = current->mNext;
251+
// prevent current item overwriting an already expired rTarget.
252+
const int32_t rRemaining = rTarget - millis();
253+
if (rRemaining > 0 && static_cast<uint32_t>(rRemaining) > current->callNow.remaining())
254+
{
255+
rTarget = millis() + current->callNow.remaining();
256+
}
244257
}
245258

246259
if (yieldNow)

cores/esp8266/Schedule.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
// scheduled function happen more often: every yield() (vs every loop()),
4040
// and time resolution is microsecond (vs millisecond). Details are below.
4141

42-
// compute_scheduled_recurrent_grain() is used by delay() to give a chance to
42+
// get_scheduled_recurrent_delay() is used by delay() to give a chance to
4343
// all recurrent functions to run per their timing requirement.
4444

45-
uint32_t compute_scheduled_recurrent_grain ();
45+
uint32_t get_scheduled_recurrent_delay();
4646

4747
// scheduled functions called once:
4848
//

cores/esp8266/core_esp8266_main.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,10 @@ bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uin
173173
}
174174

175175
// compute greatest delay interval with respect to scheduled recurrent functions
176-
uint32_t grain_ms = std::min(intvl_ms, compute_scheduled_recurrent_grain());
176+
const uint32_t max_delay_ms = std::min(intvl_ms, get_scheduled_recurrent_delay());
177177

178178
// recurrent scheduled functions will be called from esp_delay()->esp_suspend()
179-
esp_delay(grain_ms > 0 ?
180-
std::min((timeout_ms - expired), grain_ms) :
181-
(timeout_ms - expired));
179+
esp_delay(std::min((timeout_ms - expired), max_delay_ms));
182180

183181
return false; // expiration must be checked again
184182
}

0 commit comments

Comments
 (0)