diff options
| author | 2021-01-29 23:06:40 -0800 | |
|---|---|---|
| committer | 2021-01-29 23:06:40 -0800 | |
| commit | a4526c4e1acb50808bbe205952101142288e1c60 (patch) | |
| tree | 7109edf89606c43352da9de40d0e3a920a08b659 /src/core/hle/kernel/process.cpp | |
| parent | Merge pull request #5795 from ReinUsesLisp/bytes-to-map-end (diff) | |
| parent | hle: kernel: KLightLock: Fix several bugs. (diff) | |
| download | yuzu-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.cpp | 91 |
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 | */ |
| 39 | void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { | 39 | void 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 | ||
| 139 | void 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 | |||
| 148 | void 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 | |||
| 140 | u64 Process::GetTotalPhysicalMemoryAvailable() const { | 156 | u64 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 | ||
| 165 | void Process::RegisterThread(const Thread* thread) { | 181 | bool 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 | |||
| 206 | void 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 | |||
| 221 | void 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 | |||
| 236 | void Process::RegisterThread(const KThread* thread) { | ||
| 166 | thread_list.push_back(thread); | 237 | thread_list.push_back(thread); |
| 167 | } | 238 | } |
| 168 | 239 | ||
| 169 | void Process::UnregisterThread(const Thread* thread) { | 240 | void 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) { | |||
| 267 | void Process::PrepareForTermination() { | 338 | void 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 { | |||
| 372 | Process::Process(Core::System& system) | 443 | Process::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 | ||
| 377 | Process::~Process() = default; | 448 | Process::~Process() = default; |
| 378 | 449 | ||