scheduler: Keep track of the number of the ready threads
This commit is contained in:
@@ -53,20 +53,6 @@ bool gSingleCore;
|
|||||||
bool gCPUFrequencyManagement;
|
bool gCPUFrequencyManagement;
|
||||||
bool gTrackLoad;
|
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
|
} // namespace Scheduler
|
||||||
|
|
||||||
using namespace Scheduler;
|
using namespace Scheduler;
|
||||||
@@ -415,6 +401,7 @@ reschedule(int32 nextState)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case THREAD_STATE_FREE_ON_RESCHED:
|
case THREAD_STATE_FREE_ON_RESCHED:
|
||||||
|
oldThreadData->Dies();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
oldThreadData->GoesAway();
|
oldThreadData->GoesAway();
|
||||||
|
|||||||
@@ -13,6 +13,25 @@
|
|||||||
#include "scheduler_thread.h"
|
#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;
|
using namespace Scheduler;
|
||||||
|
|
||||||
|
|
||||||
@@ -340,7 +359,7 @@ CPUPriorityHeap::Dump()
|
|||||||
CoreEntry::CoreEntry()
|
CoreEntry::CoreEntry()
|
||||||
:
|
:
|
||||||
fCPUCount(0),
|
fCPUCount(0),
|
||||||
fCPUIdleCount(0),
|
fIdleCPUCount(0),
|
||||||
fStarvationCounter(0),
|
fStarvationCounter(0),
|
||||||
fStarvationCounterIdle(0),
|
fStarvationCounterIdle(0),
|
||||||
fThreadCount(0),
|
fThreadCount(0),
|
||||||
@@ -459,9 +478,9 @@ void
|
|||||||
CoreEntry::AddCPU(CPUEntry* cpu)
|
CoreEntry::AddCPU(CPUEntry* cpu)
|
||||||
{
|
{
|
||||||
ASSERT(fCPUCount >= 0);
|
ASSERT(fCPUCount >= 0);
|
||||||
ASSERT(fCPUIdleCount >= 0);
|
ASSERT(fIdleCPUCount >= 0);
|
||||||
|
|
||||||
fCPUIdleCount++;
|
fIdleCPUCount++;
|
||||||
if (fCPUCount++ == 0) {
|
if (fCPUCount++ == 0) {
|
||||||
// core has been reenabled
|
// core has been reenabled
|
||||||
fLoad = 0;
|
fLoad = 0;
|
||||||
@@ -479,9 +498,9 @@ void
|
|||||||
CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing)
|
CoreEntry::RemoveCPU(CPUEntry* cpu, ThreadProcessing& threadPostProcessing)
|
||||||
{
|
{
|
||||||
ASSERT(fCPUCount > 0);
|
ASSERT(fCPUCount > 0);
|
||||||
ASSERT(fCPUIdleCount > 0);
|
ASSERT(fIdleCPUCount > 0);
|
||||||
|
|
||||||
fCPUIdleCount--;
|
fIdleCPUCount--;
|
||||||
if (--fCPUCount == 0) {
|
if (--fCPUCount == 0) {
|
||||||
// core has been disabled
|
// core has been disabled
|
||||||
if (fHighLoad) {
|
if (fHighLoad) {
|
||||||
@@ -545,8 +564,10 @@ CoreLoadHeap::Dump()
|
|||||||
CoreEntry* entry = PeekMinimum();
|
CoreEntry* entry = PeekMinimum();
|
||||||
while (entry) {
|
while (entry) {
|
||||||
int32 key = GetKey(entry);
|
int32 key = GetKey(entry);
|
||||||
|
|
||||||
|
int32 activeCPUs = entry->CPUCount() - entry->IdleCPUCount();
|
||||||
kprintf("%4" B_PRId32 " %3" B_PRId32 "%% %7" B_PRId32 "\n", entry->ID(),
|
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();
|
RemoveMinimum();
|
||||||
sDebugCoreHeap.Insert(entry, key);
|
sDebugCoreHeap.Insert(entry, key);
|
||||||
@@ -664,6 +685,8 @@ dump_run_queue(int /* argc */, char** /* argv */)
|
|||||||
static int
|
static int
|
||||||
dump_cpu_heap(int /* argc */, char** /* argv */)
|
dump_cpu_heap(int /* argc */, char** /* argv */)
|
||||||
{
|
{
|
||||||
|
kprintf("Total ready threads: %" B_PRId32 "\n\n", gReadyThreadCount);
|
||||||
|
|
||||||
kprintf("core load threads\n");
|
kprintf("core load threads\n");
|
||||||
gCoreLoadHeap.Dump();
|
gCoreLoadHeap.Dump();
|
||||||
kprintf("\n");
|
kprintf("\n");
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ public:
|
|||||||
inline PackageEntry* Package() const { return fPackage; }
|
inline PackageEntry* Package() const { return fPackage; }
|
||||||
inline int32 CPUCount() const
|
inline int32 CPUCount() const
|
||||||
{ return fCPUCount; }
|
{ return fCPUCount; }
|
||||||
|
inline int32 IdleCPUCount() const
|
||||||
|
{ return fIdleCPUCount; }
|
||||||
|
|
||||||
inline void LockCPUHeap();
|
inline void LockCPUHeap();
|
||||||
inline void UnlockCPUHeap();
|
inline void UnlockCPUHeap();
|
||||||
@@ -170,7 +172,7 @@ private:
|
|||||||
PackageEntry* fPackage;
|
PackageEntry* fPackage;
|
||||||
|
|
||||||
int32 fCPUCount;
|
int32 fCPUCount;
|
||||||
int32 fCPUIdleCount;
|
int32 fIdleCPUCount;
|
||||||
CPUPriorityHeap fCPUHeap;
|
CPUPriorityHeap fCPUHeap;
|
||||||
spinlock fCPULock;
|
spinlock fCPULock;
|
||||||
|
|
||||||
@@ -452,8 +454,8 @@ CoreEntry::CPUGoesIdle(CPUEntry* /* cpu */)
|
|||||||
if (gSingleCore)
|
if (gSingleCore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASSERT(fCPUIdleCount < fCPUCount);
|
ASSERT(fIdleCPUCount < fCPUCount);
|
||||||
if (++fCPUIdleCount == fCPUCount)
|
if (++fIdleCPUCount == fCPUCount)
|
||||||
fPackage->CoreGoesIdle(this);
|
fPackage->CoreGoesIdle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,8 +466,8 @@ CoreEntry::CPUWakesUp(CPUEntry* /* cpu */)
|
|||||||
if (gSingleCore)
|
if (gSingleCore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASSERT(fCPUIdleCount > 0);
|
ASSERT(fIdleCPUCount > 0);
|
||||||
if (fCPUIdleCount-- == fCPUCount)
|
if (fIdleCPUCount-- == fCPUCount)
|
||||||
fPackage->CoreWakesUp(this);
|
fPackage->CoreWakesUp(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,14 @@
|
|||||||
#include "scheduler_thread.h"
|
#include "scheduler_thread.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Scheduler {
|
||||||
|
|
||||||
|
|
||||||
|
int32 gReadyThreadCount;
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Scheduler
|
||||||
|
|
||||||
using namespace Scheduler;
|
using namespace Scheduler;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public:
|
|||||||
inline void SetStolenInterruptTime(bigtime_t interruptTime);
|
inline void SetStolenInterruptTime(bigtime_t interruptTime);
|
||||||
|
|
||||||
inline void GoesAway();
|
inline void GoesAway();
|
||||||
|
inline void Dies();
|
||||||
|
|
||||||
inline bigtime_t WentSleep() const { return fWentSleep; }
|
inline bigtime_t WentSleep() const { return fWentSleep; }
|
||||||
inline bigtime_t WentSleepActive() const { return fWentSleepActive; }
|
inline bigtime_t WentSleepActive() const { return fWentSleepActive; }
|
||||||
|
|
||||||
@@ -128,6 +130,8 @@ public:
|
|||||||
virtual void operator()(ThreadData* thread) = 0;
|
virtual void operator()(ThreadData* thread) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern int32 gReadyThreadCount;
|
||||||
|
|
||||||
|
|
||||||
inline int32
|
inline int32
|
||||||
ThreadData::_GetMinimalPriority() const
|
ThreadData::_GetMinimalPriority() const
|
||||||
@@ -260,6 +264,16 @@ ThreadData::GoesAway()
|
|||||||
fWentSleepCount = fCore->StarvationCounter();
|
fWentSleepCount = fCore->StarvationCounter();
|
||||||
fWentSleepCountIdle = fCore->StarvationCounterIdle();
|
fWentSleepCountIdle = fCore->StarvationCounterIdle();
|
||||||
fWentSleepActive = fCore->GetActiveTime();
|
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();
|
SCHEDULER_ENTER_FUNCTION();
|
||||||
|
|
||||||
|
if (fThread->state != B_THREAD_READY && fThread->state != B_THREAD_RUNNING)
|
||||||
|
atomic_add(&gReadyThreadCount, 1);
|
||||||
|
|
||||||
fThread->state = B_THREAD_READY;
|
fThread->state = B_THREAD_READY;
|
||||||
|
|
||||||
if (gTrackLoad)
|
if (gTrackLoad)
|
||||||
|
|||||||
Reference in New Issue
Block a user