mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
SVC: Correct GetThreadPriority, SetThreadPriority, GetThreadCoreMask, SetThreadCoreMask, GetCurrentProcessorNumber
This commit is contained in:
parent
49ba563995
commit
589f9cf108
5 changed files with 26 additions and 15 deletions
|
@ -467,6 +467,14 @@ const Kernel::Scheduler& System::CurrentScheduler() const {
|
||||||
return impl->CurrentPhysicalCore().Scheduler();
|
return impl->CurrentPhysicalCore().Scheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Kernel::PhysicalCore& System::CurrentPhysicalCore() {
|
||||||
|
return impl->CurrentPhysicalCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Kernel::PhysicalCore& System::CurrentPhysicalCore() const {
|
||||||
|
return impl->CurrentPhysicalCore();
|
||||||
|
}
|
||||||
|
|
||||||
Kernel::Scheduler& System::Scheduler(std::size_t core_index) {
|
Kernel::Scheduler& System::Scheduler(std::size_t core_index) {
|
||||||
return impl->GetPhysicalCore(core_index).Scheduler();
|
return impl->GetPhysicalCore(core_index).Scheduler();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ class VfsFilesystem;
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class GlobalScheduler;
|
class GlobalScheduler;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
|
class PhysicalCore;
|
||||||
class Process;
|
class Process;
|
||||||
class Scheduler;
|
class Scheduler;
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
@ -211,6 +212,12 @@ public:
|
||||||
/// Gets the scheduler for the CPU core that is currently running
|
/// Gets the scheduler for the CPU core that is currently running
|
||||||
const Kernel::Scheduler& CurrentScheduler() const;
|
const Kernel::Scheduler& CurrentScheduler() const;
|
||||||
|
|
||||||
|
/// Gets the physical core for the CPU core that is currently running
|
||||||
|
Kernel::PhysicalCore& CurrentPhysicalCore();
|
||||||
|
|
||||||
|
/// Gets the physical core for the CPU core that is currently running
|
||||||
|
const Kernel::PhysicalCore& CurrentPhysicalCore() const;
|
||||||
|
|
||||||
/// Gets a reference to an ARM interface for the CPU core with the specified index
|
/// Gets a reference to an ARM interface for the CPU core with the specified index
|
||||||
ARM_Interface& ArmInterface(std::size_t core_index);
|
ARM_Interface& ArmInterface(std::size_t core_index);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "core/hle/kernel/memory/memory_block.h"
|
#include "core/hle/kernel/memory/memory_block.h"
|
||||||
#include "core/hle/kernel/memory/page_table.h"
|
#include "core/hle/kernel/memory/page_table.h"
|
||||||
#include "core/hle/kernel/mutex.h"
|
#include "core/hle/kernel/mutex.h"
|
||||||
|
#include "core/hle/kernel/physical_core.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/readable_event.h"
|
#include "core/hle/kernel/readable_event.h"
|
||||||
#include "core/hle/kernel/resource_limit.h"
|
#include "core/hle/kernel/resource_limit.h"
|
||||||
|
@ -1071,6 +1072,7 @@ static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
*priority = 0;
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -1105,14 +1107,13 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri
|
||||||
|
|
||||||
thread->SetPriority(priority);
|
thread->SetPriority(priority);
|
||||||
|
|
||||||
system.PrepareReschedule(thread->GetProcessorID());
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get which CPU core is executing the current thread
|
/// Get which CPU core is executing the current thread
|
||||||
static u32 GetCurrentProcessorNumber(Core::System& system) {
|
static u32 GetCurrentProcessorNumber(Core::System& system) {
|
||||||
LOG_TRACE(Kernel_SVC, "called");
|
LOG_TRACE(Kernel_SVC, "called");
|
||||||
return system.CurrentScheduler().GetCurrentThread()->GetProcessorID();
|
return static_cast<u32>(system.CurrentPhysicalCore().CoreIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
|
static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
|
||||||
|
@ -1430,8 +1431,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
|
||||||
|
|
||||||
ThreadType type = THREADTYPE_USER;
|
ThreadType type = THREADTYPE_USER;
|
||||||
CASCADE_RESULT(std::shared_ptr<Thread> thread,
|
CASCADE_RESULT(std::shared_ptr<Thread> thread,
|
||||||
Thread::Create(system, type, "", entry_point, priority, arg, processor_id, stack_top,
|
Thread::Create(system, type, "", entry_point, priority, arg, processor_id,
|
||||||
current_process));
|
stack_top, current_process));
|
||||||
|
|
||||||
const auto new_thread_handle = current_process->GetHandleTable().Create(thread);
|
const auto new_thread_handle = current_process->GetHandleTable().Create(thread);
|
||||||
if (new_thread_handle.Failed()) {
|
if (new_thread_handle.Failed()) {
|
||||||
|
@ -1804,6 +1805,8 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
||||||
thread_handle);
|
thread_handle);
|
||||||
|
*core = 0;
|
||||||
|
*mask = 0;
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1866,11 +1869,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
system.PrepareReschedule(thread->GetProcessorID());
|
return thread->SetCoreAndAffinityMask(core, affinity_mask);
|
||||||
thread->ChangeCore(core, affinity_mask);
|
|
||||||
system.PrepareReschedule(thread->GetProcessorID());
|
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) {
|
static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) {
|
||||||
|
|
|
@ -250,6 +250,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::SetPriority(u32 priority) {
|
void Thread::SetPriority(u32 priority) {
|
||||||
|
SchedulerLock lock(kernel);
|
||||||
ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST,
|
ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST,
|
||||||
"Invalid priority value.");
|
"Invalid priority value.");
|
||||||
nominal_priority = priority;
|
nominal_priority = priority;
|
||||||
|
@ -383,10 +384,6 @@ void Thread::UpdatePriority() {
|
||||||
lock_owner->UpdatePriority();
|
lock_owner->UpdatePriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::ChangeCore(u32 core, u64 mask) {
|
|
||||||
SetCoreAndAffinityMask(core, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Thread::AllSynchronizationObjectsReady() const {
|
bool Thread::AllSynchronizationObjectsReady() const {
|
||||||
return std::none_of(wait_objects.begin(), wait_objects.end(),
|
return std::none_of(wait_objects.begin(), wait_objects.end(),
|
||||||
[this](const std::shared_ptr<SynchronizationObject>& object) {
|
[this](const std::shared_ptr<SynchronizationObject>& object) {
|
||||||
|
@ -467,6 +464,7 @@ void Thread::SetCurrentPriority(u32 new_priority) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
|
ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
|
||||||
|
SchedulerLock lock(kernel);
|
||||||
const auto HighestSetCore = [](u64 mask, u32 max_cores) {
|
const auto HighestSetCore = [](u64 mask, u32 max_cores) {
|
||||||
for (s32 core = static_cast<s32>(max_cores - 1); core >= 0; core--) {
|
for (s32 core = static_cast<s32>(max_cores - 1); core >= 0; core--) {
|
||||||
if (((mask >> core) & 1) != 0) {
|
if (((mask >> core) & 1) != 0) {
|
||||||
|
|
|
@ -221,7 +221,7 @@ public:
|
||||||
void UpdatePriority();
|
void UpdatePriority();
|
||||||
|
|
||||||
/// Changes the core that the thread is running or scheduled to run on.
|
/// Changes the core that the thread is running or scheduled to run on.
|
||||||
void ChangeCore(u32 core, u64 mask);
|
ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the thread's thread ID
|
* Gets the thread's thread ID
|
||||||
|
@ -522,7 +522,6 @@ private:
|
||||||
|
|
||||||
void SetSchedulingStatus(ThreadSchedStatus new_status);
|
void SetSchedulingStatus(ThreadSchedStatus new_status);
|
||||||
void SetCurrentPriority(u32 new_priority);
|
void SetCurrentPriority(u32 new_priority);
|
||||||
ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
|
|
||||||
|
|
||||||
void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);
|
void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue