1d287274dSPawel Dziepak /* 2d287274dSPawel Dziepak * Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org. 3d287274dSPawel Dziepak * Distributed under the terms of the MIT License. 4d287274dSPawel Dziepak */ 5d287274dSPawel Dziepak #ifndef KERNEL_SCHEDULER_CPU_H 6d287274dSPawel Dziepak #define KERNEL_SCHEDULER_CPU_H 7d287274dSPawel Dziepak 8d287274dSPawel Dziepak 9d287274dSPawel Dziepak #include <OS.h> 10d287274dSPawel Dziepak 11d287274dSPawel Dziepak #include <thread.h> 12e1e7235cSPawel Dziepak #include <util/AutoLock.h> 13d287274dSPawel Dziepak #include <util/MinMaxHeap.h> 14*ef8e55a1SPawel Dziepak #include <util/Heap.h> 15d287274dSPawel Dziepak 16d287274dSPawel Dziepak #include <cpufreq.h> 17d287274dSPawel Dziepak 18d287274dSPawel Dziepak #include "RunQueue.h" 19d287274dSPawel Dziepak #include "scheduler_common.h" 20d287274dSPawel Dziepak #include "scheduler_modes.h" 2196dcc73bSPawel Dziepak #include "scheduler_profiler.h" 22d287274dSPawel Dziepak 23d287274dSPawel Dziepak 24d287274dSPawel Dziepak namespace Scheduler { 25d287274dSPawel Dziepak 26d287274dSPawel Dziepak 2760e198f2SPawel Dziepak class DebugDumper; 2860e198f2SPawel Dziepak 29d287274dSPawel Dziepak struct ThreadData; 30e1e7235cSPawel Dziepak class ThreadProcessing; 31d287274dSPawel Dziepak 32d287274dSPawel Dziepak struct CPUEntry; 33d287274dSPawel Dziepak struct CoreEntry; 34d287274dSPawel Dziepak struct PackageEntry; 35d287274dSPawel Dziepak 36d287274dSPawel Dziepak // The run queues. Holds the threads ready to run ordered by priority. 37d287274dSPawel Dziepak // One queue per schedulable target per core. Additionally, each 38d287274dSPawel Dziepak // logical processor has its sPinnedRunQueues used for scheduling 39d287274dSPawel Dziepak // pinned threads. 40d287274dSPawel Dziepak class ThreadRunQueue : public RunQueue<ThreadData, THREAD_MAX_SET_PRIORITY> { 41d287274dSPawel Dziepak public: 42d287274dSPawel Dziepak void Dump() const; 43d287274dSPawel Dziepak }; 44d287274dSPawel Dziepak 45*ef8e55a1SPawel Dziepak class CPUEntry : public HeapLinkImpl<CPUEntry, int32> { 46a08b40d4SPawel Dziepak public: 47d287274dSPawel Dziepak CPUEntry(); 48d287274dSPawel Dziepak 49a08b40d4SPawel Dziepak void Init(int32 id, CoreEntry* core); 50a08b40d4SPawel Dziepak 51a08b40d4SPawel Dziepak inline int32 ID() const { return fCPUNumber; } 52a08b40d4SPawel Dziepak inline CoreEntry* Core() const { return fCore; } 53a08b40d4SPawel Dziepak 54a08b40d4SPawel Dziepak void Start(); 55a08b40d4SPawel Dziepak void Stop(); 56a08b40d4SPawel Dziepak 57a08b40d4SPawel Dziepak inline void EnterScheduler(); 58a08b40d4SPawel Dziepak inline void ExitScheduler(); 59a08b40d4SPawel Dziepak 60a08b40d4SPawel Dziepak inline void LockScheduler(); 61a08b40d4SPawel Dziepak inline void UnlockScheduler(); 62a08b40d4SPawel Dziepak 63a08b40d4SPawel Dziepak void PushFront(ThreadData* thread, 64a08b40d4SPawel Dziepak int32 priority); 65a08b40d4SPawel Dziepak void PushBack(ThreadData* thread, 66a08b40d4SPawel Dziepak int32 priority); 67a08b40d4SPawel Dziepak void Remove(ThreadData* thread); 68a08b40d4SPawel Dziepak inline ThreadData* PeekThread() const; 69a08b40d4SPawel Dziepak ThreadData* PeekIdleThread() const; 70a08b40d4SPawel Dziepak 71d287274dSPawel Dziepak void UpdatePriority(int32 priority); 72d287274dSPawel Dziepak 73a08b40d4SPawel Dziepak inline int32 GetLoad() const { return fLoad; } 74d287274dSPawel Dziepak void ComputeLoad(); 75d287274dSPawel Dziepak 76d287274dSPawel Dziepak ThreadData* ChooseNextThread(ThreadData* oldThread, 77d287274dSPawel Dziepak bool putAtBack); 78d287274dSPawel Dziepak 79d287274dSPawel Dziepak void TrackActivity(ThreadData* oldThreadData, 80d287274dSPawel Dziepak ThreadData* nextThreadData); 81d287274dSPawel Dziepak 82a08b40d4SPawel Dziepak static inline CPUEntry* GetCPU(int32 cpu); 83a08b40d4SPawel Dziepak 84a08b40d4SPawel Dziepak private: 85a08b40d4SPawel Dziepak inline void _RequestPerformanceLevel( 86a08b40d4SPawel Dziepak ThreadData* threadData); 87a08b40d4SPawel Dziepak 88d287274dSPawel Dziepak int32 fCPUNumber; 89d287274dSPawel Dziepak CoreEntry* fCore; 90d287274dSPawel Dziepak 91d287274dSPawel Dziepak rw_spinlock fSchedulerModeLock; 92d287274dSPawel Dziepak 93d287274dSPawel Dziepak ThreadRunQueue fRunQueue; 94d287274dSPawel Dziepak 95d287274dSPawel Dziepak int32 fLoad; 96d287274dSPawel Dziepak 97d287274dSPawel Dziepak bigtime_t fMeasureActiveTime; 98d287274dSPawel Dziepak bigtime_t fMeasureTime; 99d287274dSPawel Dziepak 100a08b40d4SPawel Dziepak friend class DebugDumper; 101d287274dSPawel Dziepak } CACHE_LINE_ALIGN; 102d287274dSPawel Dziepak 103*ef8e55a1SPawel Dziepak class CPUPriorityHeap : public Heap<CPUEntry, int32> { 104d287274dSPawel Dziepak public: 105d287274dSPawel Dziepak CPUPriorityHeap() { } 106d287274dSPawel Dziepak CPUPriorityHeap(int32 cpuCount); 107d287274dSPawel Dziepak 108d287274dSPawel Dziepak void Dump(); 109d287274dSPawel Dziepak }; 110d287274dSPawel Dziepak 111e1e7235cSPawel Dziepak class CoreEntry : public MinMaxHeapLinkImpl<CoreEntry, int32>, 112e1e7235cSPawel Dziepak public DoublyLinkedListLinkImpl<CoreEntry> { 113e1e7235cSPawel Dziepak public: 114d287274dSPawel Dziepak CoreEntry(); 115d287274dSPawel Dziepak 116e1e7235cSPawel Dziepak void Init(int32 id, PackageEntry* package); 117e1e7235cSPawel Dziepak 118e1e7235cSPawel Dziepak inline int32 ID() const { return fCoreID; } 119e1e7235cSPawel Dziepak inline PackageEntry* Package() const { return fPackage; } 120e1e7235cSPawel Dziepak inline int32 CPUCount() const 121e1e7235cSPawel Dziepak { return fCPUCount; } 122e1e7235cSPawel Dziepak 123e1e7235cSPawel Dziepak inline void LockCPUHeap(); 124e1e7235cSPawel Dziepak inline void UnlockCPUHeap(); 125e1e7235cSPawel Dziepak 126e1e7235cSPawel Dziepak inline CPUPriorityHeap* CPUHeap(); 127e1e7235cSPawel Dziepak 128e1e7235cSPawel Dziepak inline int32 ThreadCount() const 129e1e7235cSPawel Dziepak { return fThreadCount; } 130e1e7235cSPawel Dziepak 131e1e7235cSPawel Dziepak inline void LockRunQueue(); 132e1e7235cSPawel Dziepak inline void UnlockRunQueue(); 133e1e7235cSPawel Dziepak 134e1e7235cSPawel Dziepak void PushFront(ThreadData* thread, 135e1e7235cSPawel Dziepak int32 priority); 136e1e7235cSPawel Dziepak void PushBack(ThreadData* thread, 137e1e7235cSPawel Dziepak int32 priority); 138b24ea642SPawel Dziepak void Remove(ThreadData* thread); 139e1e7235cSPawel Dziepak inline ThreadData* PeekThread() const; 140e1e7235cSPawel Dziepak 141e1e7235cSPawel Dziepak inline bigtime_t GetActiveTime() const; 142e1e7235cSPawel Dziepak inline void IncreaseActiveTime( 143e1e7235cSPawel Dziepak bigtime_t activeTime); 144e1e7235cSPawel Dziepak 145d287274dSPawel Dziepak inline int32 GetLoad() const; 146e1e7235cSPawel Dziepak void UpdateLoad(int32 delta); 147e1e7235cSPawel Dziepak 148e1e7235cSPawel Dziepak inline int32 StarvationCounter() const; 149e1e7235cSPawel Dziepak 150*ef8e55a1SPawel Dziepak inline void CPUGoesIdle(CPUEntry* cpu); 151*ef8e55a1SPawel Dziepak inline void CPUWakesUp(CPUEntry* cpu); 152*ef8e55a1SPawel Dziepak 153e1e7235cSPawel Dziepak void AddCPU(CPUEntry* cpu); 154e1e7235cSPawel Dziepak void RemoveCPU(CPUEntry* cpu, 155e1e7235cSPawel Dziepak ThreadProcessing& 156e1e7235cSPawel Dziepak threadPostProcessing); 157d287274dSPawel Dziepak 158d287274dSPawel Dziepak static inline CoreEntry* GetCore(int32 cpu); 159d287274dSPawel Dziepak 160e1e7235cSPawel Dziepak private: 161e1e7235cSPawel Dziepak static void _UnassignThread(Thread* thread, 162e1e7235cSPawel Dziepak void* core); 163e1e7235cSPawel Dziepak 164d287274dSPawel Dziepak int32 fCoreID; 165d287274dSPawel Dziepak PackageEntry* fPackage; 166d287274dSPawel Dziepak 167d287274dSPawel Dziepak int32 fCPUCount; 168*ef8e55a1SPawel Dziepak int32 fCPUIdleCount; 169d287274dSPawel Dziepak CPUPriorityHeap fCPUHeap; 170d287274dSPawel Dziepak spinlock fCPULock; 171d287274dSPawel Dziepak 172d287274dSPawel Dziepak int32 fStarvationCounter; 173d287274dSPawel Dziepak DoublyLinkedList<ThreadData> fThreadList; 174d287274dSPawel Dziepak 175d287274dSPawel Dziepak int32 fThreadCount; 176d287274dSPawel Dziepak ThreadRunQueue fRunQueue; 177d287274dSPawel Dziepak spinlock fQueueLock; 178d287274dSPawel Dziepak 179d287274dSPawel Dziepak bigtime_t fActiveTime; 180e1e7235cSPawel Dziepak mutable seqlock fActiveTimeLock; 181d287274dSPawel Dziepak 182d287274dSPawel Dziepak int32 fLoad; 183d287274dSPawel Dziepak bool fHighLoad; 184e1e7235cSPawel Dziepak 185e1e7235cSPawel Dziepak friend class DebugDumper; 186d287274dSPawel Dziepak } CACHE_LINE_ALIGN; 187d287274dSPawel Dziepak 188e1e7235cSPawel Dziepak class CoreRunQueueLocking { 189e1e7235cSPawel Dziepak public: 190e1e7235cSPawel Dziepak inline bool Lock(CoreEntry* core) 191e1e7235cSPawel Dziepak { 192e1e7235cSPawel Dziepak core->LockRunQueue(); 193e1e7235cSPawel Dziepak return true; 194e1e7235cSPawel Dziepak } 195e1e7235cSPawel Dziepak 196e1e7235cSPawel Dziepak inline void Unlock(CoreEntry* core) 197e1e7235cSPawel Dziepak { 198e1e7235cSPawel Dziepak core->UnlockRunQueue(); 199e1e7235cSPawel Dziepak } 200e1e7235cSPawel Dziepak }; 201e1e7235cSPawel Dziepak 202e1e7235cSPawel Dziepak typedef AutoLocker<CoreEntry, CoreRunQueueLocking> CoreRunQueueLocker; 203e1e7235cSPawel Dziepak 204e1e7235cSPawel Dziepak class CoreCPUHeapLocking { 205e1e7235cSPawel Dziepak public: 206e1e7235cSPawel Dziepak inline bool Lock(CoreEntry* core) 207e1e7235cSPawel Dziepak { 208e1e7235cSPawel Dziepak core->LockCPUHeap(); 209e1e7235cSPawel Dziepak return true; 210e1e7235cSPawel Dziepak } 211e1e7235cSPawel Dziepak 212e1e7235cSPawel Dziepak inline void Unlock(CoreEntry* core) 213e1e7235cSPawel Dziepak { 214e1e7235cSPawel Dziepak core->UnlockCPUHeap(); 215e1e7235cSPawel Dziepak } 216e1e7235cSPawel Dziepak }; 217e1e7235cSPawel Dziepak 218e1e7235cSPawel Dziepak typedef AutoLocker<CoreEntry, CoreCPUHeapLocking> CoreCPUHeapLocker; 219e1e7235cSPawel Dziepak 220d287274dSPawel Dziepak class CoreLoadHeap : public MinMaxHeap<CoreEntry, int32> { 221d287274dSPawel Dziepak public: 222d287274dSPawel Dziepak CoreLoadHeap() { } 223d287274dSPawel Dziepak CoreLoadHeap(int32 coreCount); 224d287274dSPawel Dziepak 225d287274dSPawel Dziepak void Dump(); 226d287274dSPawel Dziepak }; 227d287274dSPawel Dziepak 228d287274dSPawel Dziepak // gPackageEntries are used to decide which core should be woken up from the 229d287274dSPawel Dziepak // idle state. When aiming for performance we should use as many packages as 230d287274dSPawel Dziepak // possible with as little cores active in each package as possible (so that the 231d287274dSPawel Dziepak // package can enter any boost mode if it has one and the active core have more 232d287274dSPawel Dziepak // of the shared cache for themselves. If power saving is the main priority we 233d287274dSPawel Dziepak // should keep active cores on as little packages as possible (so that other 234d287274dSPawel Dziepak // packages can go to the deep state of sleep). The heap stores only packages 235d287274dSPawel Dziepak // with at least one core active and one core idle. The packages with all cores 236d287274dSPawel Dziepak // idle are stored in gPackageIdleList (in LIFO manner). 23760e198f2SPawel Dziepak class PackageEntry : public DoublyLinkedListLinkImpl<PackageEntry> { 23860e198f2SPawel Dziepak public: 239d287274dSPawel Dziepak PackageEntry(); 240d287274dSPawel Dziepak 24160e198f2SPawel Dziepak void Init(int32 id); 24260e198f2SPawel Dziepak 24360e198f2SPawel Dziepak inline void CoreGoesIdle(CoreEntry* core); 24460e198f2SPawel Dziepak inline void CoreWakesUp(CoreEntry* core); 24560e198f2SPawel Dziepak 24660e198f2SPawel Dziepak inline CoreEntry* GetIdleCore() const; 24760e198f2SPawel Dziepak 24860e198f2SPawel Dziepak void AddIdleCore(CoreEntry* core); 24960e198f2SPawel Dziepak void RemoveIdleCore(CoreEntry* core); 25060e198f2SPawel Dziepak 25160e198f2SPawel Dziepak static inline PackageEntry* GetMostIdlePackage(); 25260e198f2SPawel Dziepak static inline PackageEntry* GetLeastIdlePackage(); 25360e198f2SPawel Dziepak 25460e198f2SPawel Dziepak private: 255d287274dSPawel Dziepak int32 fPackageID; 256d287274dSPawel Dziepak 257d287274dSPawel Dziepak DoublyLinkedList<CoreEntry> fIdleCores; 258d287274dSPawel Dziepak int32 fIdleCoreCount; 259d287274dSPawel Dziepak int32 fCoreCount; 260d287274dSPawel Dziepak rw_spinlock fCoreLock; 26160e198f2SPawel Dziepak 26260e198f2SPawel Dziepak friend class DebugDumper; 263d287274dSPawel Dziepak } CACHE_LINE_ALIGN; 264d287274dSPawel Dziepak typedef DoublyLinkedList<PackageEntry> IdlePackageList; 265d287274dSPawel Dziepak 266d287274dSPawel Dziepak extern CPUEntry* gCPUEntries; 267d287274dSPawel Dziepak 268d287274dSPawel Dziepak extern CoreEntry* gCoreEntries; 269d287274dSPawel Dziepak extern CoreLoadHeap gCoreLoadHeap; 270d287274dSPawel Dziepak extern CoreLoadHeap gCoreHighLoadHeap; 271d287274dSPawel Dziepak extern rw_spinlock gCoreHeapsLock; 272d287274dSPawel Dziepak extern int32 gCoreCount; 273d287274dSPawel Dziepak 274d287274dSPawel Dziepak extern PackageEntry* gPackageEntries; 275d287274dSPawel Dziepak extern IdlePackageList gIdlePackageList; 276d287274dSPawel Dziepak extern rw_spinlock gIdlePackageLock; 277d287274dSPawel Dziepak extern int32 gPackageCount; 278d287274dSPawel Dziepak 279d287274dSPawel Dziepak 280e1e7235cSPawel Dziepak inline void 281a08b40d4SPawel Dziepak CPUEntry::EnterScheduler() 282a08b40d4SPawel Dziepak { 28396dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 284a08b40d4SPawel Dziepak acquire_read_spinlock(&fSchedulerModeLock); 285a08b40d4SPawel Dziepak } 286a08b40d4SPawel Dziepak 287a08b40d4SPawel Dziepak 288a08b40d4SPawel Dziepak inline void 289a08b40d4SPawel Dziepak CPUEntry::ExitScheduler() 290a08b40d4SPawel Dziepak { 29196dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 292a08b40d4SPawel Dziepak release_read_spinlock(&fSchedulerModeLock); 293a08b40d4SPawel Dziepak } 294a08b40d4SPawel Dziepak 295a08b40d4SPawel Dziepak 296a08b40d4SPawel Dziepak inline void 297a08b40d4SPawel Dziepak CPUEntry::LockScheduler() 298a08b40d4SPawel Dziepak { 29996dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 300a08b40d4SPawel Dziepak acquire_write_spinlock(&fSchedulerModeLock); 301a08b40d4SPawel Dziepak } 302a08b40d4SPawel Dziepak 303a08b40d4SPawel Dziepak 304a08b40d4SPawel Dziepak inline void 305a08b40d4SPawel Dziepak CPUEntry::UnlockScheduler() 306a08b40d4SPawel Dziepak { 30796dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 308a08b40d4SPawel Dziepak release_write_spinlock(&fSchedulerModeLock); 309a08b40d4SPawel Dziepak } 310a08b40d4SPawel Dziepak 311a08b40d4SPawel Dziepak 312a08b40d4SPawel Dziepak /* static */ inline CPUEntry* 313a08b40d4SPawel Dziepak CPUEntry::GetCPU(int32 cpu) 314a08b40d4SPawel Dziepak { 31596dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 316a08b40d4SPawel Dziepak return &gCPUEntries[cpu]; 317a08b40d4SPawel Dziepak } 318a08b40d4SPawel Dziepak 319a08b40d4SPawel Dziepak 320a08b40d4SPawel Dziepak inline void 321e1e7235cSPawel Dziepak CoreEntry::LockCPUHeap() 322e1e7235cSPawel Dziepak { 32396dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 324e1e7235cSPawel Dziepak acquire_spinlock(&fCPULock); 325e1e7235cSPawel Dziepak } 326e1e7235cSPawel Dziepak 327e1e7235cSPawel Dziepak 328e1e7235cSPawel Dziepak inline void 329e1e7235cSPawel Dziepak CoreEntry::UnlockCPUHeap() 330e1e7235cSPawel Dziepak { 33196dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 332e1e7235cSPawel Dziepak release_spinlock(&fCPULock); 333e1e7235cSPawel Dziepak } 334e1e7235cSPawel Dziepak 335e1e7235cSPawel Dziepak 336e1e7235cSPawel Dziepak inline CPUPriorityHeap* 337e1e7235cSPawel Dziepak CoreEntry::CPUHeap() 338e1e7235cSPawel Dziepak { 33996dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 340e1e7235cSPawel Dziepak return &fCPUHeap; 341e1e7235cSPawel Dziepak } 342e1e7235cSPawel Dziepak 343e1e7235cSPawel Dziepak 344e1e7235cSPawel Dziepak inline void 345e1e7235cSPawel Dziepak CoreEntry::LockRunQueue() 346e1e7235cSPawel Dziepak { 34796dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 348e1e7235cSPawel Dziepak acquire_spinlock(&fQueueLock); 349e1e7235cSPawel Dziepak } 350e1e7235cSPawel Dziepak 351e1e7235cSPawel Dziepak 352e1e7235cSPawel Dziepak inline void 353e1e7235cSPawel Dziepak CoreEntry::UnlockRunQueue() 354e1e7235cSPawel Dziepak { 35596dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 356e1e7235cSPawel Dziepak release_spinlock(&fQueueLock); 357e1e7235cSPawel Dziepak } 358e1e7235cSPawel Dziepak 359e1e7235cSPawel Dziepak 360e1e7235cSPawel Dziepak inline void 361e1e7235cSPawel Dziepak CoreEntry::IncreaseActiveTime(bigtime_t activeTime) 362e1e7235cSPawel Dziepak { 36396dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 364e1e7235cSPawel Dziepak WriteSequentialLocker _(fActiveTimeLock); 365e1e7235cSPawel Dziepak fActiveTime += activeTime; 366e1e7235cSPawel Dziepak } 367e1e7235cSPawel Dziepak 368e1e7235cSPawel Dziepak 369e1e7235cSPawel Dziepak inline bigtime_t 370e1e7235cSPawel Dziepak CoreEntry::GetActiveTime() const 371e1e7235cSPawel Dziepak { 37296dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 373e1e7235cSPawel Dziepak 37496dcc73bSPawel Dziepak bigtime_t activeTime; 375e1e7235cSPawel Dziepak uint32 count; 376e1e7235cSPawel Dziepak do { 377e1e7235cSPawel Dziepak count = acquire_read_seqlock(&fActiveTimeLock); 378e1e7235cSPawel Dziepak activeTime = fActiveTime; 379e1e7235cSPawel Dziepak } while (!release_read_seqlock(&fActiveTimeLock, count)); 380e1e7235cSPawel Dziepak return activeTime; 381e1e7235cSPawel Dziepak } 382e1e7235cSPawel Dziepak 383e1e7235cSPawel Dziepak 384d287274dSPawel Dziepak inline int32 385d287274dSPawel Dziepak CoreEntry::GetLoad() const 386d287274dSPawel Dziepak { 38796dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 38896dcc73bSPawel Dziepak 389d287274dSPawel Dziepak ASSERT(fCPUCount >= 0); 390d287274dSPawel Dziepak return fLoad / fCPUCount; 391d287274dSPawel Dziepak } 392d287274dSPawel Dziepak 393d287274dSPawel Dziepak 394e1e7235cSPawel Dziepak inline int32 395e1e7235cSPawel Dziepak CoreEntry::StarvationCounter() const 396e1e7235cSPawel Dziepak { 39796dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 398e1e7235cSPawel Dziepak return fStarvationCounter; 399e1e7235cSPawel Dziepak } 400e1e7235cSPawel Dziepak 401e1e7235cSPawel Dziepak 402d287274dSPawel Dziepak /* static */ inline CoreEntry* 403d287274dSPawel Dziepak CoreEntry::GetCore(int32 cpu) 404d287274dSPawel Dziepak { 40596dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 406a08b40d4SPawel Dziepak return gCPUEntries[cpu].Core(); 407d287274dSPawel Dziepak } 408d287274dSPawel Dziepak 409d287274dSPawel Dziepak 41060e198f2SPawel Dziepak inline CoreEntry* 41160e198f2SPawel Dziepak PackageEntry::GetIdleCore() const 41260e198f2SPawel Dziepak { 41396dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 41460e198f2SPawel Dziepak return fIdleCores.Last(); 41560e198f2SPawel Dziepak } 41660e198f2SPawel Dziepak 41760e198f2SPawel Dziepak 41860e198f2SPawel Dziepak /* static */ inline PackageEntry* 41960e198f2SPawel Dziepak PackageEntry::GetMostIdlePackage() 42060e198f2SPawel Dziepak { 42196dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 42296dcc73bSPawel Dziepak 42360e198f2SPawel Dziepak PackageEntry* current = &gPackageEntries[0]; 42460e198f2SPawel Dziepak for (int32 i = 1; i < gPackageCount; i++) { 42560e198f2SPawel Dziepak if (gPackageEntries[i].fIdleCoreCount > current->fIdleCoreCount) 42660e198f2SPawel Dziepak current = &gPackageEntries[i]; 42760e198f2SPawel Dziepak } 42860e198f2SPawel Dziepak 42960e198f2SPawel Dziepak if (current->fIdleCoreCount == 0) 43060e198f2SPawel Dziepak return NULL; 43160e198f2SPawel Dziepak 43260e198f2SPawel Dziepak return current; 43360e198f2SPawel Dziepak } 43460e198f2SPawel Dziepak 43560e198f2SPawel Dziepak 43660e198f2SPawel Dziepak /* static */ inline PackageEntry* 43760e198f2SPawel Dziepak PackageEntry::GetLeastIdlePackage() 43860e198f2SPawel Dziepak { 43996dcc73bSPawel Dziepak SCHEDULER_ENTER_FUNCTION(); 44096dcc73bSPawel Dziepak 44160e198f2SPawel Dziepak PackageEntry* package = NULL; 44260e198f2SPawel Dziepak 44360e198f2SPawel Dziepak for (int32 i = 0; i < gPackageCount; i++) { 44460e198f2SPawel Dziepak PackageEntry* current = &gPackageEntries[i]; 44560e198f2SPawel Dziepak 44660e198f2SPawel Dziepak int32 currentIdleCoreCount = current->fIdleCoreCount; 44760e198f2SPawel Dziepak if (currentIdleCoreCount != 0 && (package == NULL 44860e198f2SPawel Dziepak || currentIdleCoreCount < package->fIdleCoreCount)) { 44960e198f2SPawel Dziepak package = current; 45060e198f2SPawel Dziepak } 45160e198f2SPawel Dziepak } 45260e198f2SPawel Dziepak 45360e198f2SPawel Dziepak return package; 45460e198f2SPawel Dziepak } 45560e198f2SPawel Dziepak 45660e198f2SPawel Dziepak 457d287274dSPawel Dziepak } // namespace Scheduler 458d287274dSPawel Dziepak 459d287274dSPawel Dziepak 460d287274dSPawel Dziepak #endif // KERNEL_SCHEDULER_CPU_H 461d287274dSPawel Dziepak 462