summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/process.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2021-01-29 23:06:40 -0800
committerGravatar GitHub2021-01-29 23:06:40 -0800
commita4526c4e1acb50808bbe205952101142288e1c60 (patch)
tree7109edf89606c43352da9de40d0e3a920a08b659 /src/core/hle/kernel/process.cpp
parentMerge pull request #5795 from ReinUsesLisp/bytes-to-map-end (diff)
parenthle: kernel: KLightLock: Fix several bugs. (diff)
downloadyuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.gz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.tar.xz
yuzu-a4526c4e1acb50808bbe205952101142288e1c60.zip
Merge pull request #5779 from bunnei/kthread-rewrite
Rewrite KThread to be more accurate
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
-rw-r--r--src/core/hle/kernel/process.cpp91
1 files changed, 81 insertions, 10 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 37b77fa6e..0edbfc4cc 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -16,13 +16,13 @@
16#include "core/hle/kernel/code_set.h" 16#include "core/hle/kernel/code_set.h"
17#include "core/hle/kernel/errors.h" 17#include "core/hle/kernel/errors.h"
18#include "core/hle/kernel/k_scheduler.h" 18#include "core/hle/kernel/k_scheduler.h"
19#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/kernel.h" 20#include "core/hle/kernel/kernel.h"
20#include "core/hle/kernel/memory/memory_block_manager.h" 21#include "core/hle/kernel/memory/memory_block_manager.h"
21#include "core/hle/kernel/memory/page_table.h" 22#include "core/hle/kernel/memory/page_table.h"
22#include "core/hle/kernel/memory/slab_heap.h" 23#include "core/hle/kernel/memory/slab_heap.h"
23#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
24#include "core/hle/kernel/resource_limit.h" 25#include "core/hle/kernel/resource_limit.h"
25#include "core/hle/kernel/thread.h"
26#include "core/hle/lock.h" 26#include "core/hle/lock.h"
27#include "core/memory.h" 27#include "core/memory.h"
28#include "core/settings.h" 28#include "core/settings.h"
@@ -38,11 +38,10 @@ namespace {
38 */ 38 */
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 ThreadType type = THREADTYPE_USER; 41 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0,
42 auto thread_res = Thread::Create(system, type, "main", entry_point, priority, 0, 42 owner_process.GetIdealCoreId(), stack_top, &owner_process);
43 owner_process.GetIdealCore(), stack_top, &owner_process);
44 43
45 std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap(); 44 std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap();
46 45
47 // Register 1 must be a handle to the main thread 46 // Register 1 must be a handle to the main thread
48 const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); 47 const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
@@ -137,6 +136,23 @@ std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const {
137 return resource_limit; 136 return resource_limit;
138} 137}
139 138
139void Process::IncrementThreadCount() {
140 ASSERT(num_threads >= 0);
141 num_created_threads++;
142
143 if (const auto count = ++num_threads; count > peak_num_threads) {
144 peak_num_threads = count;
145 }
146}
147
148void Process::DecrementThreadCount() {
149 ASSERT(num_threads > 0);
150
151 if (const auto count = --num_threads; count == 0) {
152 UNIMPLEMENTED_MSG("Process termination is not implemented!");
153 }
154}
155
140u64 Process::GetTotalPhysicalMemoryAvailable() const { 156u64 Process::GetTotalPhysicalMemoryAvailable() const {
141 const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) + 157 const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) +
142 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + 158 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
@@ -162,11 +178,66 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const {
162 return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); 178 return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
163} 179}
164 180
165void Process::RegisterThread(const Thread* thread) { 181bool Process::ReleaseUserException(KThread* thread) {
182 KScopedSchedulerLock sl{kernel};
183
184 if (exception_thread == thread) {
185 exception_thread = nullptr;
186
187 // Remove waiter thread.
188 s32 num_waiters{};
189 KThread* next = thread->RemoveWaiterByKey(
190 std::addressof(num_waiters),
191 reinterpret_cast<uintptr_t>(std::addressof(exception_thread)));
192 if (next != nullptr) {
193 if (next->GetState() == ThreadState::Waiting) {
194 next->SetState(ThreadState::Runnable);
195 } else {
196 KScheduler::SetSchedulerUpdateNeeded(kernel);
197 }
198 }
199
200 return true;
201 } else {
202 return false;
203 }
204}
205
206void Process::PinCurrentThread() {
207 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
208
209 // Get the current thread.
210 const s32 core_id = GetCurrentCoreId(kernel);
211 KThread* cur_thread = GetCurrentThreadPointer(kernel);
212
213 // Pin it.
214 PinThread(core_id, cur_thread);
215 cur_thread->Pin();
216
217 // An update is needed.
218 KScheduler::SetSchedulerUpdateNeeded(kernel);
219}
220
221void Process::UnpinCurrentThread() {
222 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
223
224 // Get the current thread.
225 const s32 core_id = GetCurrentCoreId(kernel);
226 KThread* cur_thread = GetCurrentThreadPointer(kernel);
227
228 // Unpin it.
229 cur_thread->Unpin();
230 UnpinThread(core_id, cur_thread);
231
232 // An update is needed.
233 KScheduler::SetSchedulerUpdateNeeded(kernel);
234}
235
236void Process::RegisterThread(const KThread* thread) {
166 thread_list.push_back(thread); 237 thread_list.push_back(thread);
167} 238}
168 239
169void Process::UnregisterThread(const Thread* thread) { 240void Process::UnregisterThread(const KThread* thread) {
170 thread_list.remove(thread); 241 thread_list.remove(thread);
171} 242}
172 243
@@ -267,7 +338,7 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
267void Process::PrepareForTermination() { 338void Process::PrepareForTermination() {
268 ChangeStatus(ProcessStatus::Exiting); 339 ChangeStatus(ProcessStatus::Exiting);
269 340
270 const auto stop_threads = [this](const std::vector<std::shared_ptr<Thread>>& thread_list) { 341 const auto stop_threads = [this](const std::vector<std::shared_ptr<KThread>>& thread_list) {
271 for (auto& thread : thread_list) { 342 for (auto& thread : thread_list) {
272 if (thread->GetOwnerProcess() != this) 343 if (thread->GetOwnerProcess() != this)
273 continue; 344 continue;
@@ -279,7 +350,7 @@ void Process::PrepareForTermination() {
279 ASSERT_MSG(thread->GetState() == ThreadState::Waiting, 350 ASSERT_MSG(thread->GetState() == ThreadState::Waiting,
280 "Exiting processes with non-waiting threads is currently unimplemented"); 351 "Exiting processes with non-waiting threads is currently unimplemented");
281 352
282 thread->Stop(); 353 thread->Exit();
283 } 354 }
284 }; 355 };
285 356
@@ -372,7 +443,7 @@ bool Process::IsSignaled() const {
372Process::Process(Core::System& system) 443Process::Process(Core::System& system)
373 : KSynchronizationObject{system.Kernel()}, 444 : KSynchronizationObject{system.Kernel()},
374 page_table{std::make_unique<Memory::PageTable>(system)}, handle_table{system.Kernel()}, 445 page_table{std::make_unique<Memory::PageTable>(system)}, handle_table{system.Kernel()},
375 address_arbiter{system}, condition_var{system}, system{system} {} 446 address_arbiter{system}, condition_var{system}, state_lock{system.Kernel()}, system{system} {}
376 447
377Process::~Process() = default; 448Process::~Process() = default;
378 449