@@ -26,7 +26,7 @@ struct recurrent_fn_t
26
26
esp8266::polledTimeout::periodicFastUs callNow;
27
27
const std::atomic<bool >* wakeupToken = nullptr ;
28
28
bool wakeupTokenCmp = false ;
29
- recurrent_fn_t (esp8266::polledTimeout::periodicFastUs interval): callNow(interval) { }
29
+ recurrent_fn_t (esp8266::polledTimeout::periodicFastUs interval) : callNow(interval) { }
30
30
};
31
31
32
32
static recurrent_fn_t rFirst (0 ); // fifo not needed
@@ -35,7 +35,7 @@ static recurrent_fn_t rFirst(0); // fifo not needed
35
35
// or if none are available allocates a new one,
36
36
// or nullptr if limit is reached
37
37
IRAM_ATTR // called from ISR
38
- static scheduled_fn_t * get_fn_unsafe ()
38
+ static scheduled_fn_t * get_fn_unsafe ()
39
39
{
40
40
scheduled_fn_t * result = nullptr ;
41
41
// try to get an item from unused items list
@@ -54,15 +54,15 @@ static scheduled_fn_t* get_fn_unsafe ()
54
54
return result;
55
55
}
56
56
57
- static void recycle_fn_unsafe (scheduled_fn_t * fn)
57
+ static void recycle_fn_unsafe (scheduled_fn_t * fn)
58
58
{
59
59
fn->mFunc = nullptr ; // special overload in c++ std lib
60
60
fn->mNext = sUnused ;
61
61
sUnused = fn;
62
62
}
63
63
64
64
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)
66
66
{
67
67
if (!fn)
68
68
return false ;
@@ -85,16 +85,14 @@ bool schedule_function (const std::function<void(void)>& fn)
85
85
return true ;
86
86
}
87
87
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,
89
89
const std::atomic<bool>* wakeupToken)
90
90
{
91
91
assert (repeat_us < decltype (recurrent_fn_t ::callNow)::neverExpires); // ~26800000us (26.8s)
92
92
93
93
if (!fn)
94
94
return false ;
95
95
96
- esp8266::InterruptLock lockAllInterruptsInThisScope;
97
-
98
96
recurrent_fn_t * item = new (std::nothrow) recurrent_fn_t (repeat_us);
99
97
if (!item)
100
98
return false ;
@@ -103,13 +101,15 @@ bool schedule_recurrent_function_us (const std::function<bool(void)>& fn, uint32
103
101
item->wakeupToken = wakeupToken;
104
102
item->wakeupTokenCmp = wakeupToken && wakeupToken->load ();
105
103
104
+ esp8266::InterruptLock lockAllInterruptsInThisScope;
105
+
106
106
item->mNext = rFirst.mNext ;
107
107
rFirst.mNext = item;
108
108
109
109
return true ;
110
110
}
111
111
112
- void run_scheduled_functions ()
112
+ void run_scheduled_functions ()
113
113
{
114
114
esp8266::polledTimeout::periodicFastMs yieldNow (100 ); // yield every 100ms
115
115
@@ -124,9 +124,9 @@ void run_scheduled_functions ()
124
124
sFirst = sFirst ->mNext ;
125
125
if (!sFirst )
126
126
sLast = nullptr ;
127
- recycle_fn_unsafe (to_recycle);
128
- }
129
-
127
+ recycle_fn_unsafe (to_recycle);
128
+ }
129
+
130
130
if (yieldNow)
131
131
{
132
132
// because scheduled function are allowed to last:
@@ -137,8 +137,10 @@ void run_scheduled_functions ()
137
137
}
138
138
}
139
139
140
- void run_scheduled_recurrent_functions ()
140
+ void run_scheduled_recurrent_functions ()
141
141
{
142
+ esp8266::polledTimeout::periodicFastMs yieldNow (100 ); // yield every 100ms
143
+
142
144
// Note to the reader:
143
145
// There is no exposed API to remove a scheduled function:
144
146
// Scheduled functions are removed only from this function, and
@@ -178,8 +180,8 @@ void run_scheduled_recurrent_functions ()
178
180
179
181
auto to_ditch = current;
180
182
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 ;
183
185
184
186
current = current->mNext ;
185
187
prev->mNext = current;
@@ -191,8 +193,15 @@ void run_scheduled_recurrent_functions ()
191
193
prev = current;
192
194
current = current->mNext ;
193
195
}
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);
196
205
197
206
fence = false ;
198
207
}
0 commit comments