From 85ad694308290c13bb7cee2f442f67ba1ad8a809 Mon Sep 17 00:00:00 2001
From: Sasan Golchin <ahmad.golchin@mail.polimi.it>
Date: Tue, 27 Sep 2016 12:42:53 +0200
Subject: [PATCH] Priority Scheduler FIX: Preemption does not occure while idle
 thread is active

---
 .../scheduler/priority/priority_scheduler.cpp  | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/miosix/kernel/scheduler/priority/priority_scheduler.cpp b/miosix/kernel/scheduler/priority/priority_scheduler.cpp
index 1c239512..c146898c 100644
--- a/miosix/kernel/scheduler/priority/priority_scheduler.cpp
+++ b/miosix/kernel/scheduler/priority/priority_scheduler.cpp
@@ -201,13 +201,17 @@ void PriorityScheduler::IRQsetIdleThread(Thread *idleThread)
     idle=idleThread;
 }
 
-static void setNextPreemption(){
+static void setNextPreemption(bool curIsIdleThread){
     static long long preemptionPeriodTicks = tc->ns2tick(preemptionPeriodNs);
-    long long nextPeriodicPreemption = timer.IRQgetCurrentTick() + preemptionPeriodTicks;   
-    if (firstSleepItemTicks < nextPeriodicPreemption )
+    if (curIsIdleThread){
         timer.IRQsetNextInterrupt(firstSleepItemTicks);
-    else
-        timer.IRQsetNextInterrupt(nextPeriodicPreemption);
+    }else{
+        long long nextPeriodicPreemption = timer.IRQgetCurrentTick() + preemptionPeriodTicks;   
+        if (firstSleepItemTicks < nextPeriodicPreemption )
+            timer.IRQsetNextInterrupt(firstSleepItemTicks);
+        else
+            timer.IRQsetNextInterrupt(nextPeriodicPreemption);
+    }
 }
 
 unsigned int PriorityScheduler::IRQfindNextThread()
@@ -239,7 +243,7 @@ unsigned int PriorityScheduler::IRQfindNextThread()
                 //Rotate to next thread so that next time the list is walked
                 //a different thread, if available, will be chosen first
                 thread_list[i]=temp;
-                setNextPreemption();
+                setNextPreemption(false);
                 return preemptionPeriodNs;
             } else temp=temp->schedData.next;
             if(temp==thread_list[i]->schedData.next) break;
@@ -251,7 +255,7 @@ unsigned int PriorityScheduler::IRQfindNextThread()
     #ifdef WITH_PROCESSES
     MPUConfiguration::IRQdisable();
     #endif //WITH_PROCESSES
-    setNextPreemption();
+    setNextPreemption(true);
     return preemptionPeriodNs;
 }
 
-- 
GitLab