@@ -133,86 +133,109 @@ uint8_t Scheduler::countProcesses(int priority, bool enabledOnly)
133133 return count;
134134}
135135
136+
136137int Scheduler::run ()
137138{
138139 // Already running in another call frame
139140 if (_active) return 0 ;
140141
141142 uint8_t count = 0 ;
143+ uint32_t start = getCurrTS ();
142144 for (uint8_t pLevel=0 ; pLevel < NUM_PRIORITY_LEVELS; pLevel++)
143145 {
144146 processQueue ();
145147
146- _active = _pLevels[pLevel].next ;
147- if (!_active)
148+ // Resume looking where we left off in the list
149+ Process *torun = getRunnable (start, _pLevels[pLevel].next , NULL );
150+
151+ if (!torun && _pLevels[pLevel].next != _pLevels[pLevel].head )
152+ torun = getRunnable (start, _pLevels[pLevel].head , _pLevels[pLevel].next );
153+
154+ // No ready process found at this priority level
155+ if (!torun)
148156 continue ;
149157
150- // ///////// Run the correct process /////////
151- uint32_t start = getCurrTS ();
158+ _pLevels[pLevel].next = torun->hasNext () ? torun->getNext () : _pLevels[pLevel].head ;
152159
153- if (_active->needsServicing (start))
154- {
155- bool force = _active->forceSet (); // Store whether it was a forced iteraiton
156- _active->willService (start);
160+ // ///////// Run the correct process /////////
161+ _active = torun;
162+ start = getCurrTS (); // update
163+ bool force = _active->forceSet (); // Store whether it was a forced iteraiton
164+ _active->willService (start);
157165
158166#ifdef _PROCESS_EXCEPTION_HANDLING
159- int ret = setjmp (_env);
167+ int ret = setjmp (_env);
160168
161- #ifdef _PROCESS_TIMEOUT_INTERRUPTS
162- ENABLE_SCHEDULER_ISR ();
163- #endif
164- if (!ret) {
165- _active->service ();
166- } else {
167- jmpHandler (ret);
168- }
169- #else
169+ // Enable the interrupts
170+ #ifdef _PROCESS_TIMEOUT_INTERRUPTS
171+ ENABLE_SCHEDULER_ISR ();
172+ #endif
173+
174+ if (!ret) {
170175 _active->service ();
176+ } else {
177+ jmpHandler (ret);
178+ }
179+ #else
180+ _active->service ();
171181#endif
172182
183+ // Disable the interrupts after the process returned
173184#ifdef _PROCESS_TIMEOUT_INTERRUPTS
174185 DISABLE_SCHEDULER_ISR ();
175186#endif
187+ // ////////////////////END PROCESS SERVICING//////////////////////
176188
177189#ifdef _PROCESS_STATISTICS
178- uint32_t runTime = getCurrTS () - start;
179- // Make sure no overflow happens
180- if (_active->statsWillOverflow (1 , runTime))
181- handleHistOverFlow (HISTORY_DIV_FACTOR);
190+ uint32_t runTime = getCurrTS () - start;
191+ // Make sure no overflow happens
192+ if (_active->statsWillOverflow (1 , runTime))
193+ handleHistOverFlow (HISTORY_DIV_FACTOR);
182194
183- _active->setHistIterations (_active->getHistIterations ()+1 );
184- _active->setHistRuntime (_active->getHistRunTime ()+runTime);
195+ _active->setHistIterations (_active->getHistIterations ()+1 );
196+ _active->setHistRuntime (_active->getHistRunTime ()+runTime);
185197
186198#endif
187- // Is it time to disable?
188- if (_active->wasServiced (force)) {
189- disable (*_active);
190- }
191-
192- count++; // incr counter
199+ // Is it time to disable?
200+ if (_active->wasServiced (force)) {
201+ disable (*_active);
193202 }
194- // ////////////////////END PROCESS SERVICING//////////////////////
203+ _active = NULL ; // done!
204+
205+ count++; // incr counter
206+ processQueue ();
195207 delay (0 ); // For esp8266
208+ break ; // We found the process and serviced it, so were done
209+ }
210+ delay (0 ); // For esp8266
211+
212+ return count;
213+ }
214+
215+
216+ // end is exclusive, end=NULL means go to entire end of list
217+ Process *Scheduler::getRunnable (uint32_t start, Process *begin, Process *end)
218+ {
219+ if (!start)
220+ return NULL ;
221+
222+ Process *torun = NULL ;
223+ Process *tmp = begin;
196224
197- // Determine what to do next ///
198- if (!_active->hasNext ()) {
199- #ifdef _PROCESS_REORDERING
200- if (++_pLevels[pLevel].passes >= _PROCESS_REORDERING_AGGRESSIVENESS) {
201- reOrderProcs ((ProcPriority)pLevel);
202- ++_pLevels[pLevel].passes = 0 ;
225+ // Search for the best process
226+ while (tmp != end) {
227+ if (tmp->needsServicing (start)) {
228+ if (torun) { // Compare which one needs to run more
229+ torun = Process::runWhich (torun, tmp);
230+ } else { // torun is NULL so this is the best one to run
231+ torun = tmp;
203232 }
204- #endif
205- _pLevels[pLevel].next = _pLevels[pLevel].head ; // Set next to first
206- } else {
207- _pLevels[pLevel].next = _active->getNext (); // Set next and break
208- _active = NULL ;
209- break ;
210233 }
211234
212- _active = NULL ;
235+ tmp = tmp-> getNext () ;
213236 }
214- processQueue ();
215- return count ;
237+
238+ return torun ;
216239}
217240
218241
@@ -434,9 +457,15 @@ void Scheduler::handleHistOverFlow(uint8_t div)
434457 longjmp (_env, e);
435458 }
436459
437- void Scheduler::handleException (Process & process, int e)
460+ void Scheduler::handleException (Process * process, int e)
438461 {
439- process.restart ();
462+ // Exception came from process
463+ if (process) {
464+ process.restart ();
465+ } else {
466+ // Exception came from scheduler
467+
468+ }
440469 }
441470
442471
@@ -457,7 +486,7 @@ void Scheduler::handleHistOverFlow(uint8_t div)
457486
458487 default :
459488 if (!_active->handleException (e))
460- handleException (* _active, e);
489+ handleException (_active, e);
461490 break ;
462491
463492 }
0 commit comments