[haiku-commits] BRANCH pdziepak-github.scheduler [f6ad3d7] src/system/kernel/scheduler

  • From: pdziepak-github.scheduler <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 8 Jan 2014 07:30:32 +0100 (CET)

added 3 changesets to branch 'refs/remotes/pdziepak-github/scheduler'
old head: 51592558cc941f06948a58c48ff3ff462054a713
new head: f6ad3d77f7f4cd87f56e077983f7fe895588bcee
overview: https://github.com/pdziepak/Haiku/compare/5159255...f6ad3d7

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

cd486a1: scheduler: Improve recognition of CPU bound threads

6928199: scheduler: Keep track of the number of the ready threads

f6ad3d7: scheduler: Introduce strong and weak priority penalties

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

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

8 files changed, 172 insertions(+), 74 deletions(-)
src/system/kernel/scheduler/low_latency.cpp      |  8 +--
src/system/kernel/scheduler/power_saving.cpp     |  2 -
src/system/kernel/scheduler/scheduler.cpp        | 18 +----
src/system/kernel/scheduler/scheduler_cpu.cpp    | 64 +++++++++++------
src/system/kernel/scheduler/scheduler_cpu.h      | 30 ++++++--
src/system/kernel/scheduler/scheduler_modes.h    |  2 -
src/system/kernel/scheduler/scheduler_thread.cpp | 46 +++++++++---
src/system/kernel/scheduler/scheduler_thread.h   | 76 ++++++++++++++++----

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

Commit:      cd486a157ef7dfe2607603d1b65624499d647591
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Wed Jan  8 03:36:28 2014 UTC

scheduler: Improve recognition of CPU bound threads

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

diff --git a/src/system/kernel/scheduler/low_latency.cpp 
b/src/system/kernel/scheduler/low_latency.cpp
index 09c6f71..51381c3 100644
--- a/src/system/kernel/scheduler/low_latency.cpp
+++ b/src/system/kernel/scheduler/low_latency.cpp
@@ -160,13 +160,11 @@ rebalance_irqs(bool idle)
 scheduler_mode_operations gSchedulerLowLatencyMode = {
        "low latency",
 
-       true,
-
        2000,
-       700,
-       { 2, 30 },
+       100,
+       { 2, 25 },
 
-       60000,
+       50000,
 
        switch_to_mode,
        set_cpu_enabled,
diff --git a/src/system/kernel/scheduler/power_saving.cpp 
b/src/system/kernel/scheduler/power_saving.cpp
index b41bbe7..66efc8c 100644
--- a/src/system/kernel/scheduler/power_saving.cpp
+++ b/src/system/kernel/scheduler/power_saving.cpp
@@ -236,8 +236,6 @@ rebalance_irqs(bool idle)
 scheduler_mode_operations gSchedulerPowerSavingMode = {
        "power saving",
 
-       false,
-
        3000,
        1000,
        { 3, 60 },
diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index ca04585..0ee4cd0 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -404,8 +404,6 @@ reschedule(int32 nextState)
 
                        if 
(oldThreadData->HasQuantumEnded(oldThread->cpu->preempted,
                                        oldThread->has_yielded)) {
-                               oldThreadData->IncreasePenalty();
-
                                TRACE("enqueueing thread %ld into run queue 
priority = %ld\n",
                                        oldThread->id, 
oldThreadData->GetEffectivePriority());
                                putOldThreadAtBack = true;
@@ -419,7 +417,6 @@ reschedule(int32 nextState)
                case THREAD_STATE_FREE_ON_RESCHED:
                        break;
                default:
-                       oldThreadData->IncreasePenalty();
                        oldThreadData->GoesAway();
                        TRACE("not enqueueing thread %ld into run queue 
next_state = %ld\n",
                                oldThread->id, nextState);
diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp 
b/src/system/kernel/scheduler/scheduler_cpu.cpp
index 9f9eb48..4bdb566 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.cpp
+++ b/src/system/kernel/scheduler/scheduler_cpu.cpp
@@ -21,7 +21,6 @@ public:
        static  void            DumpCPURunQueue(CPUEntry* cpu);
        static  void            DumpCoreRunQueue(CoreEntry* core);
        static  void            DumpIdleCoresInPackage(PackageEntry* package);
-
 };
 
 
@@ -43,7 +42,8 @@ ThreadRunQueue::Dump() const
 
                        kprintf("%p  %-7" B_PRId32 " %-8" B_PRId32 " %-8" 
B_PRId32 " %s\n",
                                thread, thread->id, thread->priority,
-                               threadData->GetEffectivePriority(), 
thread->name);
+                               thread->priority - 
threadData->GetEffectivePriority(),
+                               thread->name);
                }
        }
 }
@@ -159,9 +159,6 @@ CPUEntry::UpdatePriority(int32 priority)
                return;
        fCore->CPUHeap()->ModifyKey(this, priority);
 
-       if (gSingleCore)
-               return;
-
        if (oldPriority == B_IDLE_PRIORITY)
                fCore->CPUWakesUp(this);
        else if (priority == B_IDLE_PRIORITY)
@@ -345,6 +342,7 @@ CoreEntry::CoreEntry()
        fCPUCount(0),
        fCPUIdleCount(0),
        fStarvationCounter(0),
+       fStarvationCounterIdle(0),
        fThreadCount(0),
        fActiveTime(0),
        fLoad(0),
@@ -380,8 +378,6 @@ CoreEntry::PushBack(ThreadData* thread, int32 priority)
        SCHEDULER_ENTER_FUNCTION();
 
        fRunQueue.PushBack(thread, priority);
-       fThreadList.Insert(thread);
-
        atomic_add(&fThreadCount, 1);
 }
 
@@ -393,12 +389,13 @@ CoreEntry::Remove(ThreadData* thread)
 
        ASSERT(thread->IsEnqueued());
        thread->SetDequeued();
-       if (thread_is_idle_thread(thread->GetThread())
-               || fThreadList.Head() == thread) {
+
+       ASSERT(!thread_is_idle_thread(thread->GetThread()));
+       if (thread->GetEffectivePriority() == B_LOWEST_ACTIVE_PRIORITY
+               || thread->IsCPUBound()) {
                atomic_add(&fStarvationCounter, 1);
        }
-       if (thread->WentSleepCount() == 0)
-               fThreadList.Remove(thread);
+
        fRunQueue.Remove(thread);
        atomic_add(&fThreadCount, -1);
 }
@@ -548,8 +545,8 @@ CoreLoadHeap::Dump()
        CoreEntry* entry = PeekMinimum();
        while (entry) {
                int32 key = GetKey(entry);
-               kprintf("%4" B_PRId32 " %3" B_PRId32 "%%\n", entry->ID(),
-                       entry->GetLoad() / 10);
+               kprintf("%4" B_PRId32 " %3" B_PRId32 "%% %7" B_PRId32 "\n", 
entry->ID(),
+                       entry->GetLoad() / 10, entry->ThreadCount());
 
                RemoveMinimum();
                sDebugCoreHeap.Insert(entry, key);
@@ -647,7 +644,7 @@ DebugDumper::DumpIdleCoresInPackage(PackageEntry* package)
 
 
 static int
-dump_run_queue(int argc, char **argv)
+dump_run_queue(int /* argc */, char** /* argv */)
 {
        int32 cpuCount = smp_get_num_cpus();
        int32 coreCount = gCoreCount;
@@ -665,9 +662,9 @@ dump_run_queue(int argc, char **argv)
 
 
 static int
-dump_cpu_heap(int argc, char** argv)
+dump_cpu_heap(int /* argc */, char** /* argv */)
 {
-       kprintf("core load\n");
+       kprintf("core load threads\n");
        gCoreLoadHeap.Dump();
        kprintf("\n");
        gCoreHighLoadHeap.Dump();
@@ -685,7 +682,7 @@ dump_cpu_heap(int argc, char** argv)
 
 
 static int
-dump_idle_cores(int argc, char** argv)
+dump_idle_cores(int /* argc */, char** /* argv */)
 {
        kprintf("Idle packages:\n");
        IdlePackageList::ReverseIterator idleIterator
diff --git a/src/system/kernel/scheduler/scheduler_cpu.h 
b/src/system/kernel/scheduler/scheduler_cpu.h
index 1def98d..95f20bc 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.h
+++ b/src/system/kernel/scheduler/scheduler_cpu.h
@@ -150,6 +150,7 @@ public:
                                                void                    
UpdateLoad(int32 delta);
 
        inline                          int32                   
StarvationCounter() const;
+       inline                          int32                   
StarvationCounterIdle() const;
 
        inline                          void                    
CPUGoesIdle(CPUEntry* cpu);
        inline                          void                    
CPUWakesUp(CPUEntry* cpu);
@@ -174,7 +175,7 @@ private:
                                                spinlock                
fCPULock;
 
                                                int32                   
fStarvationCounter;
-                                               DoublyLinkedList<ThreadData>    
fThreadList;
+                                               int32                   
fStarvationCounterIdle;
 
                                                int32                   
fThreadCount;
                                                ThreadRunQueue  fRunQueue;
@@ -387,6 +388,14 @@ CoreEntry::StarvationCounter() const
 }
 
 
+inline int32
+CoreEntry::StarvationCounterIdle() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+       return fStarvationCounterIdle;
+}
+
+
 /* PackageEntry::CoreGoesIdle and PackageEntry::CoreWakesUp have to be defined
    before CoreEntry::CPUGoesIdle and CoreEntry::CPUWakesUp. If they weren't
    GCC2 wouldn't inline them as, apparently, it doesn't do enough optimization
@@ -437,8 +446,13 @@ PackageEntry::CoreWakesUp(CoreEntry* core)
 inline void
 CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
 {
-       ASSERT(fCPUIdleCount < fCPUCount);
+       atomic_add(&fStarvationCounter, 1);
+       atomic_add(&fStarvationCounterIdle, 1);
+
+       if (gSingleCore)
+               return;
 
+       ASSERT(fCPUIdleCount < fCPUCount);
        if (++fCPUIdleCount == fCPUCount)
                fPackage->CoreGoesIdle(this);
 }
@@ -447,8 +461,10 @@ CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
 inline void
 CoreEntry::CPUWakesUp(CPUEntry* /* cpu */)
 {
-       ASSERT(fCPUIdleCount > 0);
+       if (gSingleCore)
+               return;
 
+       ASSERT(fCPUIdleCount > 0);
        if (fCPUIdleCount-- == fCPUCount)
                fPackage->CoreWakesUp(this);
 }
diff --git a/src/system/kernel/scheduler/scheduler_modes.h 
b/src/system/kernel/scheduler/scheduler_modes.h
index 09670dd..820912a 100644
--- a/src/system/kernel/scheduler/scheduler_modes.h
+++ b/src/system/kernel/scheduler/scheduler_modes.h
@@ -13,8 +13,6 @@
 struct scheduler_mode_operations {
        const char*                             name;
 
-       bool                                    avoid_boost;
-
        bigtime_t                               base_quantum;
        bigtime_t                               minimal_quantum;
        bigtime_t                               quantum_multipliers[2];
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index af4b40a..e7a2445 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -19,6 +19,9 @@ ThreadData::_InitBase()
        fAdditionalPenalty = 0;
        fEffectivePriority = fThread->priority;
 
+       fReceivedPenalty = false;
+       fHasSlept = false;
+
        fTimeLeft = 0;
        fStolenTime = 0;
 
@@ -28,7 +31,8 @@ ThreadData::_InitBase()
 
        fWentSleep = 0;
        fWentSleepActive = 0;
-       fWentSleepCount = -1;
+       fWentSleepCount = 0;
+       fWentSleepCountIdle = 0;
 
        fEnqueued = false;
 }
@@ -124,7 +128,25 @@ ThreadData::Dump() const
                additionalPenalty = fAdditionalPenalty % kMinimalPriority;
        kprintf("\tadditional_penalty:\t%" B_PRId32 " (%" B_PRId32 ")\n",
                additionalPenalty, fAdditionalPenalty);
-       kprintf("\tstolen_time:\t\t%" B_PRId64 "\n", fStolenTime);
+       kprintf("\teffective_priority:\t%" B_PRId32 "\n", 
GetEffectivePriority());
+
+       kprintf("\treceived_penalty:\t%s\n", fReceivedPenalty ? "true" : 
"false");
+       kprintf("\thas_slept:\t\t%s\n", fHasSlept ? "true" : "false");
+
+       bigtime_t quantum = _GetBaseQuantum();
+       if (fThread->priority < B_FIRST_REAL_TIME_PRIORITY) {
+               int32 threadCount = (fCore->ThreadCount() + 1) / 
fCore->CPUCount();
+               threadCount = max_c(threadCount, 1);
+
+               quantum
+                       = std::min(gCurrentMode->maximum_latency / threadCount, 
quantum);
+               quantum = std::max(quantum,     gCurrentMode->minimal_quantum);
+       }
+       kprintf("\ttime_left:\t\t%" B_PRId64 " us (quantum: %" B_PRId64 " 
us)\n",
+               fTimeLeft, quantum);
+
+       kprintf("\tstolen_time:\t\t%" B_PRId64 " us\n", fStolenTime);
+       kprintf("\tquantum_start:\t\t%" B_PRId64 " us\n", fQuantumStart);
        kprintf("\tload:\t\t\t%" B_PRId32 "%%\n", fLoad / 10);
        kprintf("\twent_sleep:\t\t%" B_PRId64 "\n", fWentSleep);
        kprintf("\twent_sleep_active:\t%" B_PRId64 "\n", fWentSleepActive);
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index 5c8d052..fd28497 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -44,10 +44,11 @@ public:
 
        inline  int32           GetEffectivePriority() const;
 
-       inline  void            IncreasePenalty();
        inline  void            CancelPenalty();
        inline  bool            ShouldCancelPenalty() const;
 
+       inline  bool            IsCPUBound() const      { return 
fAdditionalPenalty != 0; }
+
                        bool            ChooseCoreAndCPU(CoreEntry*& targetCore,
                                                        CPUEntry*& targetCPU);
 
@@ -58,7 +59,6 @@ public:
        inline  void            GoesAway();
        inline  bigtime_t       WentSleep() const       { return fWentSleep; }
        inline  bigtime_t       WentSleepActive() const { return 
fWentSleepActive; }
-       inline  bigtime_t       WentSleepCount() const  { return 
fWentSleepCount; }
 
        inline  void            PutBack();
        inline  void            Enqueue();
@@ -83,6 +83,7 @@ public:
        static  void            ComputeQuantumLengths();
 
 private:
+       inline  void            _IncreasePenalty();
        inline  int32           _GetPenalty() const;
 
                        void            _ComputeEffectivePriority() const;
@@ -98,6 +99,7 @@ private:
                        bigtime_t       fWentSleep;
                        bigtime_t       fWentSleepActive;
                        int32           fWentSleepCount;
+                       int32           fWentSleepCountIdle;
 
                        bool            fEnqueued;
 
@@ -105,6 +107,8 @@ private:
 
                        int32           fPriorityPenalty;
                        int32           fAdditionalPenalty;
+                       bool            fReceivedPenalty;
+                       bool            fHasSlept;
 
        mutable int32           fEffectivePriority;
 
@@ -167,7 +171,7 @@ ThreadData::GetEffectivePriority() const
 
 
 inline void
-ThreadData::IncreasePenalty()
+ThreadData::_IncreasePenalty()
 {
        SCHEDULER_ENTER_FUNCTION();
 
@@ -178,6 +182,7 @@ ThreadData::IncreasePenalty()
 
        TRACE("increasing thread %ld penalty\n", fThread->id);
 
+       fReceivedPenalty = true;
        int32 oldPenalty = fPriorityPenalty++;
 
        ASSERT(fThread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY);
@@ -216,9 +221,16 @@ ThreadData::ShouldCancelPenalty() const
 
        if (fCore == NULL)
                return false;
+       if (system_time() - fWentSleep > gCurrentMode->minimal_quantum * 2)
+               return false;
+
+       if (GetEffectivePriority() != B_LOWEST_ACTIVE_PRIORITY
+               && !IsCPUBound()) {
+               if (fCore->StarvationCounter() != fWentSleepCount)
+                       return true;
+       }
 
-       return fCore->StarvationCounter() != fWentSleepCount
-               && system_time() - fWentSleep > gCurrentMode->base_quantum;
+       return fCore->StarvationCounterIdle() != fWentSleepCountIdle;
 }
 
 
@@ -238,10 +250,15 @@ ThreadData::GoesAway()
 {
        SCHEDULER_ENTER_FUNCTION();
 
+       if (!fReceivedPenalty)
+               _IncreasePenalty();
+       fHasSlept = true;
+
        fLastInterruptTime = 0;
 
        fWentSleep = system_time();
        fWentSleepCount = fCore->StarvationCounter();
+       fWentSleepCountIdle = fCore->StarvationCounterIdle();
        fWentSleepActive = fCore->GetActiveTime();
 }
 
@@ -253,7 +270,6 @@ ThreadData::PutBack()
 
        if (gTrackLoad)
                ComputeLoad();
-       fWentSleepCount = -1;
 
        int32 priority = GetEffectivePriority();
 
@@ -285,7 +301,6 @@ ThreadData::Enqueue()
 
        if (gTrackLoad)
                ComputeLoad();
-       fWentSleepCount = 0;
 
        int32 priority = GetEffectivePriority();
 
@@ -328,7 +343,7 @@ ThreadData::Dequeue()
        CoreRunQueueLocker _(fCore);
        if (!fEnqueued)
                return false;
-       ASSERT(fWentSleepCount < 1);
+
        fCore->Remove(this);
        ASSERT(!fEnqueued);
        return true;
@@ -354,15 +369,25 @@ ThreadData::HasQuantumEnded(bool wasPreempted, bool 
hasYielded)
        }
 
        bigtime_t timeUsed = system_time() - fQuantumStart;
-       fTimeLeft -= timeUsed;
+       if (timeUsed > 0);
+               fTimeLeft -= timeUsed;
        fTimeLeft = std::max(fTimeLeft, bigtime_t(0));
 
        // too little time left, it's better make the next quantum a bit longer
-       if (wasPreempted || fTimeLeft <= gCurrentMode->minimal_quantum) {
+       int32 skipTime = gCurrentMode->minimal_quantum;
+       skipTime -= skipTime / 10;
+       if (wasPreempted || fTimeLeft <= skipTime) {
                fStolenTime += fTimeLeft;
                fTimeLeft = 0;
        }
 
+       if (fTimeLeft == 0) {
+               if (!fReceivedPenalty && !fHasSlept)
+                       _IncreasePenalty();
+               fReceivedPenalty = false;
+               fHasSlept = false;
+       }
+
        return fTimeLeft == 0;
 }
 

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

Commit:      6928199bc882d48c9f08bfb15162f044e9751464
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Wed Jan  8 04:02:04 2014 UTC

scheduler: Keep track of the number of the ready threads

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

diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index 0ee4cd0..babf25b 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -53,20 +53,6 @@ bool gSingleCore;
 bool gCPUFrequencyManagement;
 bool gTrackLoad;
 
-CPUEntry* gCPUEntries;
-
-CoreEntry* gCoreEntries;
-CoreLoadHeap gCoreLoadHeap;
-CoreLoadHeap gCoreHighLoadHeap;
-rw_spinlock gCoreHeapsLock = B_RW_SPINLOCK_INITIALIZER;
-int32 gCoreCount;
-
-PackageEntry* gPackageEntries;
-IdlePackageList gIdlePackageList;
-rw_spinlock gIdlePackageLock = B_RW_SPINLOCK_INITIALIZER;
-int32 gPackageCount;
-
-
 }      // namespace Scheduler
 
 using namespace Scheduler;
@@ -415,6 +401,7 @@ reschedule(int32 nextState)
 
                        break;
                case THREAD_STATE_FREE_ON_RESCHED:
+                       oldThreadData->Dies();
                        break;
                default:
                        oldThreadData->GoesAway();
diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp 
b/src/system/kernel/scheduler/scheduler_cpu.cpp
index 4bdb566..d715e72 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.cpp
+++ b/src/system/kernel/scheduler/scheduler_cpu.cpp
@@ -13,6 +13,25 @@
 #include "scheduler_thread.h"
 
 
+namespace Scheduler {
+
+
+CPUEntry* gCPUEntries;
+
+CoreEntry* gCoreEntries;
+CoreLoadHeap gCoreLoadHeap;
+CoreLoadHeap gCoreHighLoadHeap;
+rw_spinlock gCoreHeapsLock = B_RW_SPINLOCK_INITIALIZER;
+int32 gCoreCount;
+
+PackageEntry* gPackageEntries;
+IdlePackageList gIdlePackageList;
+rw_spinlock gIdlePackageLock = B_RW_SPINLOCK_INITIALIZER;
+int32 gPackageCount;
+
+
+}      // namespace Scheduler
+
 using namespace Scheduler;
 
 
@@ -340,7 +359,7 @@ CPUPriorityHeap::Dump()
 CoreEntry::CoreEntry()
        :
        fCPUCount(0),
-       fCPUIdleCount(0),
+       fIdleCPUCount(0),
        fStarvationCounter(0),
        fStarvationCounterIdle(0),
        fThreadCount(0),
@@ -459,9 +478,9 @@ void
 CoreEntry::AddCPU(CPUEntry* cpu)
 {
        ASSERT(fCPUCount >= 0);
-       ASSERT(fCPUIdleCount >= 0);
+       ASSERT(fIdleCPUCount >= 0);
 
-       fCPUIdleCount++;
+       fIdleCPUCount++;
        if (fCPUCount++ == 0) {
                // core has been reenabled
                fLoad = 0;
@@ -479,9 +498,9 @@ void
 CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing)
 {
        ASSERT(fCPUCount > 0);
-       ASSERT(fCPUIdleCount > 0);
+       ASSERT(fIdleCPUCount > 0);
 
-       fCPUIdleCount--;
+       fIdleCPUCount--;
        if (--fCPUCount == 0) {
                // core has been disabled
                if (fHighLoad) {
@@ -545,8 +564,10 @@ CoreLoadHeap::Dump()
        CoreEntry* entry = PeekMinimum();
        while (entry) {
                int32 key = GetKey(entry);
+
+               int32 activeCPUs = entry->CPUCount() - entry->IdleCPUCount();
                kprintf("%4" B_PRId32 " %3" B_PRId32 "%% %7" B_PRId32 "\n", 
entry->ID(),
-                       entry->GetLoad() / 10, entry->ThreadCount());
+                       entry->GetLoad() / 10, entry->ThreadCount() + 
activeCPUs);
 
                RemoveMinimum();
                sDebugCoreHeap.Insert(entry, key);
@@ -664,6 +685,8 @@ dump_run_queue(int /* argc */, char** /* argv */)
 static int
 dump_cpu_heap(int /* argc */, char** /* argv */)
 {
+       kprintf("Total ready threads: %" B_PRId32 "\n\n", gReadyThreadCount);
+
        kprintf("core load threads\n");
        gCoreLoadHeap.Dump();
        kprintf("\n");
diff --git a/src/system/kernel/scheduler/scheduler_cpu.h 
b/src/system/kernel/scheduler/scheduler_cpu.h
index 95f20bc..6c1d209 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.h
+++ b/src/system/kernel/scheduler/scheduler_cpu.h
@@ -123,6 +123,8 @@ public:
        inline                          PackageEntry*   Package() const { 
return fPackage; }
        inline                          int32                   CPUCount() const
                                                                                
        { return fCPUCount; }
+       inline                          int32                   IdleCPUCount() 
const
+                                                                               
        { return fIdleCPUCount; }
 
        inline                          void                    LockCPUHeap();
        inline                          void                    UnlockCPUHeap();
@@ -170,7 +172,7 @@ private:
                                                PackageEntry*   fPackage;
 
                                                int32                   
fCPUCount;
-                                               int32                   
fCPUIdleCount;
+                                               int32                   
fIdleCPUCount;
                                                CPUPriorityHeap fCPUHeap;
                                                spinlock                
fCPULock;
 
@@ -452,8 +454,8 @@ CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
        if (gSingleCore)
                return;
 
-       ASSERT(fCPUIdleCount < fCPUCount);
-       if (++fCPUIdleCount == fCPUCount)
+       ASSERT(fIdleCPUCount < fCPUCount);
+       if (++fIdleCPUCount == fCPUCount)
                fPackage->CoreGoesIdle(this);
 }
 
@@ -464,8 +466,8 @@ CoreEntry::CPUWakesUp(CPUEntry* /* cpu */)
        if (gSingleCore)
                return;
 
-       ASSERT(fCPUIdleCount > 0);
-       if (fCPUIdleCount-- == fCPUCount)
+       ASSERT(fIdleCPUCount > 0);
+       if (fIdleCPUCount-- == fCPUCount)
                fPackage->CoreWakesUp(this);
 }
 
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index e7a2445..63f4450 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -6,6 +6,14 @@
 #include "scheduler_thread.h"
 
 
+namespace Scheduler {
+
+
+int32 gReadyThreadCount;
+
+
+}      // namespace Scheduler
+
 using namespace Scheduler;
 
 
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index fd28497..8966920 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -57,6 +57,8 @@ public:
        inline  void            SetStolenInterruptTime(bigtime_t interruptTime);
 
        inline  void            GoesAway();
+       inline  void            Dies();
+
        inline  bigtime_t       WentSleep() const       { return fWentSleep; }
        inline  bigtime_t       WentSleepActive() const { return 
fWentSleepActive; }
 
@@ -128,6 +130,8 @@ public:
        virtual void            operator()(ThreadData* thread) = 0;
 };
 
+extern int32 gReadyThreadCount;
+
 
 inline int32
 ThreadData::_GetMinimalPriority() const
@@ -260,6 +264,16 @@ ThreadData::GoesAway()
        fWentSleepCount = fCore->StarvationCounter();
        fWentSleepCountIdle = fCore->StarvationCounterIdle();
        fWentSleepActive = fCore->GetActiveTime();
+
+       atomic_add(&gReadyThreadCount, -1);
+}
+
+
+inline void
+ThreadData::Dies()
+{
+       SCHEDULER_ENTER_FUNCTION();
+       atomic_add(&gReadyThreadCount, -1);
 }
 
 
@@ -297,6 +311,9 @@ ThreadData::Enqueue()
 {
        SCHEDULER_ENTER_FUNCTION();
 
+       if (fThread->state != B_THREAD_READY && fThread->state != 
B_THREAD_RUNNING)
+               atomic_add(&gReadyThreadCount, 1);
+
        fThread->state = B_THREAD_READY;
 
        if (gTrackLoad)

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

Commit:      f6ad3d77f7f4cd87f56e077983f7fe895588bcee
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Wed Jan  8 06:03:22 2014 UTC

scheduler: Introduce strong and weak priority penalties

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

diff --git a/src/system/kernel/scheduler/low_latency.cpp 
b/src/system/kernel/scheduler/low_latency.cpp
index 51381c3..3b567cb 100644
--- a/src/system/kernel/scheduler/low_latency.cpp
+++ b/src/system/kernel/scheduler/low_latency.cpp
@@ -164,7 +164,7 @@ scheduler_mode_operations gSchedulerLowLatencyMode = {
        100,
        { 2, 25 },
 
-       50000,
+       10000,
 
        switch_to_mode,
        set_cpu_enabled,
diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp 
b/src/system/kernel/scheduler/scheduler_thread.cpp
index 63f4450..a16cf32 100644
--- a/src/system/kernel/scheduler/scheduler_thread.cpp
+++ b/src/system/kernel/scheduler/scheduler_thread.cpp
@@ -217,14 +217,14 @@ ThreadData::ComputeQuantum()
        quantum += fStolenTime;
        fStolenTime = 0;
 
-       int32 threadCount = (fCore->ThreadCount() + 1) / fCore->CPUCount();
-       threadCount = max_c(threadCount, 1);
-
-       quantum = std::min(gCurrentMode->maximum_latency / threadCount, 
quantum);
-       quantum = std::max(quantum,     gCurrentMode->minimal_quantum);
+       int32 threadCount = fCore->ThreadCount() / fCore->CPUCount();
+       if (threadCount >= 1) {
+               quantum
+                       = std::min(gCurrentMode->maximum_latency / threadCount, 
quantum);
+               quantum = std::max(quantum,     gCurrentMode->minimal_quantum);
+       }
 
        fTimeLeft = quantum;
-
        return quantum;
 }
 
diff --git a/src/system/kernel/scheduler/scheduler_thread.h 
b/src/system/kernel/scheduler/scheduler_thread.h
index 8966920..92e5f23 100644
--- a/src/system/kernel/scheduler/scheduler_thread.h
+++ b/src/system/kernel/scheduler/scheduler_thread.h
@@ -44,11 +44,11 @@ public:
 
        inline  int32           GetEffectivePriority() const;
 
+       inline  bool            IsCPUBound() const;
+
        inline  void            CancelPenalty();
        inline  bool            ShouldCancelPenalty() const;
 
-       inline  bool            IsCPUBound() const      { return 
fAdditionalPenalty != 0; }
-
                        bool            ChooseCoreAndCPU(CoreEntry*& targetCore,
                                                        CPUEntry*& targetCPU);
 
@@ -85,7 +85,7 @@ public:
        static  void            ComputeQuantumLengths();
 
 private:
-       inline  void            _IncreasePenalty();
+       inline  void            _IncreasePenalty(bool strong);
        inline  int32           _GetPenalty() const;
 
                        void            _ComputeEffectivePriority() const;
@@ -175,7 +175,7 @@ ThreadData::GetEffectivePriority() const
 
 
 inline void
-ThreadData::_IncreasePenalty()
+ThreadData::_IncreasePenalty(bool strong)
 {
        SCHEDULER_ENTER_FUNCTION();
 
@@ -187,12 +187,14 @@ ThreadData::_IncreasePenalty()
        TRACE("increasing thread %ld penalty\n", fThread->id);
 
        fReceivedPenalty = true;
-       int32 oldPenalty = fPriorityPenalty++;
+       int32 oldPenalty = fPriorityPenalty;
+       if (strong)
+               fPriorityPenalty++;
 
        ASSERT(fThread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY);
 
        const int kMinimalPriority = _GetMinimalPriority();
-       if (fThread->priority - oldPenalty <= kMinimalPriority) {
+       if (!strong || fThread->priority - oldPenalty <= kMinimalPriority) {
                fPriorityPenalty = oldPenalty;
                fAdditionalPenalty++;
        }
@@ -201,6 +203,14 @@ ThreadData::_IncreasePenalty()
 }
 
 
+inline bool
+ThreadData::IsCPUBound() const
+{
+       SCHEDULER_ENTER_FUNCTION();
+       return fAdditionalPenalty != 0 && fPriorityPenalty != 0;
+}
+
+
 inline void
 ThreadData::CancelPenalty()
 {
@@ -255,7 +265,7 @@ ThreadData::GoesAway()
        SCHEDULER_ENTER_FUNCTION();
 
        if (!fReceivedPenalty)
-               _IncreasePenalty();
+               _IncreasePenalty(false);
        fHasSlept = true;
 
        fLastInterruptTime = 0;
@@ -400,7 +410,7 @@ ThreadData::HasQuantumEnded(bool wasPreempted, bool 
hasYielded)
 
        if (fTimeLeft == 0) {
                if (!fReceivedPenalty && !fHasSlept)
-                       _IncreasePenalty();
+                       _IncreasePenalty(true);
                fReceivedPenalty = false;
                fHasSlept = false;
        }


Other related posts:

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