scheduler: Keep track of the number of the ready threads

This commit is contained in:
Pawel Dziepak 2014-01-08 05:02:04 +01:00
parent 9c465cc83b
commit d36098e043
5 changed files with 62 additions and 25 deletions

View File

@ -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();

View File

@ -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");

View File

@ -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);
}

View File

@ -6,6 +6,14 @@
#include "scheduler_thread.h"
namespace Scheduler {
int32 gReadyThreadCount;
} // namespace Scheduler
using namespace Scheduler;

View File

@ -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)