summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2021-01-03 01:49:18 -0800
committerGravatar bunnei2021-01-28 21:42:25 -0800
commit4dbf3f4880cac69db21cc8f18582814dc986c854 (patch)
tree16bd5c45c3341e3341d3581e830dbc9f5067784d /src/core/hle/kernel
parenthle: kernel: KThread: Reorganize thread priority defaults. (diff)
downloadyuzu-4dbf3f4880cac69db21cc8f18582814dc986c854.tar.gz
yuzu-4dbf3f4880cac69db21cc8f18582814dc986c854.tar.xz
yuzu-4dbf3f4880cac69db21cc8f18582814dc986c854.zip
hle: kernel: KThread: Clean up thread priorities.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/global_scheduler_context.h2
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp2
-rw-r--r--src/core/hle/kernel/k_thread.cpp10
-rw-r--r--src/core/hle/kernel/k_thread.h22
-rw-r--r--src/core/hle/kernel/process.cpp2
-rw-r--r--src/core/hle/kernel/process.h7
-rw-r--r--src/core/hle/kernel/svc.cpp66
-rw-r--r--src/core/hle/kernel/svc_results.h1
-rw-r--r--src/core/hle/kernel/svc_types.h4
9 files changed, 41 insertions, 75 deletions
diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h
index 11592843e..0f7b9a61c 100644
--- a/src/core/hle/kernel/global_scheduler_context.h
+++ b/src/core/hle/kernel/global_scheduler_context.h
@@ -21,7 +21,7 @@ class KernelCore;
21class SchedulerLock; 21class SchedulerLock;
22 22
23using KSchedulerPriorityQueue = 23using KSchedulerPriorityQueue =
24 KPriorityQueue<KThread, Core::Hardware::NUM_CPU_CORES, Svc::LowestThreadPriority, 24 KPriorityQueue<KThread, Core::Hardware::NUM_CPU_CORES, Svc::LowestThreadPriority + 1,
25 Svc::HighestThreadPriority>; 25 Svc::HighestThreadPriority>;
26 26
27static constexpr s32 HighestCoreMigrationAllowedPriority = 2; 27static constexpr s32 HighestCoreMigrationAllowedPriority = 2;
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index 0e6300760..233022023 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -764,7 +764,7 @@ void KScheduler::Initialize() {
764 std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc(); 764 std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc();
765 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); 765 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
766 auto thread_res = KThread::Create(system, ThreadType::Kernel, name, 0, 766 auto thread_res = KThread::Create(system, ThreadType::Kernel, name, 0,
767 Svc::LowestThreadPriority, 0, static_cast<u32>(core_id), 0, 767 KThread::IdleThreadPriority, 0, static_cast<u32>(core_id), 0,
768 nullptr, std::move(init_func), init_func_parameter); 768 nullptr, std::move(init_func), init_func_parameter);
769 idle_thread = thread_res.Unwrap().get(); 769 idle_thread = thread_res.Unwrap().get();
770 770
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 518c5d5df..e5be849bb 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -127,14 +127,6 @@ ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, Thread
127 void* thread_start_parameter) { 127 void* thread_start_parameter) {
128 auto& kernel = system.Kernel(); 128 auto& kernel = system.Kernel();
129 129
130 R_UNLESS(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority,
131 Svc::ResultInvalidPriority);
132
133 if (processor_id > THREADPROCESSORID_MAX) {
134 LOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id);
135 return ERR_INVALID_PROCESSOR_ID;
136 }
137
138 if (owner_process) { 130 if (owner_process) {
139 if (!system.Memory().IsValidVirtualAddress(*owner_process, entry_point)) { 131 if (!system.Memory().IsValidVirtualAddress(*owner_process, entry_point)) {
140 LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); 132 LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
@@ -423,7 +415,7 @@ ResultCode KThread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask)
423 }; 415 };
424 416
425 const bool use_override = affinity_override_count != 0; 417 const bool use_override = affinity_override_count != 0;
426 if (new_core == THREADPROCESSORID_DONT_UPDATE) { 418 if (new_core == Svc::IdealCoreNoUpdate) {
427 new_core = use_override ? ideal_core_override : ideal_core; 419 new_core = use_override ? ideal_core_override : ideal_core;
428 if ((new_affinity_mask & (1ULL << new_core)) == 0) { 420 if ((new_affinity_mask & (1ULL << new_core)) == 0) {
429 LOG_ERROR(Kernel, "New affinity mask is incorrect! new_core={}, new_affinity_mask={}", 421 LOG_ERROR(Kernel, "New affinity mask is incorrect! new_core={}, new_affinity_mask={}",
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 83a6d36ae..ef2313f87 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -47,28 +47,6 @@ enum class ThreadType : u32 {
47}; 47};
48DECLARE_ENUM_FLAG_OPERATORS(ThreadType); 48DECLARE_ENUM_FLAG_OPERATORS(ThreadType);
49 49
50enum ThreadProcessorId : s32 {
51 /// Indicates that no particular processor core is preferred.
52 THREADPROCESSORID_DONT_CARE = -1,
53
54 /// Run thread on the ideal core specified by the process.
55 THREADPROCESSORID_IDEAL = -2,
56
57 /// Indicates that the preferred processor ID shouldn't be updated in
58 /// a core mask setting operation.
59 THREADPROCESSORID_DONT_UPDATE = -3,
60
61 THREADPROCESSORID_0 = 0, ///< Run thread on core 0
62 THREADPROCESSORID_1 = 1, ///< Run thread on core 1
63 THREADPROCESSORID_2 = 2, ///< Run thread on core 2
64 THREADPROCESSORID_3 = 3, ///< Run thread on core 3
65 THREADPROCESSORID_MAX = 4, ///< Processor ID must be less than this
66
67 /// Allowed CPU mask
68 THREADPROCESSORID_DEFAULT_MASK = (1 << THREADPROCESSORID_0) | (1 << THREADPROCESSORID_1) |
69 (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3)
70};
71
72enum class ThreadState : u16 { 50enum class ThreadState : u16 {
73 Initialized = 0, 51 Initialized = 0,
74 Waiting = 1, 52 Waiting = 1,
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index e47da2b7f..819e275ff 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -39,7 +39,7 @@ namespace {
39void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { 39void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) {
40 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); 40 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
41 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0, 41 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0,
42 owner_process.GetIdealCore(), stack_top, &owner_process); 42 owner_process.GetIdealCoreId(), stack_top, &owner_process);
43 43
44 std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap(); 44 std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap();
45 45
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index db01d6c8a..5a2cfdb36 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -173,10 +173,15 @@ public:
173 std::shared_ptr<ResourceLimit> GetResourceLimit() const; 173 std::shared_ptr<ResourceLimit> GetResourceLimit() const;
174 174
175 /// Gets the ideal CPU core ID for this process 175 /// Gets the ideal CPU core ID for this process
176 u8 GetIdealCore() const { 176 u8 GetIdealCoreId() const {
177 return ideal_core; 177 return ideal_core;
178 } 178 }
179 179
180 /// Checks if the specified thread priority is valid.
181 bool CheckThreadPriority(s32 prio) const {
182 return ((1ULL << prio) & GetPriorityMask()) != 0;
183 }
184
180 /// Gets the bitmask of allowed cores that this process' threads can run on. 185 /// Gets the bitmask of allowed cores that this process' threads can run on.
181 u64 GetCoreMask() const { 186 u64 GetCoreMask() const {
182 return capabilities.GetCoreMask(); 187 return capabilities.GetCoreMask();
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 70a8ef34b..2512bfd98 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1443,54 +1443,40 @@ static void ExitProcess32(Core::System& system) {
1443 ExitProcess(system); 1443 ExitProcess(system);
1444} 1444}
1445 1445
1446static constexpr bool IsValidCoreId(int32_t core_id) {
1447 return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES));
1448}
1449
1446/// Creates a new thread 1450/// Creates a new thread
1447static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, 1451static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
1448 VAddr stack_top, u32 priority, s32 processor_id) { 1452 VAddr stack_bottom, u32 priority, s32 core_id) {
1449 LOG_DEBUG(Kernel_SVC, 1453 LOG_DEBUG(Kernel_SVC,
1450 "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " 1454 "called entry_point=0x{:08X}, arg=0x{:08X}, stack_bottom=0x{:08X}, "
1451 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", 1455 "priority=0x{:08X}, core_id=0x{:08X}",
1452 entry_point, arg, stack_top, priority, processor_id, *out_handle); 1456 entry_point, arg, stack_bottom, priority, core_id);
1453 1457
1454 auto* const current_process = system.Kernel().CurrentProcess(); 1458 // Adjust core id, if it's the default magic.
1455 1459 auto& kernel = system.Kernel();
1456 if (processor_id == THREADPROCESSORID_IDEAL) { 1460 auto& process = *kernel.CurrentProcess();
1457 // Set the target CPU to the one specified by the process. 1461 if (core_id == Svc::IdealCoreUseProcessValue) {
1458 processor_id = current_process->GetIdealCore(); 1462 core_id = process.GetIdealCoreId();
1459 ASSERT(processor_id != THREADPROCESSORID_IDEAL);
1460 }
1461
1462 if (processor_id < THREADPROCESSORID_0 || processor_id > THREADPROCESSORID_3) {
1463 LOG_ERROR(Kernel_SVC, "Invalid thread processor ID: {}", processor_id);
1464 return ERR_INVALID_PROCESSOR_ID;
1465 }
1466
1467 const u64 core_mask = current_process->GetCoreMask();
1468 if ((core_mask | (1ULL << processor_id)) != core_mask) {
1469 LOG_ERROR(Kernel_SVC, "Invalid thread core specified ({})", processor_id);
1470 return ERR_INVALID_PROCESSOR_ID;
1471 }
1472
1473 if (priority > Svc::LowestThreadPriority) {
1474 LOG_ERROR(Kernel_SVC,
1475 "Invalid thread priority specified ({}). Must be within the range 0-64",
1476 priority);
1477 return ERR_INVALID_THREAD_PRIORITY;
1478 } 1463 }
1479 1464
1480 if (((1ULL << priority) & current_process->GetPriorityMask()) == 0) { 1465 // Validate arguments.
1481 LOG_ERROR(Kernel_SVC, "Invalid thread priority specified ({})", priority); 1466 R_UNLESS(IsValidCoreId(core_id), Svc::ResultInvalidCoreId);
1482 return ERR_INVALID_THREAD_PRIORITY; 1467 R_UNLESS(((1ULL << core_id) & process.GetCoreMask()) != 0, Svc::ResultInvalidCoreId);
1483 }
1484 1468
1485 auto& kernel = system.Kernel(); 1469 R_UNLESS(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority,
1470 Svc::ResultInvalidPriority);
1471 R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority);
1486 1472
1487 ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Threads, 1)); 1473 ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Threads, 1));
1488 1474
1489 CASCADE_RESULT(std::shared_ptr<KThread> thread, 1475 CASCADE_RESULT(std::shared_ptr<KThread> thread,
1490 KThread::Create(system, ThreadType::User, "", entry_point, priority, arg, 1476 KThread::Create(system, ThreadType::User, "", entry_point, priority, arg,
1491 processor_id, stack_top, current_process)); 1477 core_id, stack_bottom, &process));
1492 1478
1493 const auto new_thread_handle = current_process->GetHandleTable().Create(thread); 1479 const auto new_thread_handle = process.GetHandleTable().Create(thread);
1494 if (new_thread_handle.Failed()) { 1480 if (new_thread_handle.Failed()) {
1495 LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", 1481 LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}",
1496 new_thread_handle.Code().raw); 1482 new_thread_handle.Code().raw);
@@ -1872,10 +1858,10 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
1872 1858
1873 const auto* const current_process = system.Kernel().CurrentProcess(); 1859 const auto* const current_process = system.Kernel().CurrentProcess();
1874 1860
1875 if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) { 1861 if (core == static_cast<u32>(Svc::IdealCoreUseProcessValue)) {
1876 const u8 ideal_cpu_core = current_process->GetIdealCore(); 1862 const u8 ideal_cpu_core = current_process->GetIdealCoreId();
1877 1863
1878 ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL)); 1864 ASSERT(ideal_cpu_core != static_cast<u8>(Svc::IdealCoreUseProcessValue));
1879 1865
1880 // Set the target CPU to the ideal core specified by the process. 1866 // Set the target CPU to the ideal core specified by the process.
1881 core = ideal_cpu_core; 1867 core = ideal_cpu_core;
@@ -1903,8 +1889,8 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
1903 affinity_mask); 1889 affinity_mask);
1904 return ERR_INVALID_COMBINATION; 1890 return ERR_INVALID_COMBINATION;
1905 } 1891 }
1906 } else if (core != static_cast<u32>(THREADPROCESSORID_DONT_CARE) && 1892 } else if (core != static_cast<u32>(Svc::IdealCoreDontCare) &&
1907 core != static_cast<u32>(THREADPROCESSORID_DONT_UPDATE)) { 1893 core != static_cast<u32>(Svc::IdealCoreNoUpdate)) {
1908 LOG_ERROR(Kernel_SVC, "Invalid processor ID specified (core={}).", core); 1894 LOG_ERROR(Kernel_SVC, "Invalid processor ID specified (core={}).", core);
1909 return ERR_INVALID_PROCESSOR_ID; 1895 return ERR_INVALID_PROCESSOR_ID;
1910 } 1896 }
diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h
index 74adabc11..67bdf5424 100644
--- a/src/core/hle/kernel/svc_results.h
+++ b/src/core/hle/kernel/svc_results.h
@@ -12,6 +12,7 @@ constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59};
12constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; 12constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102};
13constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; 13constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106};
14constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; 14constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112};
15constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113};
15constexpr ResultCode ResultInvalidHandle{ErrorModule::Kernel, 114}; 16constexpr ResultCode ResultInvalidHandle{ErrorModule::Kernel, 114};
16constexpr ResultCode ResultTimedOut{ErrorModule::Kernel, 117}; 17constexpr ResultCode ResultTimedOut{ErrorModule::Kernel, 117};
17constexpr ResultCode ResultCancelled{ErrorModule::Kernel, 118}; 18constexpr ResultCode ResultCancelled{ErrorModule::Kernel, 118};
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index 09b858f2a..8909dbfab 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -77,6 +77,10 @@ enum class ArbitrationType : u32 {
77 WaitIfEqual = 2, 77 WaitIfEqual = 2,
78}; 78};
79 79
80constexpr inline s32 IdealCoreDontCare = -1;
81constexpr inline s32 IdealCoreUseProcessValue = -2;
82constexpr inline s32 IdealCoreNoUpdate = -3;
83
80constexpr inline s32 LowestThreadPriority = 63; 84constexpr inline s32 LowestThreadPriority = 63;
81constexpr inline s32 HighestThreadPriority = 0; 85constexpr inline s32 HighestThreadPriority = 0;
82 86