4
4
#include " Schedule.h"
5
5
#include " PolledTimeout.h"
6
6
#include " interrupts.h"
7
+ #include " coredecls.h"
7
8
8
9
typedef std::function<bool (void )> mFuncT ;
9
10
@@ -12,15 +13,14 @@ struct scheduled_fn_t
12
13
scheduled_fn_t * mNext = nullptr ;
13
14
mFuncT mFunc ;
14
15
esp8266::polledTimeout::periodicFastUs callNow;
16
+ schedule_e policy;
15
17
16
18
scheduled_fn_t () : callNow(esp8266::polledTimeout::periodicFastUs::alwaysExpired) { }
17
19
};
18
20
19
21
static scheduled_fn_t * sFirst = nullptr ;
20
22
static scheduled_fn_t * sLast = nullptr ;
21
-
22
23
static scheduled_fn_t * sUnused = nullptr ;
23
-
24
24
static int sCount = 0 ;
25
25
26
26
IRAM_ATTR // called from ISR
@@ -52,7 +52,7 @@ static void recycle_fn_unsafe(scheduled_fn_t* fn)
52
52
}
53
53
54
54
IRAM_ATTR // (not only) called from ISR
55
- bool schedule_function_us (std::function<bool (void )>&& fn, uint32_t repeat_us)
55
+ bool schedule_function_us (std::function<bool (void )>&& fn, uint32_t repeat_us, schedule_e policy )
56
56
{
57
57
assert (repeat_us < decltype (scheduled_fn_t ::callNow)::neverExpires); // ~26800000us (26.8s)
58
58
@@ -64,8 +64,9 @@ bool schedule_function_us(std::function<bool(void)>&& fn, uint32_t repeat_us)
64
64
65
65
if (repeat_us)
66
66
item->callNow .reset (repeat_us);
67
-
67
+ item-> policy = policy;
68
68
item->mFunc = fn;
69
+
69
70
if (sFirst )
70
71
sLast ->mNext = item;
71
72
else
@@ -76,24 +77,24 @@ bool schedule_function_us(std::function<bool(void)>&& fn, uint32_t repeat_us)
76
77
}
77
78
78
79
IRAM_ATTR // (not only) called from ISR
79
- bool schedule_function_us (const std::function<bool (void )>& fn, uint32_t repeat_us)
80
+ bool schedule_function_us (const std::function<bool (void )>& fn, uint32_t repeat_us, schedule_e policy )
80
81
{
81
- return schedule_function_us (std::function<bool (void )>(fn), repeat_us);
82
+ return schedule_function_us (std::function<bool (void )>(fn), repeat_us, policy );
82
83
}
83
84
84
85
IRAM_ATTR // called from ISR
85
- bool schedule_function (std::function<void (void )>&& fn)
86
+ bool schedule_function (std::function<void (void )>&& fn, schedule_e policy )
86
87
{
87
- return schedule_function_us ([fn]() { fn (); return false ; }, 0 );
88
+ return schedule_function_us ([fn]() { fn (); return false ; }, 0 , policy );
88
89
}
89
90
90
91
IRAM_ATTR // called from ISR
91
- bool schedule_function (const std::function<void (void )>& fn)
92
+ bool schedule_function (const std::function<void (void )>& fn, schedule_e policy )
92
93
{
93
- return schedule_function (std::function<void (void )>(fn));
94
+ return schedule_function (std::function<void (void )>(fn), policy );
94
95
}
95
96
96
- void run_scheduled_functions ()
97
+ void run_scheduled_functions (schedule_e policy )
97
98
{
98
99
// Note to the reader:
99
100
// There is no exposed API to remove a scheduled function:
@@ -110,13 +111,22 @@ void run_scheduled_functions()
110
111
fence = true ;
111
112
}
112
113
114
+ esp8266::polledTimeout::periodicFastMs yieldNow (100 ); // yield every 100ms
113
115
scheduled_fn_t * lastRecurring = nullptr ;
114
116
scheduled_fn_t * nextCall = sFirst ;
115
117
while (nextCall)
116
118
{
117
119
scheduled_fn_t * toCall = nextCall;
118
120
nextCall = nextCall->mNext ;
119
- if (toCall->callNow )
121
+
122
+ // run scheduled function:
123
+ // - when its schedule policy allows it anytime
124
+ // - or if we are called at loop() time
125
+ // and
126
+ // - its time policy allows it
127
+ if ( ( toCall->policy == SCHEDULED_FUNCTION_WITHOUT_YIELDELAYCALLS
128
+ || policy == SCHEDULED_FUNCTION_ONCE_PER_LOOP)
129
+ && toCall->callNow )
120
130
{
121
131
if (toCall->mFunc ())
122
132
{
@@ -142,6 +152,13 @@ void run_scheduled_functions()
142
152
else
143
153
// function stays in list
144
154
lastRecurring = toCall;
155
+
156
+ if (policy == SCHEDULED_FUNCTION_ONCE_PER_LOOP && yieldNow)
157
+ {
158
+ // this is yield() in cont stack:
159
+ esp_schedule ();
160
+ cont_yield (g_pcont);
161
+ }
145
162
}
146
163
147
164
fence = false ;
0 commit comments