hle: kernel: KThread: Migrate to updated KThreadQueue (part 2).
This commit is contained in:
parent
b0671c7cfa
commit
f62c7091a2
1 changed files with 19 additions and 29 deletions
|
@ -504,30 +504,33 @@ ResultCode KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_m
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
ResultCode KThread::SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask) {
|
|
||||||
|
ResultCode KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) {
|
||||||
ASSERT(parent != nullptr);
|
ASSERT(parent != nullptr);
|
||||||
ASSERT(v_affinity_mask != 0);
|
ASSERT(v_affinity_mask != 0);
|
||||||
KScopedLightLock lk{activity_pause_lock};
|
KScopedLightLock lk(activity_pause_lock);
|
||||||
|
|
||||||
// Set the core mask.
|
// Set the core mask.
|
||||||
u64 p_affinity_mask = 0;
|
u64 p_affinity_mask = 0;
|
||||||
{
|
{
|
||||||
KScopedSchedulerLock sl{kernel};
|
KScopedSchedulerLock sl(kernel);
|
||||||
ASSERT(num_core_migration_disables >= 0);
|
ASSERT(num_core_migration_disables >= 0);
|
||||||
|
|
||||||
// If the core id is no-update magic, preserve the ideal core id.
|
// If we're updating, set our ideal virtual core.
|
||||||
if (cpu_core_id == Svc::IdealCoreNoUpdate) {
|
if (core_id_ != Svc::IdealCoreNoUpdate) {
|
||||||
cpu_core_id = virtual_ideal_core_id;
|
virtual_ideal_core_id = core_id_;
|
||||||
R_UNLESS(((1ULL << cpu_core_id) & v_affinity_mask) != 0, ResultInvalidCombination);
|
} else {
|
||||||
|
// Preserve our ideal core id.
|
||||||
|
core_id_ = virtual_ideal_core_id;
|
||||||
|
R_UNLESS(((1ULL << core_id_) & v_affinity_mask) != 0, ResultInvalidCombination);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the virtual core/affinity mask.
|
// Set our affinity mask.
|
||||||
virtual_ideal_core_id = cpu_core_id;
|
|
||||||
virtual_affinity_mask = v_affinity_mask;
|
virtual_affinity_mask = v_affinity_mask;
|
||||||
|
|
||||||
// Translate the virtual core to a physical core.
|
// Translate the virtual core to a physical core.
|
||||||
if (cpu_core_id >= 0) {
|
if (core_id_ >= 0) {
|
||||||
cpu_core_id = Core::Hardware::VirtualToPhysicalCoreMap[cpu_core_id];
|
core_id_ = Core::Hardware::VirtualToPhysicalCoreMap[core_id_];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate the virtual affinity mask to a physical one.
|
// Translate the virtual affinity mask to a physical one.
|
||||||
|
@ -542,7 +545,7 @@ ResultCode KThread::SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask) {
|
||||||
const KAffinityMask old_mask = physical_affinity_mask;
|
const KAffinityMask old_mask = physical_affinity_mask;
|
||||||
|
|
||||||
// Set our new ideals.
|
// Set our new ideals.
|
||||||
physical_ideal_core_id = cpu_core_id;
|
physical_ideal_core_id = core_id_;
|
||||||
physical_affinity_mask.SetAffinityMask(p_affinity_mask);
|
physical_affinity_mask.SetAffinityMask(p_affinity_mask);
|
||||||
|
|
||||||
if (physical_affinity_mask.GetAffinityMask() != old_mask.GetAffinityMask()) {
|
if (physical_affinity_mask.GetAffinityMask() != old_mask.GetAffinityMask()) {
|
||||||
|
@ -560,18 +563,18 @@ ResultCode KThread::SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we edit the original affinity for restoration later.
|
// Otherwise, we edit the original affinity for restoration later.
|
||||||
original_physical_ideal_core_id = cpu_core_id;
|
original_physical_ideal_core_id = core_id_;
|
||||||
original_physical_affinity_mask.SetAffinityMask(p_affinity_mask);
|
original_physical_affinity_mask.SetAffinityMask(p_affinity_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the pinned waiter list.
|
// Update the pinned waiter list.
|
||||||
|
ThreadQueueImplForKThreadSetProperty wait_queue(kernel, std::addressof(pinned_waiter_list));
|
||||||
{
|
{
|
||||||
bool retry_update{};
|
bool retry_update{};
|
||||||
bool thread_is_pinned{};
|
|
||||||
do {
|
do {
|
||||||
// Lock the scheduler.
|
// Lock the scheduler.
|
||||||
KScopedSchedulerLock sl{kernel};
|
KScopedSchedulerLock sl(kernel);
|
||||||
|
|
||||||
// Don't do any further management if our termination has been requested.
|
// Don't do any further management if our termination has been requested.
|
||||||
R_SUCCEED_IF(IsTerminationRequested());
|
R_SUCCEED_IF(IsTerminationRequested());
|
||||||
|
@ -599,12 +602,9 @@ ResultCode KThread::SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask) {
|
||||||
R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(),
|
R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(),
|
||||||
ResultTerminationRequested);
|
ResultTerminationRequested);
|
||||||
|
|
||||||
// Note that the thread was pinned.
|
|
||||||
thread_is_pinned = true;
|
|
||||||
|
|
||||||
// Wait until the thread isn't pinned any more.
|
// Wait until the thread isn't pinned any more.
|
||||||
pinned_waiter_list.push_back(GetCurrentThread(kernel));
|
pinned_waiter_list.push_back(GetCurrentThread(kernel));
|
||||||
GetCurrentThread(kernel).SetState(ThreadState::Waiting);
|
GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
|
||||||
} else {
|
} else {
|
||||||
// If the thread isn't pinned, release the scheduler lock and retry until it's
|
// If the thread isn't pinned, release the scheduler lock and retry until it's
|
||||||
// not current.
|
// not current.
|
||||||
|
@ -612,16 +612,6 @@ ResultCode KThread::SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (retry_update);
|
} while (retry_update);
|
||||||
|
|
||||||
// If the thread was pinned, it no longer is, and we should remove the current thread from
|
|
||||||
// our waiter list.
|
|
||||||
if (thread_is_pinned) {
|
|
||||||
// Lock the scheduler.
|
|
||||||
KScopedSchedulerLock sl{kernel};
|
|
||||||
|
|
||||||
// Remove from the list.
|
|
||||||
pinned_waiter_list.erase(pinned_waiter_list.iterator_to(GetCurrentThread(kernel)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
|
Loading…
Reference in a new issue