diff --git a/miosix/kernel/scheduler/edf/edf_scheduler.cpp b/miosix/kernel/scheduler/edf/edf_scheduler.cpp index 386708480544b08aa16913da3b5ab6f05451629d..cc7745ffa603eb34faaaedb8464513b3148b1c2f 100644 --- a/miosix/kernel/scheduler/edf/edf_scheduler.cpp +++ b/miosix/kernel/scheduler/edf/edf_scheduler.cpp @@ -28,6 +28,8 @@ #include "edf_scheduler.h" #include "kernel/error.h" #include "kernel/process.h" +#include "interfaces/cstimer.h" +#include "kernel/scheduler/timer_interrupt.h" #include <algorithm> using namespace std; @@ -39,7 +41,11 @@ namespace miosix { //These are defined in kernel.cpp extern volatile Thread *cur; extern volatile int kernel_running; +extern IntrusiveList<SleepData> *sleepingList; +//Static members +static ContextSwitchTimer& timer = ContextSwitchTimer::instance(); +static long long nextPreemption = numeric_limits<long long>::max(); // // class EDFScheduler // @@ -105,9 +111,24 @@ void EDFScheduler::IRQsetIdleThread(Thread *idleThread) add(idleThread); } -void EDFScheduler::IRQfindNextThread() +long long EDFScheduler::IRQgetNextPreemption() { - if(kernel_running!=0) return;//If kernel is paused, do nothing + return nextPreemption; +} + +static void IRQsetNextPreemption(){ + if (sleepingList->empty()) + { + nextPreemption = numeric_limits<long long>::max(); + }else{ + nextPreemption = sleepingList->front()->wakeup_time; + } + timer.IRQsetNextInterrupt(nextPreemption); +} + +unsigned int EDFScheduler::IRQfindNextThread() +{ + if(kernel_running!=0) return 0;//If kernel is paused, do nothing Thread *walk=head; for(;;) @@ -129,7 +150,8 @@ void EDFScheduler::IRQfindNextThread() #else //WITH_PROCESSES ctxsave=cur->ctxsave; #endif //WITH_PROCESSES - return; + IRQsetNextPreemption(); + return 1; } walk=walk->schedData.next; } diff --git a/miosix/kernel/scheduler/edf/edf_scheduler.h b/miosix/kernel/scheduler/edf/edf_scheduler.h index bdabd031f52c02f1a9fbbaa84a20f5c452550d56..8432ebde7d2b971112c71bf33bd4561fdccf1410 100755 --- a/miosix/kernel/scheduler/edf/edf_scheduler.h +++ b/miosix/kernel/scheduler/edf/edf_scheduler.h @@ -133,9 +133,13 @@ public: * If the kernel is paused does nothing. * It's behaviour is to modify the global variable miosix::cur which always * points to the currently running thread. + * + * \return 1 if any active threads found and 0 otherwise */ - static void IRQfindNextThread(); + static unsigned int IRQfindNextThread(); + static long long IRQgetNextPreemption(); + private: /** diff --git a/miosix/kernel/scheduler/edf/edf_scheduler_types.h b/miosix/kernel/scheduler/edf/edf_scheduler_types.h index a2e4fc3aec241f02bc15eba3c7ec0ebb0bd08636..a20bbd463317a1c7dcd45a79d271faea2ce29521 100644 --- a/miosix/kernel/scheduler/edf/edf_scheduler_types.h +++ b/miosix/kernel/scheduler/edf/edf_scheduler_types.h @@ -76,6 +76,18 @@ public: return this->deadline>=0 && this->deadline!=std::numeric_limits<long long>::max()-1; } + + /** + * This function acts like a less-than operator but should be only used in + * synchronization module for priority inheritance. The concept of priority + * for preemption is not exactly the same for priority inheritance, hence, + * this operation is a branch out of preemption priority for inheritance + * purpose. + * @return + */ + inline bool mutexLessOp(EDFSchedulerPriority b){ + return deadline > deadline; + } private: long long deadline;///< The deadline time diff --git a/miosix/kernel/scheduler/timer_interrupt.h b/miosix/kernel/scheduler/timer_interrupt.h index 9615ca61b1c6e7755a96062f4456c0a7fa13a777..5c3221c99cba57a3668380df838bddaa02f3e27b 100644 --- a/miosix/kernel/scheduler/timer_interrupt.h +++ b/miosix/kernel/scheduler/timer_interrupt.h @@ -52,19 +52,9 @@ inline void IRQtimerInterrupt(long long currentTick) if (currentTick >= Scheduler::IRQgetNextPreemption() || hptw ){ //End of the burst || a higher priority thread has woken up Scheduler::IRQfindNextThread();//If the kernel is running, preempt + if(kernel_running!=0) tick_skew=true; } - if(kernel_running!=0) tick_skew=true; - - #ifndef SCHED_TYPE_PRIORITY - //TODO: the old tick scheduler called this function periodically, - //so the EDF scheduler would have to be called only if a thread was woken. - //Now we can have no periodic preemption, and so if we are called (and EDF - //is selected), at least one thread has woken up, so there's no need for woken - //Modify the code below accordingly - //#error "FIXME" - #endif - // miosix_private::IRQstackOverflowCheck(); // bool woken=IRQwakeThreads();//Increment tick and wake threads,if any // (void)woken; //Avoid unused variable warning.