From 8abd78be5804e998f8f1c71ffdb02a1b2abbac0e Mon Sep 17 00:00:00 2001 From: sasan-golchin <ahmad.golchin@mail.polimi.it> Date: Thu, 20 Oct 2016 16:34:29 +0200 Subject: [PATCH] Control scheduler revised to support multiburst - stage 1 --- miosix/kernel/kernel.cpp | 11 +- miosix/kernel/kernel.h | 1 + .../scheduler/control/control_scheduler.cpp | 209 +++++++++++++++--- .../scheduler/control/control_scheduler.h | 95 +------- .../control/control_scheduler_types.h | 49 +++- miosix/kernel/scheduler/edf/edf_scheduler.h | 2 +- .../scheduler/priority/priority_scheduler.cpp | 1 - .../scheduler/priority/priority_scheduler.h | 2 +- miosix/kernel/scheduler/scheduler.h | 4 +- 9 files changed, 236 insertions(+), 138 deletions(-) mode change 100644 => 100755 miosix/kernel/kernel.cpp mode change 100644 => 100755 miosix/kernel/kernel.h mode change 100644 => 100755 miosix/kernel/scheduler/control/control_scheduler.h mode change 100644 => 100755 miosix/kernel/scheduler/control/control_scheduler_types.h mode change 100644 => 100755 miosix/kernel/scheduler/edf/edf_scheduler.h mode change 100644 => 100755 miosix/kernel/scheduler/priority/priority_scheduler.h mode change 100644 => 100755 miosix/kernel/scheduler/scheduler.h diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp old mode 100644 new mode 100755 index 8b88bfc9..e93630ad --- a/miosix/kernel/kernel.cpp +++ b/miosix/kernel/kernel.cpp @@ -650,6 +650,7 @@ Thread *Thread::doCreate(void*(*startfunc)(void*) , unsigned int stacksize, reinterpret_cast<unsigned int*>(thread),argv); if((options & JOINABLE)==0) thread->flags.IRQsetDetached(); + thread->flags.t = thread; return thread; } @@ -838,31 +839,31 @@ Thread::~Thread() void Thread::ThreadFlags::IRQsetWait(bool waiting) { if(waiting) flags |= WAIT; else flags &= ~WAIT; - Scheduler::IRQwaitStatusHook(); + Scheduler::IRQwaitStatusHook(this->t); } void Thread::ThreadFlags::IRQsetJoinWait(bool waiting) { if(waiting) flags |= WAIT_JOIN; else flags &= ~WAIT_JOIN; - Scheduler::IRQwaitStatusHook(); + Scheduler::IRQwaitStatusHook(this->t); } void Thread::ThreadFlags::IRQsetCondWait(bool waiting) { if(waiting) flags |= WAIT_COND; else flags &= ~WAIT_COND; - Scheduler::IRQwaitStatusHook(); + Scheduler::IRQwaitStatusHook(this->t); } void Thread::ThreadFlags::IRQsetSleep(bool sleeping) { if(sleeping) flags |= SLEEP; else flags &= ~SLEEP; - Scheduler::IRQwaitStatusHook(); + Scheduler::IRQwaitStatusHook(this->t); } void Thread::ThreadFlags::IRQsetDeleted() { flags |= DELETED; - Scheduler::IRQwaitStatusHook(); + Scheduler::IRQwaitStatusHook(this->t); } } //namespace miosix diff --git a/miosix/kernel/kernel.h b/miosix/kernel/kernel.h old mode 100644 new mode 100755 index c19440be..d675a650 --- a/miosix/kernel/kernel.h +++ b/miosix/kernel/kernel.h @@ -861,6 +861,7 @@ private: */ bool isInUserspace() const { return flags & USERSPACE; } + Thread* t; private: ///\internal Thread is in the wait status. A call to wakeup will change ///this diff --git a/miosix/kernel/scheduler/control/control_scheduler.cpp b/miosix/kernel/scheduler/control/control_scheduler.cpp index b131273d..05eb8268 100644 --- a/miosix/kernel/scheduler/control/control_scheduler.cpp +++ b/miosix/kernel/scheduler/control/control_scheduler.cpp @@ -30,6 +30,7 @@ #include "kernel/process.h" #include <limits> #include "interfaces/cstimer.h" +#include "kernel/scheduler/scheduler.h" using namespace std; @@ -40,14 +41,45 @@ namespace miosix { //These are defined in kernel.cpp extern volatile Thread *cur; extern volatile int kernel_running; -static ContextSwitchTimer& timer = ContextSwitchTimer::instance(); extern IntrusiveList<SleepData> *sleepingList; +extern bool kernel_started; + +//Internal +static ContextSwitchTimer& timer = ContextSwitchTimer::instance(); static long long burstStart = 0; +static IntrusiveList<ThreadsListItem> activeThreads; +static IntrusiveList<ThreadsListItem>::iterator curInRound = activeThreads.end(); // // class ControlScheduler // +static inline void addThreadToActiveList(ThreadsListItem *atlEntry) +{ + + switch (atlEntry->t->getPriority().getRealtime()){ + case REALTIME_PRIORITY_IMMEDIATE: + activeThreads.insert(curInRound,atlEntry); + curInRound--;curInRound--; + break; + case REALTIME_PRIORITY_NEXT_BURST: + { + auto temp=curInRound; + activeThreads.insert(++temp,atlEntry); + break; + } + default: + activeThreads.push_back(atlEntry); + } +} + +static inline void remThreadfromActiveList(ThreadsListItem *atlEntry){ + if (curInRound==IntrusiveList<ThreadsListItem>::iterator(atlEntry)){ + curInRound++; + } + activeThreads.erase(IntrusiveList<ThreadsListItem>::iterator(atlEntry)); +} + bool ControlScheduler::PKaddThread(Thread *thread, ControlSchedulerPriority priority) { @@ -55,6 +87,7 @@ bool ControlScheduler::PKaddThread(Thread *thread, if(threadListSize>=64) return false; #endif //SCHED_CONTROL_FIXED_POINT thread->schedData.priority=priority; + thread->schedData.atlEntry.t = thread; { //Note: can't use FastInterruptDisableLock here since this code is //also called *before* the kernel is started. @@ -65,6 +98,15 @@ bool ControlScheduler::PKaddThread(Thread *thread, threadList=thread; threadListSize++; SP_Tr+=bNominal; //One thread more, increase round time + // Insert the thread in activeThreads list according to its real-time + // priority + if (thread->flags.isReady()){ + addThreadToActiveList(&thread->schedData.atlEntry); + thread->schedData.lastReadyStatus = true; + }else{ + thread->schedData.lastReadyStatus = false; + } + IRQrecalculateAlfa(); } return true; @@ -141,7 +183,7 @@ void ControlScheduler::IRQsetIdleThread(Thread *idleThread) //Initializing curInRound to end() so that the first time //IRQfindNextThread() is called the scheduling algorithm runs if(threadListSize!=1) errorHandler(UNEXPECTED); - curInRound=0; + curInRound=activeThreads.end(); } Thread *ControlScheduler::IRQgetIdleThread() @@ -195,8 +237,9 @@ unsigned int ControlScheduler::IRQfindNextThread() //Find next thread to run for(;;) { - if(curInRound!=0) curInRound=curInRound->schedData.next; - if(curInRound==0) //Note: do not replace with an else + //if(curInRound!=0) curInRound=curInRound->schedData.next; + if(curInRound!=activeThreads.end()) curInRound++; + if(curInRound==activeThreads.end()) //Note: do not replace with an else { //Check these two statements: //- If all threads are not ready, the scheduling algorithm must be @@ -204,30 +247,24 @@ unsigned int ControlScheduler::IRQfindNextThread() //- If the inner integral regulator of all ready threads saturated // then the integral regulator of the outer regulator must stop // increasing because the set point cannot be attained anyway. - bool allThreadNotReady=true; bool allReadyThreadsSaturated=true; - for(Thread *it=threadList;it!=0;it=it->schedData.next) + for (auto it=activeThreads.begin() ; it!=activeThreads.end() ; it++) { - if(it->flags.isReady()) - { - allThreadNotReady=false; - if(it->schedData.bo<bMax*multFactor) - { + if((*it)->t->schedData.bo<bMax*multFactor){ allReadyThreadsSaturated=false; //Found a counterexample for both statements, //no need to scan the list further. break; - } } } - if(allThreadNotReady) + if(activeThreads.empty()) { //No thread is ready, run the idle thread //This is very important: the idle thread can *remove* dead //threads from threadList, so it can invalidate iterators //to any element except theadList.end() - curInRound=0; + curInRound=activeThreads.end(); cur=idle; ctxsave=cur->ctxsave; #ifdef WITH_PROCESSES @@ -239,14 +276,15 @@ unsigned int ControlScheduler::IRQfindNextThread() } //End of round reached, run scheduling algorithm - curInRound=threadList; + //curInRound=threadList; + curInRound = activeThreads.front(); IRQrunRegulator(allReadyThreadsSaturated); } - if(curInRound->flags.isReady()) + if((*curInRound)->t->flags.isReady()) { //Found a READY thread, so run this one - cur=curInRound; + cur=(*curInRound)->t; #ifdef WITH_PROCESSES if(const_cast<Thread*>(cur)->flags.isInUserspace()==false) { @@ -262,78 +300,181 @@ unsigned int ControlScheduler::IRQfindNextThread() #endif //WITH_PROCESSES //miosix_private::AuxiliaryTimer::IRQsetValue( // curInRound->schedData.bo/multFactor); - IRQsetNextPreemption(curInRound->schedData.bo/multFactor); + IRQsetNextPreemption(cur->schedData.bo/multFactor); return 0; } else { //If we get here we have a non ready thread that cannot run, //so regardless of the burst calculated by the scheduler //we do not run it and set Tp to zero. - curInRound->schedData.Tp=0; + //curInRound->schedData.Tp=0; + return UINT_MAX; //This case should not happen, just for debug! } } } +void ControlScheduler::IRQwaitStatusHook(Thread* t) +{ + // Managing activeThreads list + if (t->flags.isReady() && !t->schedData.lastReadyStatus){ + // The thread has became active -> put it in the list + addThreadToActiveList(&t->schedData.atlEntry); + t->schedData.lastReadyStatus = true; + }else if (!t->flags.isReady() && t->schedData.lastReadyStatus){ + // The thread is no longer active -> remove it from the list + remThreadfromActiveList(&t->schedData.atlEntry); + t->schedData.lastReadyStatus = false; + } + #ifdef ENABLE_FEEDFORWARD + IRQrecalculateAlfa(); + #endif //ENABLE_FEEDFORWARD +} + void ControlScheduler::IRQrecalculateAlfa() { //Sum of all priorities of all threads //Note that since priority goes from 0 to PRIORITY_MAX-1 //but priorities we need go from 1 to PRIORITY_MAX we need to add one unsigned int sumPriority=0; - for(Thread *it=threadList;it!=0;it=it->schedData.next) + //for(Thread *it=threadList;it!=0;it=it->schedData.next) + for (auto it = activeThreads.begin() ; it != activeThreads.end() ; it++) { #ifdef ENABLE_FEEDFORWARD //Count only ready threads - if(it->flags.isReady()) - sumPriority+=it->schedData.priority.get()+1;//Add one + if((*it)->t->flags.isReady()) + sumPriority+=(*it)->t->schedData.priority.get()+1;//Add one #else //ENABLE_FEEDFORWARD //Count all threads - sumPriority+=it->schedData.priority.get()+1;//Add one + sumPriority+=(*it)->t->schedData.priority.get()+1;//Add one #endif //ENABLE_FEEDFORWARD } //This can happen when ENABLE_FEEDFORWARD is set and no thread is ready if(sumPriority==0) return; #ifndef SCHED_CONTROL_FIXED_POINT float base=1.0f/((float)sumPriority); - for(Thread *it=threadList;it!=0;it=it->schedData.next) + //for(Thread *it=threadList;it!=0;it=it->schedData.next) + for (auto it = activeThreads.begin() ; it != activeThreads.end() ; it++) { #ifdef ENABLE_FEEDFORWARD //Assign zero bursts to blocked threads - if(it->flags.isReady()) + if((*it)->t->flags.isReady()) { - it->schedData.alfa=base*((float)(it->schedData.priority.get()+1)); + (*it)->t->schedData.alfa=base*((float)((*it)->t->schedData.priority.get()+1)); } else { - it->schedData.alfa=0; + (*it)->t->schedData.alfa=0; } #else //ENABLE_FEEDFORWARD //Assign bursts irrespective of thread blocking status - it->schedData.alfa=base*((float)(it->schedData.priority.get()+1)); + (*it)->t->schedData.alfa=base*((float)((*it)->t->schedData.priority.get()+1)); #endif //ENABLE_FEEDFORWARD } #else //FIXED_POINT_MATH //Sum of all alfa is maximum value for an unsigned short unsigned int base=4096/sumPriority; - for(Thread *it=threadList;it!=0;it=it->schedData.next) + //for(Thread *it=threadList;it!=0;it=it->schedData.next) + for (auto it = activeThreads.begin() ; it != activeThreads.end() ; it++) { #ifdef ENABLE_FEEDFORWARD //Assign zero bursts to blocked threads - if(it->flags.isReady()) + if((*it)->t->flags.isReady()) { - it->schedData.alfa=base*(it->schedData.priority.get()+1); + (*it)->t->schedData.alfa=base*((*it)->t->schedData.priority.get()+1); } else { - it->schedData.alfa=0; + (*it)->t->schedData.alfa=0; } #else //ENABLE_FEEDFORWARD //Assign bursts irrespective of thread blocking status - it->schedData.alfa=base*(it->schedData.priority.get()+1); + (*it)->t->schedData.alfa=base*((*it)->t->schedData.priority.get()+1); #endif //ENABLE_FEEDFORWARD } #endif //FIXED_POINT_MATH reinitRegulator=true; } +void ControlScheduler::IRQrunRegulator(bool allReadyThreadsSaturated) +{ + using namespace std; + #ifdef SCHED_CONTROL_FIXED_POINT + //The fixed point scheduler may overflow if Tr is higher than this + Tr=min(Tr,524287); + #endif //FIXED_POINT_MATH + #ifdef ENABLE_REGULATOR_REINIT + if(reinitRegulator==false) + { + #endif //ENABLE_REGULATOR_REINIT + int eTr=SP_Tr-Tr; + #ifndef SCHED_CONTROL_FIXED_POINT + int bc=bco+static_cast<int>(krr*eTr-krr*zrr*eTro); + #else //FIXED_POINT_MATH + //Tr is clamped to 524287, so eTr uses at most 19bits. Considering + //the 31bits of a signed int, we have 12bits free. + const int fixedKrr=static_cast<int>(krr*2048); + const int fixedKrrZrr=static_cast<int>(krr*zrr*1024); + int bc=bco+(fixedKrr*eTr)/2048-(fixedKrrZrr*eTro)/1024; + #endif //FIXED_POINT_MATH + if(allReadyThreadsSaturated) + { + //If all inner regulators reached upper saturation, + //allow only a decrease in the burst correction. + if(bc<bco) bco=bc; + } else bco=bc; + + bco=min<int>(max(bco,-Tr),bMax*threadListSize); + #ifndef SCHED_CONTROL_FIXED_POINT + float nextRoundTime=static_cast<float>(Tr+bco); + #else //FIXED_POINT_MATH + unsigned int nextRoundTime=Tr+bco; //Bounded to 20bits + #endif //FIXED_POINT_MATH + eTro=eTr; + Tr=0;//Reset round time + for(Thread *it=threadList;it!=0;it=it->schedData.next) + { + //Recalculate per thread set point + #ifndef SCHED_CONTROL_FIXED_POINT + it->schedData.SP_Tp=static_cast<int>( + it->schedData.alfa*nextRoundTime); + #else //FIXED_POINT_MATH + //nextRoundTime is bounded to 20bits, alfa to 12bits, + //so the multiplication fits in 32bits + it->schedData.SP_Tp=(it->schedData.alfa*nextRoundTime)/4096; + #endif //FIXED_POINT_MATH + + //Run each thread internal regulator + int eTp=it->schedData.SP_Tp - it->schedData.Tp; + //note: since b and bo contain the real value multiplied by + //multFactor, this equals b=bo+eTp/multFactor. + int b=it->schedData.bo + eTp; + //saturation + it->schedData.bo=min(max(b,bMin*multFactor),bMax*multFactor); + } + #ifdef ENABLE_REGULATOR_REINIT + } else { + reinitRegulator=false; + Tr=0;//Reset round time + //Reset state of the external regulator + eTro=0; + bco=0; + + for(Thread *it=threadList;it!=0;it=it->schedData.next) + { + //Recalculate per thread set point + #ifndef SCHED_CONTROL_FIXED_POINT + it->schedData.SP_Tp=static_cast<int>(it->schedData.alfa*SP_Tr); + #else //FIXED_POINT_MATH + //SP_Tr is bounded to 20bits, alfa to 12bits, + //so the multiplication fits in 32bits + it->schedData.SP_Tp=(it->schedData.alfa*SP_Tr)/4096; + #endif //FIXED_POINT_MATH + + int b=it->schedData.SP_Tp*multFactor; + it->schedData.bo=min(max(b,bMin*multFactor),bMax*multFactor); + } + } + #endif //ENABLE_REGULATOR_REINIT +} + Thread *ControlScheduler::threadList=0; unsigned int ControlScheduler::threadListSize=0; -Thread *ControlScheduler::curInRound=0; +//Thread *ControlScheduler::curInRound=0; Thread *ControlScheduler::idle=0; int ControlScheduler::SP_Tr=0; int ControlScheduler::Tr=bNominal; diff --git a/miosix/kernel/scheduler/control/control_scheduler.h b/miosix/kernel/scheduler/control/control_scheduler.h old mode 100644 new mode 100755 index 851ccd87..79221bd6 --- a/miosix/kernel/scheduler/control/control_scheduler.h +++ b/miosix/kernel/scheduler/control/control_scheduler.h @@ -130,12 +130,7 @@ public: * its running status. For example when a thread become sleeping, waiting, * deleted or if it exits the sleeping or waiting status */ - static void IRQwaitStatusHook() - { - #ifdef ENABLE_FEEDFORWARD - IRQrecalculateAlfa(); - #endif //ENABLE_FEEDFORWARD - } + static void IRQwaitStatusHook(Thread* t); /** * \internal @@ -153,7 +148,7 @@ public: static unsigned int IRQfindNextThread(); private: - + /** * \internal * When priorities are modified, this function recalculates alfa for each @@ -165,94 +160,14 @@ private: * Called by IRQfindNextThread(), this function is where the control based * scheduling algorithm is run. It is called once per round. */ - static void IRQrunRegulator(bool allReadyThreadsSaturated) - { - using namespace std; - #ifdef SCHED_CONTROL_FIXED_POINT - //The fixed point scheduler may overflow if Tr is higher than this - Tr=min(Tr,524287); - #endif //FIXED_POINT_MATH - #ifdef ENABLE_REGULATOR_REINIT - if(reinitRegulator==false) - { - #endif //ENABLE_REGULATOR_REINIT - int eTr=SP_Tr-Tr; - #ifndef SCHED_CONTROL_FIXED_POINT - int bc=bco+static_cast<int>(krr*eTr-krr*zrr*eTro); - #else //FIXED_POINT_MATH - //Tr is clamped to 524287, so eTr uses at most 19bits. Considering - //the 31bits of a signed int, we have 12bits free. - const int fixedKrr=static_cast<int>(krr*2048); - const int fixedKrrZrr=static_cast<int>(krr*zrr*1024); - int bc=bco+(fixedKrr*eTr)/2048-(fixedKrrZrr*eTro)/1024; - #endif //FIXED_POINT_MATH - if(allReadyThreadsSaturated) - { - //If all inner regulators reached upper saturation, - //allow only a decrease in the burst correction. - if(bc<bco) bco=bc; - } else bco=bc; - - bco=min<int>(max(bco,-Tr),bMax*threadListSize); - #ifndef SCHED_CONTROL_FIXED_POINT - float nextRoundTime=static_cast<float>(Tr+bco); - #else //FIXED_POINT_MATH - unsigned int nextRoundTime=Tr+bco; //Bounded to 20bits - #endif //FIXED_POINT_MATH - eTro=eTr; - Tr=0;//Reset round time - for(Thread *it=threadList;it!=0;it=it->schedData.next) - { - //Recalculate per thread set point - #ifndef SCHED_CONTROL_FIXED_POINT - it->schedData.SP_Tp=static_cast<int>( - it->schedData.alfa*nextRoundTime); - #else //FIXED_POINT_MATH - //nextRoundTime is bounded to 20bits, alfa to 12bits, - //so the multiplication fits in 32bits - it->schedData.SP_Tp=(it->schedData.alfa*nextRoundTime)/4096; - #endif //FIXED_POINT_MATH - - //Run each thread internal regulator - int eTp=it->schedData.SP_Tp - it->schedData.Tp; - //note: since b and bo contain the real value multiplied by - //multFactor, this equals b=bo+eTp/multFactor. - int b=it->schedData.bo + eTp; - //saturation - it->schedData.bo=min(max(b,bMin*multFactor),bMax*multFactor); - } - #ifdef ENABLE_REGULATOR_REINIT - } else { - reinitRegulator=false; - Tr=0;//Reset round time - //Reset state of the external regulator - eTro=0; - bco=0; - - for(Thread *it=threadList;it!=0;it=it->schedData.next) - { - //Recalculate per thread set point - #ifndef SCHED_CONTROL_FIXED_POINT - it->schedData.SP_Tp=static_cast<int>(it->schedData.alfa*SP_Tr); - #else //FIXED_POINT_MATH - //SP_Tr is bounded to 20bits, alfa to 12bits, - //so the multiplication fits in 32bits - it->schedData.SP_Tp=(it->schedData.alfa*SP_Tr)/4096; - #endif //FIXED_POINT_MATH - - int b=it->schedData.SP_Tp*multFactor; - it->schedData.bo=min(max(b,bMin*multFactor),bMax*multFactor); - } - } - #endif //ENABLE_REGULATOR_REINIT - } + static void IRQrunRegulator(bool allReadyThreadsSaturated); ///\internal Threads (except idle thread) are stored here static Thread *threadList; static unsigned int threadListSize; - ///\internal current thread in the round - static Thread *curInRound; + ///\internal the entry of current thread in the round in the activeThreads list + //static IntrusiveList<ThreadsListItem>::iterator curInRound; ///\internal idle thread static Thread *idle; diff --git a/miosix/kernel/scheduler/control/control_scheduler_types.h b/miosix/kernel/scheduler/control/control_scheduler_types.h old mode 100644 new mode 100755 index c21a34dd..c1cc1284 --- a/miosix/kernel/scheduler/control/control_scheduler_types.h +++ b/miosix/kernel/scheduler/control/control_scheduler_types.h @@ -27,6 +27,7 @@ #include "config/miosix_settings.h" #include "parameters.h" +#include "kernel/intrusive.h" #ifndef CONTROL_SCHEDULER_TYPES_H #define CONTROL_SCHEDULER_TYPES_H @@ -37,6 +38,31 @@ namespace miosix { class Thread; //Forward declaration +/** + * Real-time priority definitions + * Applied to realtime field of ControlSchedulerPriority class. + * + * When a thread wakes up (due to a prior Thread::sleep or waiting + * for a hardware irq or etc.), the actual time the thread will have + * its burst remainder will depend on the real-time priority set for it. + */ +/** + * REALTIME_PRIORITY_IMMEDIATE: The processor control is transfered to the thread + * right in the time it wakes up. + */ +#define REALTIME_PRIORITY_IMMEDIATE 1 +/** + * REALTIME_PRIORITY_NEXT_BURST: The processor control is transfered to the thread + * right after the current running thread has consumed its burst time. + */ +#define REALTIME_PRIORITY_NEXT_BURST 2 +/** + * REALTIME_PRIORITY_NEXT_ROUND: The processor control is transfered to the thread + * in the next round and the thread is delayed until all remaining active threads + * are run. + */ +#define REALTIME_PRIORITY_NEXT_ROUND 3 + /** * This class models the concept of priority for the control based scheduler. * In this scheduler the priority is simply a short int with values ranging @@ -52,8 +78,11 @@ public: * Constructor. Not explicit for backward compatibility. * \param priority the desired priority value. */ - ControlSchedulerPriority(short int priority): priority(priority) {} - + ControlSchedulerPriority(short int priority): priority(priority), + realtime(REALTIME_PRIORITY_NEXT_ROUND) {} + + ControlSchedulerPriority(short int priority, short int realtime): + priority(priority),realtime(realtime){} /** * Default constructor. */ @@ -63,6 +92,8 @@ public: * \return the priority value */ short int get() const { return priority; } + + short int getRealtime() const {return realtime; } /** * \return true if this objects represents a valid priority. @@ -71,16 +102,18 @@ public: */ bool validate() const { - return this->priority>=0 && this->priority<PRIORITY_MAX; + return this->priority>=0 && this->priority<PRIORITY_MAX && + this->realtime >=1 && this->realtime<=3; } private: short int priority;///< The priority value + short int realtime;///< The realtime priority value }; inline bool operator <(ControlSchedulerPriority a, ControlSchedulerPriority b) { - return a.get() < b.get(); + return a.getRealtime() < b.getRealtime(); } inline bool operator <=(ControlSchedulerPriority a, ControlSchedulerPriority b) @@ -108,6 +141,12 @@ inline bool operator !=(ControlSchedulerPriority a, ControlSchedulerPriority b) return a.get() != b.get(); } +struct ThreadsListItem : public IntrusiveListItem +{ + ThreadsListItem(): t(0) {} + Thread *t; +}; + /** * \internal * An instance of this class is embedded in every Thread class. It contains all @@ -131,6 +170,8 @@ public: int SP_Tp;//Processing time set point int Tp;//Real processing time Thread *next;//Next thread in list + ThreadsListItem atlEntry; //Entry in activeThreads list + bool lastReadyStatus; }; } //namespace miosix diff --git a/miosix/kernel/scheduler/edf/edf_scheduler.h b/miosix/kernel/scheduler/edf/edf_scheduler.h old mode 100644 new mode 100755 index e4921bcb..bdabd031 --- a/miosix/kernel/scheduler/edf/edf_scheduler.h +++ b/miosix/kernel/scheduler/edf/edf_scheduler.h @@ -120,7 +120,7 @@ public: * its running status. For example when a thread become sleeping, waiting, * deleted or if it exits the sleeping or waiting status */ - static void IRQwaitStatusHook() {} + static void IRQwaitStatusHook(Thread *t) {} /** * This function is used to develop interrupt driven peripheral drivers.<br> diff --git a/miosix/kernel/scheduler/priority/priority_scheduler.cpp b/miosix/kernel/scheduler/priority/priority_scheduler.cpp index e5aed7b5..a07e837c 100644 --- a/miosix/kernel/scheduler/priority/priority_scheduler.cpp +++ b/miosix/kernel/scheduler/priority/priority_scheduler.cpp @@ -29,7 +29,6 @@ #include "kernel/error.h" #include "kernel/process.h" #include "interfaces/cstimer.h" -#include "kernel/timeconversion.h" #include <limits> #ifdef SCHED_TYPE_PRIORITY diff --git a/miosix/kernel/scheduler/priority/priority_scheduler.h b/miosix/kernel/scheduler/priority/priority_scheduler.h old mode 100644 new mode 100755 index d8e5539e..24b2a3cf --- a/miosix/kernel/scheduler/priority/priority_scheduler.h +++ b/miosix/kernel/scheduler/priority/priority_scheduler.h @@ -122,7 +122,7 @@ public: * its running status. For example when a thread become sleeping, waiting, * deleted or if it exits the sleeping or waiting status */ - static void IRQwaitStatusHook() {} + static void IRQwaitStatusHook(Thread* t) {} /** * \internal diff --git a/miosix/kernel/scheduler/scheduler.h b/miosix/kernel/scheduler/scheduler.h old mode 100644 new mode 100755 index f1fbb8ed..047bc49f --- a/miosix/kernel/scheduler/scheduler.h +++ b/miosix/kernel/scheduler/scheduler.h @@ -147,9 +147,9 @@ public: * its running status. For example when a thread become sleeping, waiting, * deleted or if it exits the sleeping or waiting status */ - static void IRQwaitStatusHook() + static void IRQwaitStatusHook(Thread *t) { - T::IRQwaitStatusHook(); + T::IRQwaitStatusHook(t); } /** -- GitLab