Skip to content

Commit 93be83a

Browse files
committed
Shrink interrupts-locked regions.
Add check for periodic yield to scheduled functions run-loop.
1 parent 3ce09a7 commit 93be83a

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

cores/esp8266/Schedule.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct recurrent_fn_t
2626
esp8266::polledTimeout::periodicFastUs callNow;
2727
const std::atomic<bool>* wakeupToken = nullptr;
2828
bool wakeupTokenCmp = false;
29-
recurrent_fn_t (esp8266::polledTimeout::periodicFastUs interval): callNow(interval) { }
29+
recurrent_fn_t(esp8266::polledTimeout::periodicFastUs interval) : callNow(interval) { }
3030
};
3131

3232
static recurrent_fn_t rFirst(0); // fifo not needed
@@ -35,7 +35,7 @@ static recurrent_fn_t rFirst(0); // fifo not needed
3535
// or if none are available allocates a new one,
3636
// or nullptr if limit is reached
3737
IRAM_ATTR // called from ISR
38-
static scheduled_fn_t* get_fn_unsafe ()
38+
static scheduled_fn_t* get_fn_unsafe()
3939
{
4040
scheduled_fn_t* result = nullptr;
4141
// try to get an item from unused items list
@@ -54,15 +54,15 @@ static scheduled_fn_t* get_fn_unsafe ()
5454
return result;
5555
}
5656

57-
static void recycle_fn_unsafe (scheduled_fn_t* fn)
57+
static void recycle_fn_unsafe(scheduled_fn_t* fn)
5858
{
5959
fn->mFunc = nullptr; // special overload in c++ std lib
6060
fn->mNext = sUnused;
6161
sUnused = fn;
6262
}
6363

6464
IRAM_ATTR // (not only) called from ISR
65-
bool schedule_function (const std::function<void(void)>& fn)
65+
bool schedule_function(const std::function<void(void)>& fn)
6666
{
6767
if (!fn)
6868
return false;
@@ -85,16 +85,14 @@ bool schedule_function (const std::function<void(void)>& fn)
8585
return true;
8686
}
8787

88-
bool schedule_recurrent_function_us (const std::function<bool(void)>& fn, uint32_t repeat_us,
88+
bool schedule_recurrent_function_us(const std::function<bool(void)>& fn, uint32_t repeat_us,
8989
const std::atomic<bool>* wakeupToken)
9090
{
9191
assert(repeat_us < decltype(recurrent_fn_t::callNow)::neverExpires); //~26800000us (26.8s)
9292

9393
if (!fn)
9494
return false;
9595

96-
esp8266::InterruptLock lockAllInterruptsInThisScope;
97-
9896
recurrent_fn_t* item = new (std::nothrow) recurrent_fn_t(repeat_us);
9997
if (!item)
10098
return false;
@@ -103,13 +101,15 @@ bool schedule_recurrent_function_us (const std::function<bool(void)>& fn, uint32
103101
item->wakeupToken = wakeupToken;
104102
item->wakeupTokenCmp = wakeupToken && wakeupToken->load();
105103

104+
esp8266::InterruptLock lockAllInterruptsInThisScope;
105+
106106
item->mNext = rFirst.mNext;
107107
rFirst.mNext = item;
108108

109109
return true;
110110
}
111111

112-
void run_scheduled_functions ()
112+
void run_scheduled_functions()
113113
{
114114
esp8266::polledTimeout::periodicFastMs yieldNow(100); // yield every 100ms
115115

@@ -124,9 +124,9 @@ void run_scheduled_functions ()
124124
sFirst = sFirst->mNext;
125125
if (!sFirst)
126126
sLast = nullptr;
127-
recycle_fn_unsafe(to_recycle);
128-
}
129-
127+
recycle_fn_unsafe(to_recycle);
128+
}
129+
130130
if (yieldNow)
131131
{
132132
// because scheduled function are allowed to last:
@@ -137,8 +137,10 @@ void run_scheduled_functions ()
137137
}
138138
}
139139

140-
void run_scheduled_recurrent_functions ()
140+
void run_scheduled_recurrent_functions()
141141
{
142+
esp8266::polledTimeout::periodicFastMs yieldNow(100); // yield every 100ms
143+
142144
// Note to the reader:
143145
// There is no exposed API to remove a scheduled function:
144146
// Scheduled functions are removed only from this function, and
@@ -178,8 +180,8 @@ void run_scheduled_recurrent_functions ()
178180

179181
auto to_ditch = current;
180182

181-
// current function recursively scheduled something
182-
if (prev->mNext != current) prev = prev->mNext;
183+
// current function recursively scheduled something
184+
if (prev->mNext != current) prev = prev->mNext;
183185

184186
current = current->mNext;
185187
prev->mNext = current;
@@ -191,8 +193,15 @@ void run_scheduled_recurrent_functions ()
191193
prev = current;
192194
current = current->mNext;
193195
}
194-
}
195-
while (current);
196+
197+
if (yieldNow)
198+
{
199+
// because scheduled function might last too long for watchdog etc,
200+
// this is yield() in cont stack:
201+
esp_schedule();
202+
cont_yield(g_pcont);
203+
}
204+
} while (current);
196205

197206
fence = false;
198207
}

cores/esp8266/Schedule.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// in user stack (called CONT stack) without the common restrictions from
1212
// system context. Details are below.
1313

14-
// The purpose of recurrent scheduled function is to independantly execute
14+
// The purpose of recurrent scheduled function is to independently execute
1515
// user code in CONT stack on a regular basis.
1616
// It has been introduced with ethernet service in mind, it can also be used
1717
// for all libraries in the need of a regular `libdaemon_handlestuff()`.
@@ -37,7 +37,7 @@
3737
// * Run the lambda only once next time.
3838
// * A scheduled function can schedule a function.
3939

40-
bool schedule_function (const std::function<void(void)>& fn);
40+
bool schedule_function(const std::function<void(void)> & fn);
4141

4242
// Run all scheduled functions.
4343
// Use this function if your are not using `loop`,
@@ -59,16 +59,14 @@ void run_scheduled_functions();
5959
// functions. However a user function returning false will cancel itself.
6060
// * Long running operations or yield() or delay() are not allowed in the
6161
// recurrent function.
62-
// * A recurrent function currently must not schedule another recurrent
63-
// functions.
6462
// * If a wakeupToken is used, if its value toggles, any remaining
6563
// delay is disregarded, and the lambda runs on the next scheduler iteration.
66-
bool schedule_recurrent_function_us (const std::function<bool(void)>& fn, uint32_t repeat_us,
64+
bool schedule_recurrent_function_us(const std::function<bool(void)>& fn, uint32_t repeat_us,
6765
const std::atomic<bool>* wakeupToken = nullptr);
6866

6967
// Test recurrence and run recurrent scheduled functions.
7068
// (internally called at every `yield()` and `loop()`)
7169

72-
void run_scheduled_recurrent_functions ();
70+
void run_scheduled_recurrent_functions();
7371

7472
#endif // ESP_SCHEDULE_H

0 commit comments

Comments
 (0)