diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 0ee4cd0bd8..babf25b872 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 4bdb566840..d715e72d44 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 95f20bc9f9..6c1d209971 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 e7a2445293..63f4450b6e 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 fd28497f3d..896692095b 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)