diff --git a/src/system/kernel/scheduler/low_latency.cpp b/src/system/kernel/scheduler/low_latency.cpp index 073c07b040..3635bee7ab 100644 --- a/src/system/kernel/scheduler/low_latency.cpp +++ b/src/system/kernel/scheduler/low_latency.cpp @@ -57,15 +57,13 @@ choose_core(const ThreadData* threadData) int32 index = 0; CPUSet mask = threadData->GetCPUMask(); - if (mask.IsEmpty()) { - // ignore when empty - mask.SetAll(); - } + const bool useMask = !mask.IsEmpty(); + CoreEntry* core = NULL; if (package != NULL) { do { core = package->GetIdleCore(index++); - } while (core != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && core != NULL && !core->CPUMask().Matches(mask)); } if (core == NULL) { ReadSpinLocker coreLocker(gCoreHeapsLock); @@ -73,12 +71,12 @@ choose_core(const ThreadData* threadData) // no idle cores, use least occupied core do { core = gCoreLoadHeap.PeekMinimum(index++); - } while (core != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && core != NULL && !core->CPUMask().Matches(mask)); if (core == NULL) { index = 0; do { core = gCoreHighLoadHeap.PeekMinimum(index++); - } while (core != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && core != NULL && !core->CPUMask().Matches(mask)); } } @@ -98,23 +96,21 @@ rebalance(const ThreadData* threadData) // Get the least loaded core. ReadSpinLocker coreLocker(gCoreHeapsLock); CPUSet mask = threadData->GetCPUMask(); - if (mask.IsEmpty()) { - // ignore when empty - mask.SetAll(); - } + const bool useMask = !mask.IsEmpty(); + int32 index = 0; CoreEntry* other; do { other = gCoreLoadHeap.PeekMinimum(index++); - if (other != NULL && other->CPUMask().IsEmpty()) + if (other != NULL && (useMask && other->CPUMask().IsEmpty())) panic("other->CPUMask().IsEmpty()\n"); - } while (other != NULL && !other->CPUMask().Matches(mask)); + } while (useMask && other != NULL && !other->CPUMask().Matches(mask)); if (other == NULL) { index = 0; do { other = gCoreHighLoadHeap.PeekMinimum(index++); - } while (other != NULL && !other->CPUMask().Matches(mask)); + } while (useMask && other != NULL && !other->CPUMask().Matches(mask)); } coreLocker.Unlock(); ASSERT(other != NULL); diff --git a/src/system/kernel/scheduler/power_saving.cpp b/src/system/kernel/scheduler/power_saving.cpp index 5b98573964..4ebd746d37 100644 --- a/src/system/kernel/scheduler/power_saving.cpp +++ b/src/system/kernel/scheduler/power_saving.cpp @@ -89,14 +89,11 @@ choose_core(const ThreadData* threadData) CoreEntry* core = NULL; CPUSet mask = threadData->GetCPUMask(); - if (mask.IsEmpty()) { - // ignore when empty - mask.SetAll(); - } + const bool useMask = !mask.IsEmpty(); // try to pack all threads on one core core = choose_small_task_core(); - if (core != NULL && !core->CPUMask().Matches(mask)) + if (core != NULL && (useMask && !core->CPUMask().Matches(mask))) core = NULL; if (core == NULL || core->GetLoad() + threadData->GetLoad() >= kHighLoad) { @@ -106,12 +103,12 @@ choose_core(const ThreadData* threadData) int32 index = 0; do { core = gCoreLoadHeap.PeekMinimum(index++); - } while (core != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && core != NULL && !core->CPUMask().Matches(mask)); if (core == NULL) { coreLocker.Unlock(); core = choose_idle_core(); - if (!core->CPUMask().Matches(mask)) + if (useMask && !core->CPUMask().Matches(mask)) core = NULL; if (core == NULL) { @@ -119,7 +116,7 @@ choose_core(const ThreadData* threadData) index = 0; do { core = gCoreHighLoadHeap.PeekMinimum(index++); - } while (core != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && core != NULL && !core->CPUMask().Matches(mask)); } } } @@ -137,10 +134,8 @@ rebalance(const ThreadData* threadData) ASSERT(!gSingleCore); CPUSet mask = threadData->GetCPUMask(); - if (mask.IsEmpty()) { - // ignore when empty - mask.SetAll(); - } + const bool useMask = !mask.IsEmpty(); + CoreEntry* core = threadData->Core(); int32 coreLoad = core->GetLoad(); @@ -151,7 +146,7 @@ rebalance(const ThreadData* threadData) CoreEntry* smallTaskCore = choose_small_task_core(); if (threadLoad > coreLoad / 3 || smallTaskCore == NULL - || !smallTaskCore->CPUMask().Matches(mask)) { + || (useMask && !smallTaskCore->CPUMask().Matches(mask))) { return core; } return coreLoad > kVeryHighLoad ? smallTaskCore : core; @@ -165,12 +160,12 @@ rebalance(const ThreadData* threadData) int32 index = 0; do { other = gCoreLoadHeap.PeekMaximum(index++); - } while (other != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && other != NULL && !other->CPUMask().Matches(mask)); if (other == NULL) { index = 0; do { other = gCoreHighLoadHeap.PeekMinimum(index++); - } while (other != NULL && !core->CPUMask().Matches(mask)); + } while (useMask && other != NULL && !other->CPUMask().Matches(mask)); } coreLocker.Unlock(); ASSERT(other != NULL); @@ -184,7 +179,7 @@ rebalance(const ThreadData* threadData) return core; CoreEntry* smallTaskCore = choose_small_task_core(); - if (smallTaskCore == NULL || !smallTaskCore->CPUMask().Matches(mask)) + if (smallTaskCore == NULL || (useMask && !smallTaskCore->CPUMask().Matches(mask))) return core; return smallTaskCore->GetLoad() + threadLoad < kHighLoad ? smallTaskCore : core; diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 3ea4f8eb2d..aeaab25058 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -329,6 +329,9 @@ reschedule(int32 nextState) Thread* oldThread = thread_get_current_thread(); ThreadData* oldThreadData = oldThread->scheduler_data; + CPUSet oldThreadMask; + bool useOldThreadMask, fetchedOldThreadMask = false; + oldThreadData->StopCPUTime(); SchedulerModeLocker modeLocker; @@ -348,7 +351,11 @@ reschedule(int32 nextState) case B_THREAD_READY: enqueueOldThread = true; - if (!oldThreadData->IsIdle() && oldThreadData->GetCPUMask().GetBit(thisCPU)) { + oldThreadMask = oldThreadData->GetCPUMask(); + useOldThreadMask = !oldThreadMask.IsEmpty(); + fetchedOldThreadMask = true; + + if (!oldThreadData->IsIdle() && (!useOldThreadMask || oldThreadMask.GetBit(thisCPU))) { oldThreadData->Continues(); if (oldThreadData->HasQuantumEnded(oldThread->cpu->preempted, oldThread->has_yielded)) { @@ -394,15 +401,19 @@ reschedule(int32 nextState) } else nextThreadData = oldThreadData; } else { - CPUSet mask = oldThreadData->GetCPUMask(); - if (mask.IsEmpty()) - mask.SetAll(); - bool oldThreadShouldMigrate = !mask.GetBit(thisCPU); + if (!fetchedOldThreadMask) { + oldThreadMask = oldThreadData->GetCPUMask(); + useOldThreadMask = !oldThreadMask.IsEmpty(); + fetchedOldThreadMask = true; + } + bool oldThreadShouldMigrate = useOldThreadMask && !oldThreadMask.GetBit(thisCPU); if (oldThreadShouldMigrate) enqueueOldThread = false; + nextThreadData = cpu->ChooseNextThread(enqueueOldThread ? oldThreadData : NULL, putOldThreadAtBack); + if (oldThreadShouldMigrate) { enqueue(oldThread, true); // replace with the idle thread, if no other thread could be found diff --git a/src/system/kernel/scheduler/scheduler_thread.cpp b/src/system/kernel/scheduler/scheduler_thread.cpp index 75835de81b..1555e4eccf 100644 --- a/src/system/kernel/scheduler/scheduler_thread.cpp +++ b/src/system/kernel/scheduler/scheduler_thread.cpp @@ -60,12 +60,11 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const int32 threadPriority = GetEffectivePriority(); CPUSet mask = GetCPUMask(); - if (mask.IsEmpty()) - mask.SetAll(); - ASSERT(mask.Matches(core->CPUMask())); + const bool useMask = !mask.IsEmpty(); + ASSERT(!useMask || mask.Matches(core->CPUMask())); if (fThread->previous_cpu != NULL && !fThread->previous_cpu->disabled - && mask.GetBit(fThread->previous_cpu->cpu_num)) { + && (!useMask || mask.GetBit(fThread->previous_cpu->cpu_num))) { CPUEntry* previousCPU = CPUEntry::GetCPU(fThread->previous_cpu->cpu_num); if (previousCPU->Core() == core) { @@ -83,7 +82,7 @@ ThreadData::_ChooseCPU(CoreEntry* core, bool& rescheduleNeeded) const CPUEntry* cpu; do { cpu = core->CPUHeap()->PeekRoot(index++); - } while (cpu != NULL && !mask.GetBit(cpu->ID())); + } while (useMask && cpu != NULL && !mask.GetBit(cpu->ID())); ASSERT(cpu != NULL); if (CPUPriorityHeap::GetKey(cpu) < threadPriority) { @@ -166,9 +165,12 @@ ThreadData::ChooseCoreAndCPU(CoreEntry*& targetCore, CPUEntry*& targetCPU) bool rescheduleNeeded = false; - if (targetCore != NULL && !targetCore->CPUMask().Matches(GetCPUMask())) + CPUSet mask = GetCPUMask(); + const bool useMask = !mask.IsEmpty(); + + if (targetCore != NULL && (useMask && !targetCore->CPUMask().Matches(mask))) targetCore = NULL; - if (targetCPU != NULL && !GetCPUMask().GetBit(targetCPU->ID())) + if (targetCPU != NULL && (useMask && !mask.GetBit(targetCPU->ID()))) targetCPU = NULL; if (targetCore == NULL && targetCPU != NULL) @@ -177,10 +179,7 @@ ThreadData::ChooseCoreAndCPU(CoreEntry*& targetCore, CPUEntry*& targetCPU) targetCPU = _ChooseCPU(targetCore, rescheduleNeeded); else if (targetCore == NULL && targetCPU == NULL) { targetCore = _ChooseCore(); - CPUSet mask = GetCPUMask(); - if (mask.IsEmpty()) - mask.SetAll(); - ASSERT(mask.Matches(targetCore->CPUMask())); + ASSERT(!useMask || mask.Matches(targetCore->CPUMask())); targetCPU = _ChooseCPU(targetCore, rescheduleNeeded); } diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 9463afde11..6afd38926a 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -204,7 +204,6 @@ Thread::Thread(const char* name, thread_id threadID, struct cpu_ent* cpu) { id = threadID >= 0 ? threadID : allocate_thread_id(); visible = false; - cpumask.SetAll(); // init locks char lockName[32]; @@ -2755,7 +2754,6 @@ thread_init(kernel_args *args) thread->team = team_get_kernel_team(); thread->priority = B_IDLE_PRIORITY; thread->state = B_THREAD_RUNNING; - thread->cpumask.SetAll(); sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1); thread->kernel_stack_area = find_area(name);