forked from suyu/suyu
Merge pull request #488 from Subv/thread_masks
Kernel/SVC: Corrected the behavior of svcSetThreadCoreMask for core values -2 and -3.
This commit is contained in:
commit
bdd68fc210
3 changed files with 31 additions and 4 deletions
|
@ -21,7 +21,9 @@ enum {
|
||||||
|
|
||||||
// Confirmed Switch OS error codes
|
// Confirmed Switch OS error codes
|
||||||
MisalignedAddress = 102,
|
MisalignedAddress = 102,
|
||||||
|
InvalidProcessorId = 113,
|
||||||
InvalidHandle = 114,
|
InvalidHandle = 114,
|
||||||
|
InvalidCombination = 116,
|
||||||
Timeout = 117,
|
Timeout = 117,
|
||||||
SynchronizationCanceled = 118,
|
SynchronizationCanceled = 118,
|
||||||
TooLarge = 119,
|
TooLarge = 119,
|
||||||
|
|
|
@ -732,7 +732,7 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
||||||
NGLOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:08X}, core=0x{:X}", thread_handle,
|
NGLOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
|
||||||
mask, core);
|
mask, core);
|
||||||
|
|
||||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||||
|
@ -740,6 +740,31 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (core == THREADPROCESSORID_DEFAULT) {
|
||||||
|
ASSERT(thread->owner_process->ideal_processor != THREADPROCESSORID_DEFAULT);
|
||||||
|
// Set the target CPU to the one specified in the process' exheader.
|
||||||
|
core = thread->owner_process->ideal_processor;
|
||||||
|
mask = 1 << core;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask == 0) {
|
||||||
|
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This value is used to only change the affinity mask without changing the current ideal core.
|
||||||
|
static constexpr u32 OnlyChangeMask = static_cast<u32>(-3);
|
||||||
|
|
||||||
|
if (core == OnlyChangeMask) {
|
||||||
|
core = thread->ideal_core;
|
||||||
|
} else if (core >= Core::NUM_CPU_CORES && core != -1) {
|
||||||
|
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error out if the input core isn't enabled in the input mask.
|
||||||
|
if (core < Core::NUM_CPU_CORES && (mask & (1 << core)) == 0) {
|
||||||
|
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination);
|
||||||
|
}
|
||||||
|
|
||||||
thread->ChangeCore(core, mask);
|
thread->ChangeCore(core, mask);
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
|
|
|
@ -460,13 +460,13 @@ void Thread::UpdatePriority() {
|
||||||
|
|
||||||
void Thread::ChangeCore(u32 core, u64 mask) {
|
void Thread::ChangeCore(u32 core, u64 mask) {
|
||||||
ideal_core = core;
|
ideal_core = core;
|
||||||
mask = mask;
|
affinity_mask = mask;
|
||||||
|
|
||||||
if (status != THREADSTATUS_READY) {
|
if (status != THREADSTATUS_READY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<s32> new_processor_id{GetNextProcessorId(mask)};
|
boost::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)};
|
||||||
|
|
||||||
if (!new_processor_id) {
|
if (!new_processor_id) {
|
||||||
new_processor_id = processor_id;
|
new_processor_id = processor_id;
|
||||||
|
@ -476,7 +476,7 @@ void Thread::ChangeCore(u32 core, u64 mask) {
|
||||||
new_processor_id = ideal_core;
|
new_processor_id = ideal_core;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(new_processor_id < 4);
|
ASSERT(*new_processor_id < 4);
|
||||||
|
|
||||||
// Add thread to new core's scheduler
|
// Add thread to new core's scheduler
|
||||||
auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id);
|
auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id);
|
||||||
|
|
Loading…
Reference in a new issue