44#include " Schedule.h"
55#include " PolledTimeout.h"
66#include " interrupts.h"
7+ #include " coredecls.h"
78
89typedef std::function<bool (void )> mFuncT ;
910
@@ -12,15 +13,14 @@ struct scheduled_fn_t
1213 scheduled_fn_t * mNext = nullptr ;
1314 mFuncT mFunc ;
1415 esp8266::polledTimeout::periodicFastUs callNow;
16+ schedule_e policy;
1517
1618 scheduled_fn_t () : callNow(esp8266::polledTimeout::periodicFastUs::alwaysExpired) { }
1719};
1820
1921static scheduled_fn_t * sFirst = nullptr ;
2022static scheduled_fn_t * sLast = nullptr ;
21-
2223static scheduled_fn_t * sUnused = nullptr ;
23-
2424static int sCount = 0 ;
2525
2626IRAM_ATTR // called from ISR
@@ -52,7 +52,7 @@ static void recycle_fn_unsafe(scheduled_fn_t* fn)
5252}
5353
5454IRAM_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 )
5656{
5757 assert (repeat_us < decltype (scheduled_fn_t ::callNow)::neverExpires); // ~26800000us (26.8s)
5858
@@ -64,8 +64,9 @@ bool schedule_function_us(std::function<bool(void)>&& fn, uint32_t repeat_us)
6464
6565 if (repeat_us)
6666 item->callNow .reset (repeat_us);
67-
67+ item-> policy = policy;
6868 item->mFunc = fn;
69+
6970 if (sFirst )
7071 sLast ->mNext = item;
7172 else
@@ -76,24 +77,24 @@ bool schedule_function_us(std::function<bool(void)>&& fn, uint32_t repeat_us)
7677}
7778
7879IRAM_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 )
8081{
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 );
8283}
8384
8485IRAM_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 )
8687{
87- return schedule_function_us ([fn]() { fn (); return false ; }, 0 );
88+ return schedule_function_us ([fn]() { fn (); return false ; }, 0 , policy );
8889}
8990
9091IRAM_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 )
9293{
93- return schedule_function (std::function<void (void )>(fn));
94+ return schedule_function (std::function<void (void )>(fn), policy );
9495}
9596
96- void run_scheduled_functions ()
97+ void run_scheduled_functions (schedule_e policy )
9798{
9899 // Note to the reader:
99100 // There is no exposed API to remove a scheduled function:
@@ -110,13 +111,22 @@ void run_scheduled_functions()
110111 fence = true ;
111112 }
112113
114+ esp8266::polledTimeout::periodicFastMs yieldNow (100 ); // yield every 100ms
113115 scheduled_fn_t * lastRecurring = nullptr ;
114116 scheduled_fn_t * nextCall = sFirst ;
115117 while (nextCall)
116118 {
117119 scheduled_fn_t * toCall = nextCall;
118120 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 )
120130 {
121131 if (toCall->mFunc ())
122132 {
@@ -142,6 +152,13 @@ void run_scheduled_functions()
142152 else
143153 // function stays in list
144154 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+ }
145162 }
146163
147164 fence = false ;
0 commit comments