|
|
@@ -1744,52 +1744,59 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
|
|
|
}
|
|
|
|
|
|
static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core,
|
|
|
- u64 mask) {
|
|
|
- LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle,
|
|
|
- mask, core);
|
|
|
+ u64 affinity_mask) {
|
|
|
+ LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, core=0x{:X}, affinity_mask=0x{:016X}",
|
|
|
+ thread_handle, core, affinity_mask);
|
|
|
|
|
|
- const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
|
|
- const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
|
|
- if (!thread) {
|
|
|
- LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
|
|
- thread_handle);
|
|
|
- return ERR_INVALID_HANDLE;
|
|
|
- }
|
|
|
+ const auto* const current_process = system.Kernel().CurrentProcess();
|
|
|
|
|
|
if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) {
|
|
|
- const u8 ideal_cpu_core = thread->GetOwnerProcess()->GetIdealCore();
|
|
|
+ const u8 ideal_cpu_core = current_process->GetIdealCore();
|
|
|
|
|
|
ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL));
|
|
|
|
|
|
// Set the target CPU to the ideal core specified by the process.
|
|
|
core = ideal_cpu_core;
|
|
|
- mask = 1ULL << core;
|
|
|
- }
|
|
|
-
|
|
|
- if (mask == 0) {
|
|
|
- LOG_ERROR(Kernel_SVC, "Mask is 0");
|
|
|
- return ERR_INVALID_COMBINATION;
|
|
|
- }
|
|
|
+ affinity_mask = 1ULL << core;
|
|
|
+ } else {
|
|
|
+ const u64 core_mask = current_process->GetCoreMask();
|
|
|
+
|
|
|
+ if ((core_mask | affinity_mask) != core_mask) {
|
|
|
+ LOG_ERROR(
|
|
|
+ Kernel_SVC,
|
|
|
+ "Invalid processor ID specified (core_mask=0x{:08X}, affinity_mask=0x{:016X})",
|
|
|
+ core_mask, affinity_mask);
|
|
|
+ return ERR_INVALID_PROCESSOR_ID;
|
|
|
+ }
|
|
|
|
|
|
- /// 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 (affinity_mask == 0) {
|
|
|
+ LOG_ERROR(Kernel_SVC, "Specfified affinity mask is zero.");
|
|
|
+ return ERR_INVALID_COMBINATION;
|
|
|
+ }
|
|
|
|
|
|
- if (core == OnlyChangeMask) {
|
|
|
- core = thread->GetIdealCore();
|
|
|
- } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(THREADPROCESSORID_DONT_UPDATE)) {
|
|
|
- LOG_ERROR(Kernel_SVC, "Invalid core specified, got {}", core);
|
|
|
- return ERR_INVALID_PROCESSOR_ID;
|
|
|
+ if (core < Core::NUM_CPU_CORES) {
|
|
|
+ if ((affinity_mask & (1ULL << core)) == 0) {
|
|
|
+ LOG_ERROR(Kernel_SVC,
|
|
|
+ "Core is not enabled for the current mask, core={}, mask={:016X}", core,
|
|
|
+ affinity_mask);
|
|
|
+ return ERR_INVALID_COMBINATION;
|
|
|
+ }
|
|
|
+ } else if (core != static_cast<u32>(THREADPROCESSORID_DONT_CARE) &&
|
|
|
+ core != static_cast<u32>(THREADPROCESSORID_DONT_UPDATE)) {
|
|
|
+ LOG_ERROR(Kernel_SVC, "Invalid processor ID specified (core={}).", core);
|
|
|
+ return ERR_INVALID_PROCESSOR_ID;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // Error out if the input core isn't enabled in the input mask.
|
|
|
- if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) {
|
|
|
- LOG_ERROR(Kernel_SVC, "Core is not enabled for the current mask, core={}, mask={:016X}",
|
|
|
- core, mask);
|
|
|
- return ERR_INVALID_COMBINATION;
|
|
|
+ const auto& handle_table = current_process->GetHandleTable();
|
|
|
+ const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
|
|
+ if (!thread) {
|
|
|
+ LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
|
|
+ thread_handle);
|
|
|
+ return ERR_INVALID_HANDLE;
|
|
|
}
|
|
|
|
|
|
- thread->ChangeCore(core, mask);
|
|
|
-
|
|
|
+ thread->ChangeCore(core, affinity_mask);
|
|
|
return RESULT_SUCCESS;
|
|
|
}
|
|
|
|