33
44
55Scheduler::Scheduler ()
6- : _head{}, _nextProc {}
6+ : _pLevels {}
77{
88 _lastID = 0 ;
99 // Create queue
@@ -35,7 +35,7 @@ Process *Scheduler::findProcById(uint8_t id)
3535{
3636 for (uint8_t i=0 ; i < NUM_PRIORITY_LEVELS; i++)
3737 {
38- for (Process *serv = _head [i]; serv != NULL ; serv = serv->getNext ())
38+ for (Process *serv = _pLevels [i]. head ; serv != NULL ; serv = serv->getNext ())
3939 {
4040 if (serv->getID () == id)
4141 return serv;
@@ -99,7 +99,7 @@ uint8_t Scheduler::countProcesses(int priority, bool enabledOnly)
9999 uint8_t count=0 ;
100100 for (uint8_t i = (priority == ALL_PRIORITY_LEVELS) ? 0 : (uint8_t )priority; i < NUM_PRIORITY_LEVELS; i++)
101101 {
102- for (Process *curr = _head [i]; curr != NULL ; curr = curr->getNext ())
102+ for (Process *curr = _pLevels [i]. head ; curr != NULL ; curr = curr->getNext ())
103103 {
104104 count += enabledOnly ? curr->isEnabled () : 1 ;
105105 }
@@ -120,7 +120,7 @@ int Scheduler::run()
120120 {
121121 processQueue ();
122122
123- _active = _nextProc [pLevel];
123+ _active = _pLevels [pLevel]. next ;
124124 if (!_active)
125125 continue ;
126126
@@ -166,17 +166,22 @@ int Scheduler::run()
166166
167167 // Determine what to do next ///
168168 if (!_active->hasNext ()) {
169- _nextProc[pLevel] = _head[pLevel]; // Set next to first
169+ #ifdef _PROCESS_REORDERING
170+ if (++_pLevels[pLevel].passes >= _PROCESS_REORDERING_AGGRESSIVENESS) {
171+ reOrderProcs ((ProcPriority)pLevel);
172+ ++_pLevels[pLevel].passes = 0 ;
173+ }
174+ #endif
175+ _pLevels[pLevel].next = _pLevels[pLevel].head ; // Set next to first
170176 } else {
171- _nextProc [pLevel] = _active->getNext (); // Set next and break
177+ _pLevels [pLevel]. next = _active->getNext (); // Set next and break
172178 _active = NULL ;
173179 break ;
174180 }
175181
182+ _active = NULL ;
176183 }
177-
178184 processQueue ();
179-
180185 return count;
181186}
182187
@@ -230,7 +235,7 @@ void Scheduler::procHalt()
230235{
231236 for (uint8_t i = 0 ; i < NUM_PRIORITY_LEVELS; i++)
232237 {
233- for (Process *curr = _head [i]; curr != NULL ; curr = curr->getNext ())
238+ for (Process *curr = _pLevels [i]. head ; curr != NULL ; curr = curr->getNext ())
234239 {
235240 procDestroy (*curr);
236241 }
@@ -310,7 +315,6 @@ void Scheduler::processQueue()
310315}
311316
312317#ifdef _PROCESS_STATISTICS
313-
314318bool Scheduler::updateStats ()
315319{
316320 QueableOperation op (QueableOperation::UPDATE_STATS);
@@ -331,7 +335,7 @@ void Scheduler::procUpdateStats()
331335
332336 for (uint8_t l = 0 ; l < NUM_PRIORITY_LEVELS; l++)
333337 {
334- for (i = 0 , p = _head [l]; p != NULL && i < count; p = p->getNext (), i++)
338+ for (i = 0 , p = _pLevels [l]. head ; p != NULL && i < count; p = p->getNext (), i++)
335339 {
336340 // to ensure no overflows
337341 sTime [i] = (p->getHistRunTime () + count/2 ) / count;
@@ -341,7 +345,7 @@ void Scheduler::procUpdateStats()
341345
342346 for (uint8_t l = 0 ; l < NUM_PRIORITY_LEVELS; l++)
343347 {
344- for (i = 0 , p = _head [l]; p != NULL && i < count; p = p->getNext (), i++)
348+ for (i = 0 , p = _pLevels [l]. head ; p != NULL && i < count; p = p->getNext (), i++)
345349 {
346350 // to ensure no overflows have to use double
347351 if (!totalTime) {
@@ -361,7 +365,7 @@ void Scheduler::handleHistOverFlow(uint8_t div)
361365{
362366 for (uint8_t i = 0 ; i < NUM_PRIORITY_LEVELS; i++)
363367 {
364- for (Process *p = _head [i]; p != NULL ; p = p->getNext ())
368+ for (Process *p = _pLevels [i]. head ; p != NULL ; p = p->getNext ())
365369 {
366370 p->divStats (div);
367371 }
@@ -400,11 +404,11 @@ bool Scheduler::appendNode(Process &node)
400404
401405 ProcPriority p = node.getPriority ();
402406
403- if (!_head [p]) {
404- _head [p] = &node;
405- _nextProc [p] = &node;
407+ if (!_pLevels [p]. head ) { // adding to head
408+ _pLevels [p]. head = &node;
409+ _pLevels [p]. next = &node;
406410 } else {
407- Process *next = _head [p];
411+ Process *next = _pLevels [p]. head ; // adding not to head
408412 for (; next->hasNext (); next = next->getNext ()); // run through list
409413 // Update pointers
410414 next->setNext (&node);
@@ -416,31 +420,105 @@ bool Scheduler::removeNode(Process &node)
416420{
417421 ProcPriority p = node.getPriority ();
418422
419- if (&node == _head [p]) { // node is head
420- _head [p] = node.getNext ();
423+ if (&node == _pLevels [p]. head ) { // node is head
424+ _pLevels [p]. head = node.getNext ();
421425 } else {
422426 // Find the previous node
423- Process *prev = _head[p];
424- for (; prev != NULL && prev->getNext () != &node; prev = prev->getNext ());
427+ Process *prev = findPrevNode (node);
425428
426- if (!prev) return false ; // previous node does not exist
429+ if (!prev)
430+ return false ; // previous node does not exist
427431
428432 prev->setNext (node.getNext ());
429433 }
430434
431- if (_nextProc [p] == &node)
432- _nextProc [p] = node.hasNext () ? node.getNext () : _head [p];
435+ if (_pLevels [p]. next == &node)
436+ _pLevels [p]. next = node.hasNext () ? node.getNext () : _pLevels [p]. head ;
433437
434438 return true ;
435439}
436440
437-
438441bool Scheduler::findNode (Process &node)
439442{
440- for (Process *p = _head [node.getPriority ()]; p != NULL ; p = p->getNext ())
443+ for (Process *p = _pLevels [node.getPriority ()]. head ; p != NULL ; p = p->getNext ())
441444 {
442445 if (p == &node)
443446 return true ;
444447 }
445448 return false ;
446449}
450+
451+ Process *Scheduler::findPrevNode (Process &node)
452+ {
453+ Process *prev = _pLevels[node.getPriority ()].head ;
454+ for (; prev != NULL && prev->getNext () != &node; prev = prev->getNext ());
455+ return prev;
456+ }
457+
458+ /*
459+ void Scheduler::reOrderProcs(ProcPriority level)
460+ {
461+ for(Process *p = _pLevels[level].head; p != NULL && p->hasNext(); p = p->getNext())
462+ {
463+ Process *next = p->getNext();
464+
465+ if (p->getAvgRunTime() > next->getAvgRunTime())
466+ {
467+ Serial.println("Swapping");
468+ if(!swapNode(*p, *next)) //this should never fail, but to be safe
469+ break;
470+
471+ p = next;
472+ }
473+ }
474+ }
475+
476+ bool Scheduler::swapNode(Process &n1, Process &n2)
477+ {
478+ if (&n1 == &n2 || n1.getPriority() != n2.getPriority())
479+ return false;
480+
481+
482+ Process *n1_prev = findPrevNode(n1);
483+ Process *n2_prev = findPrevNode(n2);
484+
485+ if (!n1_prev) { //n1 was head
486+ _pLevels[n1.getPriority()].head = &n2;
487+ } else { //n1 was not head
488+ n1_prev->setNext(&n2);
489+ }
490+
491+ if (!n2_prev) { //n2 was head
492+ _pLevels[n1.getPriority()].head = &n1;
493+ } else { //n2 was not head
494+ n2_prev->setNext(&n1);
495+ }
496+
497+ Process *tmp = n2.getNext();
498+ n2.setNext(n1.getNext());
499+ n1.setNext(tmp);
500+ return true;
501+ }
502+
503+ bool Scheduler::removeNodeAfter(Process &prev)
504+ {
505+ Process *toRemove = prev.getNext();
506+
507+ if (!toRemove)
508+ return false;
509+
510+ prev.setNext(toRemove->getNext());
511+
512+ return true;
513+ }
514+
515+ bool Scheduler::insertNodeAfter(Process &prev, Process &toAdd)
516+ {
517+ Process *next = prev.getNext();
518+
519+ prev.setNext(&toAdd);
520+ toAdd.setNext(&prev);
521+
522+ return true;
523+ }
524+ */
0 commit comments