diff options
| author | 2018-05-31 18:22:18 -0400 | |
|---|---|---|
| committer | 2018-05-31 18:22:18 -0400 | |
| commit | bdd68fc210d2b7138f8fcd22ec41c8b238500c28 (patch) | |
| tree | 26e0a08c8a0f8dc383eb32d21a947f600d0bdd5d | |
| parent | Merge pull request #491 from bunnei/rgba16f (diff) | |
| parent | Kernel/Thread: Corrected a typo that caused the affinity mask to never be cha... (diff) | |
| download | yuzu-bdd68fc210d2b7138f8fcd22ec41c8b238500c28.tar.gz yuzu-bdd68fc210d2b7138f8fcd22ec41c8b238500c28.tar.xz yuzu-bdd68fc210d2b7138f8fcd22ec41c8b238500c28.zip | |
Merge pull request #488 from Subv/thread_masks
Kernel/SVC: Corrected the behavior of svcSetThreadCoreMask for core values -2 and -3.
| -rw-r--r-- | src/core/hle/kernel/errors.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 6 |
3 files changed, 31 insertions, 4 deletions
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index 5be20c878..e1b5430bf 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h | |||
| @@ -21,7 +21,9 @@ enum { | |||
| 21 | 21 | ||
| 22 | // Confirmed Switch OS error codes | 22 | // Confirmed Switch OS error codes |
| 23 | MisalignedAddress = 102, | 23 | MisalignedAddress = 102, |
| 24 | InvalidProcessorId = 113, | ||
| 24 | InvalidHandle = 114, | 25 | InvalidHandle = 114, |
| 26 | InvalidCombination = 116, | ||
| 25 | Timeout = 117, | 27 | Timeout = 117, |
| 26 | SynchronizationCanceled = 118, | 28 | SynchronizationCanceled = 118, |
| 27 | TooLarge = 119, | 29 | TooLarge = 119, |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0811a16b8..ec3601e8b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -732,7 +732,7 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) | |||
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | 734 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { |
| 735 | NGLOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:08X}, core=0x{:X}", thread_handle, | 735 | NGLOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, |
| 736 | mask, core); | 736 | mask, core); |
| 737 | 737 | ||
| 738 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 738 | 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) { | |||
| 740 | return ERR_INVALID_HANDLE; | 740 | return ERR_INVALID_HANDLE; |
| 741 | } | 741 | } |
| 742 | 742 | ||
| 743 | if (core == THREADPROCESSORID_DEFAULT) { | ||
| 744 | ASSERT(thread->owner_process->ideal_processor != THREADPROCESSORID_DEFAULT); | ||
| 745 | // Set the target CPU to the one specified in the process' exheader. | ||
| 746 | core = thread->owner_process->ideal_processor; | ||
| 747 | mask = 1 << core; | ||
| 748 | } | ||
| 749 | |||
| 750 | if (mask == 0) { | ||
| 751 | return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination); | ||
| 752 | } | ||
| 753 | |||
| 754 | /// This value is used to only change the affinity mask without changing the current ideal core. | ||
| 755 | static constexpr u32 OnlyChangeMask = static_cast<u32>(-3); | ||
| 756 | |||
| 757 | if (core == OnlyChangeMask) { | ||
| 758 | core = thread->ideal_core; | ||
| 759 | } else if (core >= Core::NUM_CPU_CORES && core != -1) { | ||
| 760 | return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); | ||
| 761 | } | ||
| 762 | |||
| 763 | // Error out if the input core isn't enabled in the input mask. | ||
| 764 | if (core < Core::NUM_CPU_CORES && (mask & (1 << core)) == 0) { | ||
| 765 | return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination); | ||
| 766 | } | ||
| 767 | |||
| 743 | thread->ChangeCore(core, mask); | 768 | thread->ChangeCore(core, mask); |
| 744 | 769 | ||
| 745 | return RESULT_SUCCESS; | 770 | return RESULT_SUCCESS; |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 46fcdefb8..0075e4a0f 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -460,13 +460,13 @@ void Thread::UpdatePriority() { | |||
| 460 | 460 | ||
| 461 | void Thread::ChangeCore(u32 core, u64 mask) { | 461 | void Thread::ChangeCore(u32 core, u64 mask) { |
| 462 | ideal_core = core; | 462 | ideal_core = core; |
| 463 | mask = mask; | 463 | affinity_mask = mask; |
| 464 | 464 | ||
| 465 | if (status != THREADSTATUS_READY) { | 465 | if (status != THREADSTATUS_READY) { |
| 466 | return; | 466 | return; |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | boost::optional<s32> new_processor_id{GetNextProcessorId(mask)}; | 469 | boost::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)}; |
| 470 | 470 | ||
| 471 | if (!new_processor_id) { | 471 | if (!new_processor_id) { |
| 472 | new_processor_id = processor_id; | 472 | new_processor_id = processor_id; |
| @@ -476,7 +476,7 @@ void Thread::ChangeCore(u32 core, u64 mask) { | |||
| 476 | new_processor_id = ideal_core; | 476 | new_processor_id = ideal_core; |
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | ASSERT(new_processor_id < 4); | 479 | ASSERT(*new_processor_id < 4); |
| 480 | 480 | ||
| 481 | // Add thread to new core's scheduler | 481 | // Add thread to new core's scheduler |
| 482 | auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id); | 482 | auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id); |