diff options
author | Fernando S <fsahmkow27@gmail.com> | 2022-06-16 02:41:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-16 02:41:12 +0200 |
commit | f86b770ff75efff029fa82b959b3f33eca1750fe (patch) | |
tree | 8c1aa046c96d7f943288ecb3455f4091cdc31a09 /src/core/hle/kernel/k_process.cpp | |
parent | Merge pull request #8460 from Morph1984/bounded-q (diff) | |
parent | kernel: implement KProcess suspension (diff) | |
download | yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.tar yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.tar.gz yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.tar.bz2 yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.tar.lz yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.tar.xz yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.tar.zst yuzu-f86b770ff75efff029fa82b959b3f33eca1750fe.zip |
Diffstat (limited to 'src/core/hle/kernel/k_process.cpp')
-rw-r--r-- | src/core/hle/kernel/k_process.cpp | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 8c79b4f0f..cd863e715 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -275,11 +275,15 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a shmem->Close(); } -void KProcess::RegisterThread(const KThread* thread) { +void KProcess::RegisterThread(KThread* thread) { + KScopedLightLock lk{list_lock}; + thread_list.push_back(thread); } -void KProcess::UnregisterThread(const KThread* thread) { +void KProcess::UnregisterThread(KThread* thread) { + KScopedLightLock lk{list_lock}; + thread_list.remove(thread); } @@ -297,6 +301,50 @@ ResultCode KProcess::Reset() { return ResultSuccess; } +ResultCode KProcess::SetActivity(ProcessActivity activity) { + // Lock ourselves and the scheduler. + KScopedLightLock lk{state_lock}; + KScopedLightLock list_lk{list_lock}; + KScopedSchedulerLock sl{kernel}; + + // Validate our state. + R_UNLESS(status != ProcessStatus::Exiting, ResultInvalidState); + R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState); + + // Either pause or resume. + if (activity == ProcessActivity::Paused) { + // Verify that we're not suspended. + if (is_suspended) { + return ResultInvalidState; + } + + // Suspend all threads. + for (auto* thread : GetThreadList()) { + thread->RequestSuspend(SuspendType::Process); + } + + // Set ourselves as suspended. + SetSuspended(true); + } else { + ASSERT(activity == ProcessActivity::Runnable); + + // Verify that we're suspended. + if (!is_suspended) { + return ResultInvalidState; + } + + // Resume all threads. + for (auto* thread : GetThreadList()) { + thread->Resume(SuspendType::Process); + } + + // Set ourselves as resumed. + SetSuspended(false); + } + + return ResultSuccess; +} + ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size) { program_id = metadata.GetTitleID(); @@ -556,9 +604,10 @@ bool KProcess::IsSignaled() const { } KProcess::KProcess(KernelCore& kernel_) - : KAutoObjectWithSlabHeapAndContainer{kernel_}, - page_table{std::make_unique<KPageTable>(kernel_.System())}, handle_table{kernel_}, - address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, state_lock{kernel_} {} + : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{std::make_unique<KPageTable>( + kernel_.System())}, + handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, + state_lock{kernel_}, list_lock{kernel_} {} KProcess::~KProcess() = default; |