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:
		@@ -21,7 +21,9 @@ enum {
 | 
			
		||||
 | 
			
		||||
    // Confirmed Switch OS error codes
 | 
			
		||||
    MisalignedAddress = 102,
 | 
			
		||||
    InvalidProcessorId = 113,
 | 
			
		||||
    InvalidHandle = 114,
 | 
			
		||||
    InvalidCombination = 116,
 | 
			
		||||
    Timeout = 117,
 | 
			
		||||
    SynchronizationCanceled = 118,
 | 
			
		||||
    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) {
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
 
 | 
			
		||||
@@ -460,13 +460,13 @@ void Thread::UpdatePriority() {
 | 
			
		||||
 | 
			
		||||
void Thread::ChangeCore(u32 core, u64 mask) {
 | 
			
		||||
    ideal_core = core;
 | 
			
		||||
    mask = mask;
 | 
			
		||||
    affinity_mask = mask;
 | 
			
		||||
 | 
			
		||||
    if (status != THREADSTATUS_READY) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    boost::optional<s32> new_processor_id{GetNextProcessorId(mask)};
 | 
			
		||||
    boost::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)};
 | 
			
		||||
 | 
			
		||||
    if (!new_processor_id) {
 | 
			
		||||
        new_processor_id = processor_id;
 | 
			
		||||
@@ -476,7 +476,7 @@ void Thread::ChangeCore(u32 core, u64 mask) {
 | 
			
		||||
        new_processor_id = ideal_core;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ASSERT(new_processor_id < 4);
 | 
			
		||||
    ASSERT(*new_processor_id < 4);
 | 
			
		||||
 | 
			
		||||
    // Add thread to new core's scheduler
 | 
			
		||||
    auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user