scheduler: Encapsulate PackageEntry fields

Apart from the refactoring this commit takes the opportunity and removes
unnecessary read locks when choosing a package and a core from idle lists.
The data structures are accessed in a thread safe way and it does not really
matter whether the obtained data becomes outdated just when we release the
lock or during our search for the appropriate package/core.
This commit is contained in:
Pawel Dziepak
2013-12-23 00:56:44 +01:00
parent cf21c40b50
commit 60e198f2cb
8 changed files with 224 additions and 136 deletions
+6 -26
View File
@@ -19,7 +19,7 @@ const bigtime_t kCacheExpire = 100000;
static void static void
switch_to_mode(void) switch_to_mode()
{ {
} }
@@ -35,7 +35,7 @@ has_cache_expired(const ThreadData* threadData)
{ {
ASSERT(!gSingleCore); ASSERT(!gSingleCore);
CoreEntry* core = threadData->GetCore(); CoreEntry* core = threadData->Core();
bigtime_t activeTime; bigtime_t activeTime;
uint32 count; uint32 count;
@@ -48,39 +48,19 @@ has_cache_expired(const ThreadData* threadData)
} }
static inline PackageEntry*
get_most_idle_package(void)
{
PackageEntry* current = &gPackageEntries[0];
for (int32 i = 1; i < gPackageCount; i++) {
if (gPackageEntries[i].fIdleCoreCount > current->fIdleCoreCount)
current = &gPackageEntries[i];
}
if (current->fIdleCoreCount == 0)
return NULL;
return current;
}
static CoreEntry* static CoreEntry*
choose_core(const ThreadData* /* threadData */) choose_core(const ThreadData* /* threadData */)
{ {
ReadSpinLocker locker(gIdlePackageLock);
// wake new package // wake new package
PackageEntry* package = gIdlePackageList.Last(); PackageEntry* package = gIdlePackageList.Last();
if (package == NULL) { if (package == NULL) {
// wake new core // wake new core
package = get_most_idle_package(); package = PackageEntry::GetMostIdlePackage();
} }
locker.Unlock();
CoreEntry* core = NULL; CoreEntry* core = NULL;
if (package != NULL) { if (package != NULL)
ReadSpinLocker _(package->fCoreLock); core = package->GetIdleCore();
core = package->fIdleCores.Last();
}
if (core == NULL) { if (core == NULL) {
ReadSpinLocker coreLocker(gCoreHeapsLock); ReadSpinLocker coreLocker(gCoreHeapsLock);
@@ -98,7 +78,7 @@ choose_core(const ThreadData* /* threadData */)
static bool static bool
should_rebalance(const ThreadData* threadData) should_rebalance(const ThreadData* threadData)
{ {
int32 coreLoad = threadData->GetCore()->GetLoad(); int32 coreLoad = threadData->Core()->GetLoad();
// If the thread produces more than 50% of the load, leave it here. In // If the thread produces more than 50% of the load, leave it here. In
// such situation it is better to move other threads away. // such situation it is better to move other threads away.
+9 -21
View File
@@ -22,7 +22,7 @@ static CoreEntry* sSmallTaskCore;
static void static void
switch_to_mode(void) switch_to_mode()
{ {
sSmallTaskCore = NULL; sSmallTaskCore = NULL;
} }
@@ -46,7 +46,7 @@ has_cache_expired(const ThreadData* threadData)
static CoreEntry* static CoreEntry*
choose_small_task_core(void) choose_small_task_core()
{ {
ReadSpinLocker locker(gCoreHeapsLock); ReadSpinLocker locker(gCoreHeapsLock);
CoreEntry* core = gCoreLoadHeap.PeekMaximum(); CoreEntry* core = gCoreLoadHeap.PeekMaximum();
@@ -64,27 +64,15 @@ choose_small_task_core(void)
static CoreEntry* static CoreEntry*
choose_idle_core(void) choose_idle_core()
{ {
PackageEntry* package = NULL; PackageEntry* package = PackageEntry::GetLeastIdlePackage();
for (int32 i = 0; i < gPackageCount; i++) { if (package == NULL)
PackageEntry* current = &gPackageEntries[i];
if (current->fIdleCoreCount != 0 && (package == NULL
|| current->fIdleCoreCount < package->fIdleCoreCount)) {
package = current;
}
}
if (package == NULL) {
ReadSpinLocker _(gIdlePackageLock);
package = gIdlePackageList.Last(); package = gIdlePackageList.Last();
}
if (package != NULL) { if (package != NULL)
ReadSpinLocker _(package->fCoreLock); return package->GetIdleCore();
return package->fIdleCores.Last();
}
return NULL; return NULL;
} }
@@ -125,7 +113,7 @@ should_rebalance(const ThreadData* threadData)
{ {
ASSERT(!gSingleCore); ASSERT(!gSingleCore);
CoreEntry* core = threadData->GetCore(); CoreEntry* core = threadData->Core();
int32 coreLoad = core->GetLoad(); int32 coreLoad = core->GetLoad();
if (coreLoad > kHighLoad) { if (coreLoad > kHighLoad) {
@@ -161,7 +149,7 @@ should_rebalance(const ThreadData* threadData)
static inline void static inline void
pack_irqs(void) pack_irqs()
{ {
CoreEntry* smallTaskCore = atomic_pointer_get(&sSmallTaskCore); CoreEntry* smallTaskCore = atomic_pointer_get(&sSmallTaskCore);
if (smallTaskCore == NULL) if (smallTaskCore == NULL)
+42 -37
View File
@@ -61,7 +61,7 @@ public:
} }
}; };
class BigSchedulerLocking { class InterruptsBigSchedulerLocking {
public: public:
bool Lock(int* lockable) bool Lock(int* lockable)
{ {
@@ -80,11 +80,11 @@ public:
}; };
class InterruptsBigSchedulerLocker : class InterruptsBigSchedulerLocker :
public AutoLocker<int, BigSchedulerLocking> { public AutoLocker<int, InterruptsBigSchedulerLocking> {
public: public:
InterruptsBigSchedulerLocker() InterruptsBigSchedulerLocker()
: :
AutoLocker<int, BigSchedulerLocking>(&fState, false, true) AutoLocker<int, InterruptsBigSchedulerLocking>(&fState, false, true)
{ {
} }
@@ -157,10 +157,10 @@ enqueue(Thread* thread, bool newOne)
targetCPU = &gCPUEntries[thread->previous_cpu->cpu_num]; targetCPU = &gCPUEntries[thread->previous_cpu->cpu_num];
} else if (gSingleCore) } else if (gSingleCore)
targetCore = &gCoreEntries[0]; targetCore = &gCoreEntries[0];
else if (threadData->GetCore() != NULL else if (threadData->Core() != NULL
&& (!newOne || !threadData->HasCacheExpired()) && (!newOne || !threadData->HasCacheExpired())
&& !threadData->ShouldRebalance()) { && !threadData->ShouldRebalance()) {
targetCore = threadData->GetCore(); targetCore = threadData->Core();
} }
bool rescheduleNeeded = threadData->ChooseCoreAndCPU(targetCore, targetCPU); bool rescheduleNeeded = threadData->ChooseCoreAndCPU(targetCore, targetCPU);
@@ -194,7 +194,12 @@ enqueue(Thread* thread, bool newOne)
void void
scheduler_enqueue_in_run_queue(Thread *thread) scheduler_enqueue_in_run_queue(Thread *thread)
{ {
InterruptsSchedulerModeLocker _; #if KDEBUG
if (are_interrupts_enabled())
panic("scheduler_enqueue_in_run_queue: called with interrupts enabled");
#endif
SchedulerModeLocker _;
TRACE("enqueueing new thread %ld with static priority %ld\n", thread->id, TRACE("enqueueing new thread %ld with static priority %ld\n", thread->id,
thread->priority); thread->priority);
@@ -213,6 +218,11 @@ scheduler_enqueue_in_run_queue(Thread *thread)
int32 int32
scheduler_set_thread_priority(Thread *thread, int32 priority) scheduler_set_thread_priority(Thread *thread, int32 priority)
{ {
#if KDEBUG
if (!are_interrupts_enabled())
panic("scheduler_set_thread_priority: called with interrupts disabled");
#endif
InterruptsSpinLocker _(thread->scheduler_lock); InterruptsSpinLocker _(thread->scheduler_lock);
SchedulerModeLocker modeLocker; SchedulerModeLocker modeLocker;
@@ -230,12 +240,12 @@ scheduler_set_thread_priority(Thread *thread, int32 priority)
if (thread->state != B_THREAD_READY) { if (thread->state != B_THREAD_READY) {
if (thread->state == B_THREAD_RUNNING) { if (thread->state == B_THREAD_RUNNING) {
ASSERT(threadData->GetCore() != NULL); ASSERT(threadData->Core() != NULL);
ASSERT(thread->cpu != NULL); ASSERT(thread->cpu != NULL);
CPUEntry* cpu = &gCPUEntries[thread->cpu->cpu_num]; CPUEntry* cpu = &gCPUEntries[thread->cpu->cpu_num];
SpinLocker coreLocker(threadData->GetCore()->fCPULock); SpinLocker coreLocker(threadData->Core()->fCPULock);
cpu->UpdatePriority(priority); cpu->UpdatePriority(priority);
} }
@@ -497,7 +507,7 @@ reschedule(int32 nextState)
NotifySchedulerListeners(&SchedulerListener::ThreadScheduled, NotifySchedulerListeners(&SchedulerListener::ThreadScheduled,
oldThread, nextThread); oldThread, nextThread);
ASSERT(nextThreadData->GetCore() == core); ASSERT(nextThreadData->Core() == core);
nextThread->state = B_THREAD_RUNNING; nextThread->state = B_THREAD_RUNNING;
// update CPU heap // update CPU heap
@@ -540,6 +550,11 @@ reschedule(int32 nextState)
void void
scheduler_reschedule(int32 nextState) scheduler_reschedule(int32 nextState)
{ {
#if KDEBUG
if (are_interrupts_enabled())
panic("scheduler_reschedule: called with interrupts enabled");
#endif
if (!sSchedulerEnabled) { if (!sSchedulerEnabled) {
Thread* thread = thread_get_current_thread(); Thread* thread = thread_get_current_thread();
if (thread != NULL && nextState != B_THREAD_READY) if (thread != NULL && nextState != B_THREAD_READY)
@@ -588,7 +603,7 @@ scheduler_on_thread_destroy(Thread* thread)
thread. Interrupts must be disabled and will be disabled when returning. thread. Interrupts must be disabled and will be disabled when returning.
*/ */
void void
scheduler_start(void) scheduler_start()
{ {
InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock); InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
@@ -621,7 +636,7 @@ unassign_thread(Thread* thread, void* data)
{ {
CoreEntry* core = static_cast<CoreEntry*>(data); CoreEntry* core = static_cast<CoreEntry*>(data);
if (thread->scheduler_data->GetCore() == core if (thread->scheduler_data->Core() == core
&& thread->pinned_to_cpu == 0) { && thread->pinned_to_cpu == 0) {
thread->scheduler_data->UnassignCore(); thread->scheduler_data->UnassignCore();
} }
@@ -631,6 +646,11 @@ unassign_thread(Thread* thread, void* data)
void void
scheduler_set_cpu_enabled(int32 cpuID, bool enabled) scheduler_set_cpu_enabled(int32 cpuID, bool enabled)
{ {
#if KDEBUG
if (are_interrupts_enabled())
panic("scheduler_set_cpu_enabled: called with interrupts enabled");
#endif
dprintf("scheduler: %s CPU %" B_PRId32 "\n", dprintf("scheduler: %s CPU %" B_PRId32 "\n",
enabled ? "enabling" : "disabling", cpuID); enabled ? "enabling" : "disabling", cpuID);
@@ -667,12 +687,7 @@ scheduler_set_cpu_enabled(int32 cpuID, bool enabled)
gCoreLoadHeap.RemoveMinimum(); gCoreLoadHeap.RemoveMinimum();
} }
package->fIdleCores.Remove(core); package->RemoveIdleCore(core);
package->fIdleCoreCount--;
package->fCoreCount--;
if (package->fCoreCount == 0)
gIdlePackageList.Remove(package);
// get rid of threads // get rid of threads
thread_map(unassign_thread, core); thread_map(unassign_thread, core);
@@ -689,7 +704,7 @@ scheduler_set_cpu_enabled(int32 cpuID, bool enabled)
threadData->fWentSleepCount = -1; threadData->fWentSleepCount = -1;
} }
ASSERT(threadData->GetCore() == NULL); ASSERT(threadData->Core() == NULL);
enqueue(threadData->GetThread(), false); enqueue(threadData->GetThread(), false);
} }
} else if (oldCPUCount == 0) { } else if (oldCPUCount == 0) {
@@ -701,12 +716,7 @@ scheduler_set_cpu_enabled(int32 cpuID, bool enabled)
core->fHighLoad = false; core->fHighLoad = false;
gCoreLoadHeap.Insert(core, 0); gCoreLoadHeap.Insert(core, 0);
package->fCoreCount++; package->AddIdleCore(core);
package->fIdleCoreCount++;
package->fIdleCores.Add(core);
if (package->fCoreCount == 1)
gIdlePackageList.Add(package);
} }
if (enabled) { if (enabled) {
@@ -846,11 +856,8 @@ init()
new(&gIdlePackageList) IdlePackageList; new(&gIdlePackageList) IdlePackageList;
for (int32 i = 0; i < packageCount; i++) { for (int32 i = 0; i < packageCount; i++)
gPackageEntries[i].fPackageID = i; gPackageEntries[i].Init(i);
gPackageEntries[i].fCoreCount = coreCount / packageCount;
gIdlePackageList.Insert(&gPackageEntries[i]);
}
for (int32 i = 0; i < coreCount; i++) { for (int32 i = 0; i < coreCount; i++) {
gCoreEntries[i].fCoreID = i; gCoreEntries[i].fCoreID = i;
@@ -869,10 +876,8 @@ init()
gCPUEntries[i].fCore = core; gCPUEntries[i].fCore = core;
core->fPackage = package; core->fPackage = package;
if (core->fCPUHeap.PeekMaximum() == NULL) { if (core->fCPUHeap.PeekMaximum() == NULL)
package->fIdleCoreCount++; package->AddIdleCore(core);
package->fIdleCores.Insert(core);
}
result = core->fCPUHeap.Insert(&gCPUEntries[i], B_IDLE_PRIORITY); result = core->fCPUHeap.Insert(&gCPUEntries[i], B_IDLE_PRIORITY);
if (result != B_OK) if (result != B_OK)
@@ -888,7 +893,7 @@ init()
void void
scheduler_init(void) scheduler_init()
{ {
int32 cpuCount = smp_get_num_cpus(); int32 cpuCount = smp_get_num_cpus();
dprintf("scheduler_init: found %" B_PRId32 " logical cpu%s and %" B_PRId32 dprintf("scheduler_init: found %" B_PRId32 " logical cpu%s and %" B_PRId32
@@ -914,7 +919,7 @@ scheduler_init(void)
void void
scheduler_enable_scheduling(void) scheduler_enable_scheduling()
{ {
sSchedulerEnabled = true; sSchedulerEnabled = true;
} }
@@ -972,7 +977,7 @@ _user_estimate_max_scheduling_latency(thread_id id)
BReference<Thread> threadReference(thread, true); BReference<Thread> threadReference(thread, true);
ThreadData* threadData = thread->scheduler_data; ThreadData* threadData = thread->scheduler_data;
CoreEntry* core = threadData->GetCore(); CoreEntry* core = threadData->Core();
if (core == NULL) if (core == NULL)
core = &gCoreEntries[get_random<int32>() % gCoreCount]; core = &gCoreEntries[get_random<int32>() % gCoreCount];
@@ -1003,7 +1008,7 @@ _user_set_scheduler_mode(int32 mode)
int32 int32
_user_get_scheduler_mode(void) _user_get_scheduler_mode()
{ {
return gCurrentModeID; return gCurrentModeID;
} }
@@ -45,7 +45,7 @@ const int kLoadDifference = kMaxLoad * 20 / 100;
extern bool gSingleCore; extern bool gSingleCore;
void init_debug_commands(void); void init_debug_commands();
} // namespace Scheduler } // namespace Scheduler
+102 -48
View File
@@ -16,6 +16,13 @@
using namespace Scheduler; using namespace Scheduler;
class Scheduler::DebugDumper {
public:
static void DumpIdleCoresInPackage(PackageEntry* package);
};
static CPUPriorityHeap sDebugCPUHeap; static CPUPriorityHeap sDebugCPUHeap;
static CoreLoadHeap sDebugCoreHeap; static CoreLoadHeap sDebugCoreHeap;
@@ -67,37 +74,10 @@ CPUEntry::UpdatePriority(int32 priority)
return; return;
PackageEntry* packageEntry = fCore->fPackage; PackageEntry* packageEntry = fCore->fPackage;
if (maxPriority == B_IDLE_PRIORITY) { if (maxPriority == B_IDLE_PRIORITY)
WriteSpinLocker _(packageEntry->fCoreLock); packageEntry->CoreGoesIdle(fCore);
else if (corePriority == B_IDLE_PRIORITY)
// core goes idle packageEntry->CoreWakesUp(fCore);
ASSERT(packageEntry->fIdleCoreCount >= 0);
ASSERT(packageEntry->fIdleCoreCount < packageEntry->fCoreCount);
packageEntry->fIdleCoreCount++;
packageEntry->fIdleCores.Add(fCore);
if (packageEntry->fIdleCoreCount == packageEntry->fCoreCount) {
// package goes idle
WriteSpinLocker _(gIdlePackageLock);
gIdlePackageList.Add(packageEntry);
}
} else if (corePriority == B_IDLE_PRIORITY) {
WriteSpinLocker _(packageEntry->fCoreLock);
// core wakes up
ASSERT(packageEntry->fIdleCoreCount > 0);
ASSERT(packageEntry->fIdleCoreCount <= packageEntry->fCoreCount);
packageEntry->fIdleCoreCount--;
packageEntry->fIdleCores.Remove(fCore);
if (packageEntry->fIdleCoreCount + 1 == packageEntry->fCoreCount) {
// package wakes up
WriteSpinLocker _(gIdlePackageLock);
gIdlePackageList.Remove(packageEntry);
}
}
} }
@@ -371,6 +351,94 @@ PackageEntry::PackageEntry()
} }
void
PackageEntry::Init(int32 id)
{
fPackageID = id;
}
inline void
PackageEntry::CoreGoesIdle(CoreEntry* core)
{
WriteSpinLocker _(fCoreLock);
ASSERT(fIdleCoreCount >= 0);
ASSERT(fIdleCoreCount < fCoreCount);
fIdleCoreCount++;
fIdleCores.Add(core);
if (fIdleCoreCount == fCoreCount) {
// package goes idle
WriteSpinLocker _(gIdlePackageLock);
gIdlePackageList.Add(this);
}
}
inline void
PackageEntry::CoreWakesUp(CoreEntry* core)
{
WriteSpinLocker _(fCoreLock);
ASSERT(fIdleCoreCount > 0);
ASSERT(fIdleCoreCount <= fCoreCount);
fIdleCoreCount--;
fIdleCores.Remove(core);
if (fIdleCoreCount + 1 == fCoreCount) {
// package wakes up
WriteSpinLocker _(gIdlePackageLock);
gIdlePackageList.Remove(this);
}
}
void
PackageEntry::AddIdleCore(CoreEntry* core)
{
fCoreCount++;
fIdleCoreCount++;
fIdleCores.Add(core);
if (fCoreCount == 1)
gIdlePackageList.Add(this);
}
void
PackageEntry::RemoveIdleCore(CoreEntry* core)
{
fIdleCores.Remove(core);
fIdleCoreCount--;
fCoreCount--;
if (fCoreCount == 0)
gIdlePackageList.Remove(this);
}
/* static */ void
DebugDumper::DumpIdleCoresInPackage(PackageEntry* package)
{
kprintf("%-7" B_PRId32 " ", package->fPackageID);
DoublyLinkedList<CoreEntry>::ReverseIterator iterator
= package->fIdleCores.GetReverseIterator();
if (iterator.HasNext()) {
while (iterator.HasNext()) {
CoreEntry* coreEntry = iterator.Next();
kprintf("%" B_PRId32 "%s", coreEntry->fCoreID,
iterator.HasNext() ? ", " : "");
}
} else
kprintf("-");
kprintf("\n");
}
static int static int
dump_run_queue(int argc, char **argv) dump_run_queue(int argc, char **argv)
{ {
@@ -429,22 +497,8 @@ dump_idle_cores(int argc, char** argv)
if (idleIterator.HasNext()) { if (idleIterator.HasNext()) {
kprintf("package cores\n"); kprintf("package cores\n");
while (idleIterator.HasNext()) { while (idleIterator.HasNext())
PackageEntry* entry = idleIterator.Next(); DebugDumper::DumpIdleCoresInPackage(idleIterator.Next());
kprintf("%-7" B_PRId32 " ", entry->fPackageID);
DoublyLinkedList<CoreEntry>::ReverseIterator iterator
= entry->fIdleCores.GetReverseIterator();
if (iterator.HasNext()) {
while (iterator.HasNext()) {
CoreEntry* coreEntry = iterator.Next();
kprintf("%" B_PRId32 "%s", coreEntry->fCoreID,
iterator.HasNext() ? ", " : "");
}
} else
kprintf("-");
kprintf("\n");
}
} else } else
kprintf("No idle packages.\n"); kprintf("No idle packages.\n");
@@ -452,7 +506,7 @@ dump_idle_cores(int argc, char** argv)
} }
void Scheduler::init_debug_commands(void) void Scheduler::init_debug_commands()
{ {
new(&sDebugCPUHeap) CPUPriorityHeap(smp_get_num_cpus()); new(&sDebugCPUHeap) CPUPriorityHeap(smp_get_num_cpus());
new(&sDebugCoreHeap) CoreLoadHeap(smp_get_num_cpus()); new(&sDebugCoreHeap) CoreLoadHeap(smp_get_num_cpus());
+62 -1
View File
@@ -21,6 +21,8 @@
namespace Scheduler { namespace Scheduler {
class DebugDumper;
struct ThreadData; struct ThreadData;
struct CPUEntry; struct CPUEntry;
@@ -122,15 +124,32 @@ public:
// packages can go to the deep state of sleep). The heap stores only packages // packages can go to the deep state of sleep). The heap stores only packages
// with at least one core active and one core idle. The packages with all cores // with at least one core active and one core idle. The packages with all cores
// idle are stored in gPackageIdleList (in LIFO manner). // idle are stored in gPackageIdleList (in LIFO manner).
struct PackageEntry : public DoublyLinkedListLinkImpl<PackageEntry> { class PackageEntry : public DoublyLinkedListLinkImpl<PackageEntry> {
public:
PackageEntry(); PackageEntry();
void Init(int32 id);
inline void CoreGoesIdle(CoreEntry* core);
inline void CoreWakesUp(CoreEntry* core);
inline CoreEntry* GetIdleCore() const;
void AddIdleCore(CoreEntry* core);
void RemoveIdleCore(CoreEntry* core);
static inline PackageEntry* GetMostIdlePackage();
static inline PackageEntry* GetLeastIdlePackage();
private:
int32 fPackageID; int32 fPackageID;
DoublyLinkedList<CoreEntry> fIdleCores; DoublyLinkedList<CoreEntry> fIdleCores;
int32 fIdleCoreCount; int32 fIdleCoreCount;
int32 fCoreCount; int32 fCoreCount;
rw_spinlock fCoreLock; rw_spinlock fCoreLock;
friend class DebugDumper;
} CACHE_LINE_ALIGN; } CACHE_LINE_ALIGN;
typedef DoublyLinkedList<PackageEntry> IdlePackageList; typedef DoublyLinkedList<PackageEntry> IdlePackageList;
@@ -163,6 +182,48 @@ CoreEntry::GetCore(int32 cpu)
} }
inline CoreEntry*
PackageEntry::GetIdleCore() const
{
return fIdleCores.Last();
}
/* static */ inline PackageEntry*
PackageEntry::GetMostIdlePackage()
{
PackageEntry* current = &gPackageEntries[0];
for (int32 i = 1; i < gPackageCount; i++) {
if (gPackageEntries[i].fIdleCoreCount > current->fIdleCoreCount)
current = &gPackageEntries[i];
}
if (current->fIdleCoreCount == 0)
return NULL;
return current;
}
/* static */ inline PackageEntry*
PackageEntry::GetLeastIdlePackage()
{
PackageEntry* package = NULL;
for (int32 i = 0; i < gPackageCount; i++) {
PackageEntry* current = &gPackageEntries[i];
int32 currentIdleCoreCount = current->fIdleCoreCount;
if (currentIdleCoreCount != 0 && (package == NULL
|| currentIdleCoreCount < package->fIdleCoreCount)) {
package = current;
}
}
return package;
}
} // namespace Scheduler } // namespace Scheduler
@@ -21,7 +21,7 @@ struct scheduler_mode_operations {
bigtime_t maximum_latency; bigtime_t maximum_latency;
void (*switch_to_mode)(void); void (*switch_to_mode)();
void (*set_cpu_enabled)(int32 cpu, bool enabled); void (*set_cpu_enabled)(int32 cpu, bool enabled);
bool (*has_cache_expired)( bool (*has_cache_expired)(
const Scheduler::ThreadData* threadData); const Scheduler::ThreadData* threadData);
@@ -53,7 +53,7 @@ public:
inline Thread* GetThread() const { return fThread; } inline Thread* GetThread() const { return fThread; }
inline int32 GetLoad() const { return fLoad; } inline int32 GetLoad() const { return fLoad; }
inline CoreEntry* GetCore() const { return fCore; } inline CoreEntry* Core() const { return fCore; }
inline void UnassignCore() { fCore = NULL; } inline void UnassignCore() { fCore = NULL; }
bigtime_t fStolenTime; bigtime_t fStolenTime;