Skip to content

Commit 28c0222

Browse files
committed
Ordered, more predictable, scheduling. Before, it had different ordering compared to
FastScheduler as well as sequential calls from loop().
1 parent 93be83a commit 28c0222

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

cores/esp8266/Schedule.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ struct recurrent_fn_t
2929
recurrent_fn_t(esp8266::polledTimeout::periodicFastUs interval) : callNow(interval) { }
3030
};
3131

32-
static recurrent_fn_t rFirst(0); // fifo not needed
32+
static recurrent_fn_t rFirst(0);
33+
static recurrent_fn_t* rLast = &rFirst;
3334

3435
// Returns a pointer to an unused sched_fn_t,
3536
// or if none are available allocates a new one,
@@ -98,13 +99,14 @@ bool schedule_recurrent_function_us(const std::function<bool(void)>& fn, uint32_
9899
return false;
99100

100101
item->mFunc = fn;
102+
item->mNext = nullptr;
101103
item->wakeupToken = wakeupToken;
102104
item->wakeupTokenCmp = wakeupToken && wakeupToken->load();
103105

104106
esp8266::InterruptLock lockAllInterruptsInThisScope;
105107

106-
item->mNext = rFirst.mNext;
107-
rFirst.mNext = item;
108+
rLast->mNext = item;
109+
rLast = item;
108110

109111
return true;
110112
}
@@ -124,9 +126,9 @@ void run_scheduled_functions()
124126
sFirst = sFirst->mNext;
125127
if (!sFirst)
126128
sLast = nullptr;
127-
recycle_fn_unsafe(to_recycle);
128-
}
129-
129+
recycle_fn_unsafe(to_recycle);
130+
}
131+
130132
if (yieldNow)
131133
{
132134
// because scheduled function are allowed to last:
@@ -147,7 +149,7 @@ void run_scheduled_recurrent_functions()
147149
// its purpose is that it is never called from an interrupt
148150
// (always on cont stack).
149151

150-
recurrent_fn_t* current = rFirst.mNext;
152+
auto current = rFirst.mNext;
151153
if (!current)
152154
return;
153155

@@ -164,10 +166,14 @@ void run_scheduled_recurrent_functions()
164166
fence = true;
165167
}
166168

167-
recurrent_fn_t* prev = &rFirst;
169+
auto prev = &rFirst;
170+
// prevent scheduling of new functions during this run
171+
auto stop = rLast;
168172

173+
bool done;
169174
do
170175
{
176+
done = current == stop;
171177
const bool wakeupToken = current->wakeupToken && current->wakeupToken->load();
172178
const bool wakeup = current->wakeupTokenCmp != wakeupToken;
173179
if (wakeup) current->wakeupTokenCmp = wakeupToken;
@@ -180,11 +186,10 @@ void run_scheduled_recurrent_functions()
180186

181187
auto to_ditch = current;
182188

183-
// current function recursively scheduled something
184-
if (prev->mNext != current) prev = prev->mNext;
185-
186189
current = current->mNext;
187190
prev->mNext = current;
191+
// removing rLast
192+
if (!current) rLast = prev;
188193

189194
delete(to_ditch);
190195
}
@@ -201,7 +206,7 @@ void run_scheduled_recurrent_functions()
201206
esp_schedule();
202207
cont_yield(g_pcont);
203208
}
204-
} while (current);
209+
} while (current && !done);
205210

206211
fence = false;
207212
}

0 commit comments

Comments
 (0)