[haiku-commits] BRANCH pdziepak-github.scheduler [c4292ac] src/system/kernel/scheduler headers/private/kernel

  • From: pdziepak-github.scheduler <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 31 Dec 2013 05:00:34 +0100 (CET)

added 5 changesets to branch 'refs/remotes/pdziepak-github/scheduler'
old head: 69743c756ff14c5f2cc53d970c35ad7eb2a3c170
new head: c4292aceb9febae7f5880a1903f405abadfb95cd
overview: https://github.com/pdziepak/Haiku/compare/69743c7...c4292ac

----------------------------------------------------------------------------

d9e3792: scheduler: Protect per CPU run queue with its own lock

fdbfb4d: scheduler: Fix order of the includes
  
  Thanks Jérôme!

e5bd2f9: scheduler: Inherit penalty and core from creator thread

affaf22: kernel: Do not attempt to interrupt a thread that is not waiting

c4292ac: scheduler: Thread can not stay on CPU if it has been disabled

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

8 files changed, 118 insertions(+), 44 deletions(-)
headers/private/kernel/thread.h                  | 10 ++--
src/system/kernel/scheduler/low_latency.cpp      |  3 +-
src/system/kernel/scheduler/power_saving.cpp     |  2 +
src/system/kernel/scheduler/scheduler.cpp        | 10 ++--
src/system/kernel/scheduler/scheduler_cpu.cpp    | 22 ++++----
src/system/kernel/scheduler/scheduler_cpu.h      | 38 +++++++++++++-
src/system/kernel/scheduler/scheduler_thread.cpp | 24 +++++++--
src/system/kernel/scheduler/scheduler_thread.h   | 53 +++++++++++++-------

############################################################################

Commit:      d9e3792e0793f31ff2b8d82c3f5f33028584c3f0
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Mon Dec 30 19:03:36 2013 UTC

scheduler: Protect per CPU run queue with its own lock

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index f8d8f80..fc941b3 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -517,7 +517,7 @@ reschedule(int32 nextState)
        ThreadData* nextThreadData;
        if (gCPU[thisCPU].disabled) {
                if (!thread_is_idle_thread(oldThread)) {
-                       CoreRunQueueLocker _(core);
+                       CPURunQueueLocker _(cpu);
 
                        nextThreadData = cpu->PeekIdleThread();
                        cpu->Remove(nextThreadData);
diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp 
b/src/system/kernel/scheduler/scheduler_cpu.cpp
index f1a5b5e..08987fd 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.cpp
+++ b/src/system/kernel/scheduler/scheduler_cpu.cpp
@@ -56,6 +56,7 @@ CPUEntry::CPUEntry()
        fMeasureTime(0)
 {
        B_INITIALIZE_RW_SPINLOCK(&fSchedulerModeLock);
+       B_INITIALIZE_SPINLOCK(&fQueueLock);
 }
 
 
@@ -185,25 +186,26 @@ CPUEntry::ChooseNextThread(ThreadData* oldThread, bool 
putAtBack)
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       CoreRunQueueLocker _(fCore);
-
-       ThreadData* sharedThread = fCore->PeekThread();
-       ThreadData* pinnedThread = fRunQueue.PeekMaximum();
+       int32 oldPriority = -1;
+       if (oldThread != NULL)
+               oldPriority = oldThread->GetEffectivePriority();
 
-       ASSERT(sharedThread != NULL || pinnedThread != NULL || oldThread != 
NULL);
+       CPURunQueueLocker cpuLocker(this);
 
+       ThreadData* pinnedThread = fRunQueue.PeekMaximum();
        int32 pinnedPriority = -1;
        if (pinnedThread != NULL)
                pinnedPriority = pinnedThread->GetEffectivePriority();
 
+       CoreRunQueueLocker coreLocker(fCore);
+
+       ThreadData* sharedThread = fCore->PeekThread();
+       ASSERT(sharedThread != NULL || pinnedThread != NULL || oldThread != 
NULL);
+
        int32 sharedPriority = -1;
        if (sharedThread != NULL)
                sharedPriority = sharedThread->GetEffectivePriority();
 
-       int32 oldPriority = -1;
-       if (oldThread != NULL)
-               oldPriority = oldThread->GetEffectivePriority();
-
        int32 rest = std::max(pinnedPriority, sharedPriority);
        if (oldPriority > rest || (!putAtBack && oldPriority == rest))
                return oldThread;
@@ -213,6 +215,8 @@ CPUEntry::ChooseNextThread(ThreadData* oldThread, bool 
putAtBack)
                return sharedThread;
        }
 
+       coreLocker.Unlock();
+
        Remove(pinnedThread);
        return pinnedThread;
 }
diff --git a/src/system/kernel/scheduler/scheduler_cpu.h 
b/src/system/kernel/scheduler/scheduler_cpu.h
index 92de5d1..bd15264 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.h
+++ b/src/system/kernel/scheduler/scheduler_cpu.h
@@ -60,6 +60,9 @@ public:
        inline                          void                    LockScheduler();
        inline                          void                    
UnlockScheduler();
 
+       inline                          void                    LockRunQueue();
+       inline                          void                    
UnlockRunQueue();
+
                                                void                    
PushFront(ThreadData* thread,
                                                                                
        int32 priority);
                                                void                    
PushBack(ThreadData* thread,
@@ -91,6 +94,7 @@ private:
                                                rw_spinlock     
fSchedulerModeLock;
 
                                                ThreadRunQueue  fRunQueue;
+                                               spinlock                
fQueueLock;
 
                                                int32                   fLoad;
 
@@ -108,6 +112,22 @@ public:
                                                void                    Dump();
 };
 
+class CPURunQueueLocking {
+public:
+       inline bool Lock(CPUEntry* cpu)
+       {
+               cpu->LockRunQueue();
+               return true;
+       }
+
+       inline void Unlock(CPUEntry* cpu)
+       {
+               cpu->UnlockRunQueue();
+       }
+};
+
+typedef AutoLocker<CPUEntry, CPURunQueueLocking> CPURunQueueLocker;
+
 class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>,
        public DoublyLinkedListLinkImpl<CoreEntry> {
 public:
@@ -309,6 +329,22 @@ CPUEntry::UnlockScheduler()
 }
 
 
+inline void
+CPUEntry::LockRunQueue()
+{
+       SCHEDULER_ENTER_FUNCTION();
+       acquire_spinlock(&fQueueLock);
+}
+
+
+inline void
+CPUEntry::UnlockRunQueue()
+{
+       SCHEDULER_ENTER_FUNCTION();
+       release_spinlock(&fQueueLock);
+}
+
+
 /* static */ inline CPUEntry*
 CPUEntry::GetCPU(int32 cpu)
 {
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index 7bea75b..d37d8bf 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -234,16 +234,22 @@ ThreadData::PutBack()
 
        int32 priority = GetEffectivePriority();
 
-       CoreRunQueueLocker _(fCore);
-       ASSERT(!fEnqueued);
-       fEnqueued = true;
        if (fThread->pinned_to_cpu > 0) {
                ASSERT(fThread->cpu != NULL);
-
                CPUEntry* cpu = CPUEntry::GetCPU(fThread->cpu->cpu_num);
+
+               CPURunQueueLocker _(cpu);
+               ASSERT(!fEnqueued);
+               fEnqueued = true;
+
                cpu->PushFront(this, priority);
-       } else
+       } else {
+               CoreRunQueueLocker _(fCore);
+               ASSERT(!fEnqueued);
+               fEnqueued = true;
+
                fCore->PushFront(this, priority);
+       }
 }
 
 
@@ -258,16 +264,22 @@ ThreadData::Enqueue()
 
        int32 priority = GetEffectivePriority();
 
-       CoreRunQueueLocker _(fCore);
-       ASSERT(!fEnqueued);
-       fEnqueued = true;
        if (fThread->pinned_to_cpu > 0) {
                ASSERT(fThread->previous_cpu != NULL);
-
                CPUEntry* cpu = 
CPUEntry::GetCPU(fThread->previous_cpu->cpu_num);
+
+               CPURunQueueLocker _(cpu);
+               ASSERT(!fEnqueued);
+               fEnqueued = true;
+
                cpu->PushBack(this, priority);
-       } else
+       } else {
+               CoreRunQueueLocker _(fCore);
+               ASSERT(!fEnqueued);
+               fEnqueued = true;
+
                fCore->PushBack(this, priority);
+       }
 }
 
 
@@ -276,20 +288,23 @@ ThreadData::Dequeue()
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       CoreRunQueueLocker _(fCore);
-       if (!fEnqueued)
-               return false;
-
        if (fThread->pinned_to_cpu > 0) {
                ASSERT(fThread->previous_cpu != NULL);
-
                CPUEntry* cpu = 
CPUEntry::GetCPU(fThread->previous_cpu->cpu_num);
+
+               CPURunQueueLocker _(cpu);
+               if (!fEnqueued)
+                       return false;
                cpu->Remove(this);
-       } else {
-               ASSERT(fWentSleepCount < 1);
-               fCore->Remove(this);
+               ASSERT(!fEnqueued);
+               return true;
        }
 
+       CoreRunQueueLocker _(fCore);
+       if (!fEnqueued)
+               return false;
+       ASSERT(fWentSleepCount < 1);
+       fCore->Remove(this);
        ASSERT(!fEnqueued);
        return true;
 }

############################################################################

Commit:      fdbfb4dd82902b5702a0435487ef2be2d3676404
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Mon Dec 30 19:09:24 2013 UTC

scheduler: Fix order of the includes

Thanks Jérôme!

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_cpu.h 
b/src/system/kernel/scheduler/scheduler_cpu.h
index bd15264..c76ccf1 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.h
+++ b/src/system/kernel/scheduler/scheduler_cpu.h
@@ -10,8 +10,8 @@
 
 #include <thread.h>
 #include <util/AutoLock.h>
-#include <util/MinMaxHeap.h>
 #include <util/Heap.h>
+#include <util/MinMaxHeap.h>
 
 #include <cpufreq.h>
 

############################################################################

Commit:      e5bd2f91e3e8bd9481f74e68b816888ea1824ee7
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Mon Dec 30 23:59:29 2013 UTC

scheduler: Inherit penalty and core from creator thread

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/low_latency.cpp 
b/src/system/kernel/scheduler/low_latency.cpp
index 1e0c79d..42baee3 100644
--- a/src/system/kernel/scheduler/low_latency.cpp
+++ b/src/system/kernel/scheduler/low_latency.cpp
@@ -35,7 +35,8 @@ static bool
 has_cache_expired(const ThreadData* threadData)
 {
        SCHEDULER_ENTER_FUNCTION();
-
+       if (threadData->WentSleepActive() == 0)
+               return false;
        CoreEntry* core = threadData->Core();
        bigtime_t activeTime = core->GetActiveTime();
        return activeTime - threadData->WentSleepActive() > kCacheExpire;
diff --git a/src/system/kernel/scheduler/power_saving.cpp 
b/src/system/kernel/scheduler/power_saving.cpp
index 4239fd1..3b36add 100644
--- a/src/system/kernel/scheduler/power_saving.cpp
+++ b/src/system/kernel/scheduler/power_saving.cpp
@@ -41,6 +41,8 @@ static bool
 has_cache_expired(const ThreadData* threadData)
 {
        SCHEDULER_ENTER_FUNCTION();
+       if (threadData->WentSleep() == 0)
+               return false;
        return system_time() - threadData->WentSleep() > kCacheExpire;
 }
 
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index 4db6516..9f5d834 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -16,14 +16,12 @@ ThreadData::ThreadData(Thread* thread)
        :
        fThread(thread)
 {
-       Init();
 }
 
 
 void
 ThreadData::Init()
 {
-       fPriorityPenalty = 0;
        fAdditionalPenalty = 0;
        fEffectivePriority = -1;
 
@@ -40,7 +38,25 @@ ThreadData::Init()
 
        fEnqueued = false;
 
-       fCore = NULL;
+       Thread* currentThread = thread_get_current_thread();
+       ASSERT(currentThread != NULL);
+       if (!thread_is_idle_thread(currentThread)) {
+               ThreadData* currentThreadData = currentThread->scheduler_data;
+               int32 penalty = currentThreadData->fPriorityPenalty;
+
+               int32 minimalPriority = _GetMinimalPriority();
+               if (fThread->priority - penalty >= minimalPriority)
+                       fPriorityPenalty = penalty;
+               else
+                       fPriorityPenalty = fThread->priority - minimalPriority;
+
+               fCore = currentThreadData->fCore;
+       } else {
+               fPriorityPenalty = 0;
+               fAdditionalPenalty = 0;
+
+               fCore = NULL;
+       }
 }
 
 
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index d37d8bf..98cc660 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -195,7 +195,7 @@ ThreadData::ShouldCancelPenalty() const
 {
        SCHEDULER_ENTER_FUNCTION();
 
-       if (fCore == NULL)
+       if (fCore == NULL || fWentSleep == 0)
                return false;
 
        return fCore->StarvationCounter() != fWentSleepCount

############################################################################

Commit:      affaf2267dcdd2a8bf1d0a02da307e4406128fa7
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Dec 31 02:50:01 2013 UTC

kernel: Do not attempt to interrupt a thread that is not waiting

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h
index 96d80ba..f41987c 100644
--- a/headers/private/kernel/thread.h
+++ b/headers/private/kernel/thread.h
@@ -383,10 +383,12 @@ thread_unblock_locked(Thread* thread, status_t status)
 static inline status_t
 thread_interrupt(Thread* thread, bool kill)
 {
-       if ((thread->wait.flags & B_CAN_INTERRUPT) != 0
-               || (kill && (thread->wait.flags & B_KILL_CAN_INTERRUPT) != 0)) {
-               thread_unblock_locked(thread, B_INTERRUPTED);
-               return B_OK;
+       if (thread_is_blocked(thread)) {
+               if ((thread->wait.flags & B_CAN_INTERRUPT) != 0
+                       || (kill && (thread->wait.flags & B_KILL_CAN_INTERRUPT) 
!= 0)) {
+                       thread_unblock_locked(thread, B_INTERRUPTED);
+                       return B_OK;
+               }
        }
 
        return B_NOT_ALLOWED;

############################################################################

Commit:      c4292aceb9febae7f5880a1903f405abadfb95cd
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Dec 31 03:48:23 2013 UTC

scheduler: Thread can not stay on CPU if it has been disabled

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index fc941b3..41546f0 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -532,6 +532,9 @@ reschedule(int32 nextState)
        }
 
        Thread* nextThread = nextThreadData->GetThread();
+       ASSERT(!gCPU[thisCPU].disabled || thread_is_idle_thread(nextThread));
+
+       // update CPU heap
        CoreCPUHeapLocker cpuLocker(core);
        cpu->UpdatePriority(nextThreadData->GetEffectivePriority());
        cpuLocker.Unlock();
@@ -559,11 +562,6 @@ reschedule(int32 nextState)
        ASSERT(nextThreadData->Core() == core);
        nextThread->state = B_THREAD_RUNNING;
 
-       // update CPU heap
-       cpuLocker.Lock();
-       cpu->UpdatePriority(nextThreadData->GetEffectivePriority());
-       cpuLocker.Unlock();
-
        // track kernel time (user time is tracked in thread_at_kernel_entry())
        update_thread_times(oldThread, nextThread);
 
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index 9f5d834..4d5ea19 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -210,7 +210,7 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& 
rescheduleNeeded) const
 
        if (fThread->previous_cpu != NULL) {
                CPUEntry* previousCPU = 
&gCPUEntries[fThread->previous_cpu->cpu_num];
-               if (previousCPU->Core() == core) {
+               if (previousCPU->Core() == core && 
!fThread->previous_cpu->disabled) {
                        CoreCPUHeapLocker _(core);
                        if (CPUPriorityHeap::GetKey(previousCPU) < 
threadPriority) {
                                previousCPU->UpdatePriority(threadPriority);


Other related posts:

  • » [haiku-commits] BRANCH pdziepak-github.scheduler [c4292ac] src/system/kernel/scheduler headers/private/kernel - pdziepak-github . scheduler