aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/os/process.cpp
diff options
context:
space:
mode:
authoryuzubot <[email protected]>2024-03-04 13:02:54 +0000
committeryuzubot <[email protected]>2024-03-04 13:02:54 +0000
commit537296095ab24eddcb196b5ef98004f91de9c8c2 (patch)
treee75e9e2441dc3f8657cc42f2daaae08737949c2b /src/core/hle/service/os/process.cpp
parent2ddac7b02b660bbc7bdfe4fef240699df6d52e64 (diff)
downloadyuzu-mainline-master.tar.gz
yuzu-mainline-master.zip
"Merge Tagged PR 13018"HEADmaster
Diffstat (limited to 'src/core/hle/service/os/process.cpp')
-rw-r--r--src/core/hle/service/os/process.cpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/core/hle/service/os/process.cpp b/src/core/hle/service/os/process.cpp
new file mode 100644
index 000000000..0dbadc315
--- /dev/null
+++ b/src/core/hle/service/os/process.cpp
@@ -0,0 +1,152 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/scope_exit.h"
+
+#include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/svc_types.h"
+#include "core/hle/service/os/process.h"
+#include "core/loader/loader.h"
+
+namespace Service {
+
+Process::Process(Core::System& system)
+ : m_system(system), m_process(), m_main_thread_priority(), m_main_thread_stack_size(),
+ m_process_started() {}
+
+Process::~Process() {
+ this->Finalize();
+}
+
+bool Process::Initialize(Loader::AppLoader& loader, Loader::ResultStatus& out_load_result) {
+ // First, ensure we are not holding another process.
+ this->Finalize();
+
+ // Create the process.
+ auto* const process = Kernel::KProcess::Create(m_system.Kernel());
+ Kernel::KProcess::Register(m_system.Kernel(), process);
+
+ // On exit, ensure we free the additional reference to the process.
+ SCOPE_EXIT {
+ process->Close();
+ };
+
+ // Insert process modules into memory.
+ const auto [load_result, load_parameters] = loader.Load(*process, m_system);
+ out_load_result = load_result;
+
+ // Ensure loading was successful.
+ if (load_result != Loader::ResultStatus::Success) {
+ return false;
+ }
+
+ // TODO: remove this, kernel already tracks this
+ m_system.Kernel().AppendNewProcess(process);
+
+ // Note the load parameters from NPDM.
+ m_main_thread_priority = load_parameters->main_thread_priority;
+ m_main_thread_stack_size = load_parameters->main_thread_stack_size;
+
+ // This process has not started yet.
+ m_process_started = false;
+
+ // Take ownership of the process object.
+ m_process = process;
+ m_process->Open();
+
+ // We succeeded.
+ return true;
+}
+
+void Process::Finalize() {
+ // Terminate, if we are currently holding a process.
+ this->Terminate();
+
+ // Close the process.
+ if (m_process) {
+ m_process->Close();
+
+ // TODO: remove this, kernel already tracks this
+ m_system.Kernel().RemoveProcess(m_process);
+ }
+
+ // Clean up.
+ m_process = nullptr;
+ m_main_thread_priority = 0;
+ m_main_thread_stack_size = 0;
+ m_process_started = false;
+}
+
+bool Process::Run() {
+ // If we already started the process, don't start again.
+ if (m_process_started) {
+ return false;
+ }
+
+ // Start.
+ if (m_process) {
+ m_process->Run(m_main_thread_priority, m_main_thread_stack_size);
+ }
+
+ // Mark as started.
+ m_process_started = true;
+
+ // We succeeded.
+ return true;
+}
+
+void Process::Terminate() {
+ if (m_process) {
+ m_process->Terminate();
+ }
+}
+
+void Process::ResetSignal() {
+ if (m_process) {
+ m_process->Reset();
+ }
+}
+
+bool Process::IsRunning() const {
+ if (m_process) {
+ const auto state = m_process->GetState();
+ return state == Kernel::KProcess::State::Running ||
+ state == Kernel::KProcess::State::RunningAttached ||
+ state == Kernel::KProcess::State::DebugBreak;
+ }
+
+ return false;
+}
+
+bool Process::IsTerminated() const {
+ if (m_process) {
+ return m_process->IsTerminated();
+ }
+
+ return false;
+}
+
+u64 Process::GetProcessId() const {
+ if (m_process) {
+ return m_process->GetProcessId();
+ }
+
+ return 0;
+}
+
+u64 Process::GetProgramId() const {
+ if (m_process) {
+ return m_process->GetProgramId();
+ }
+
+ return 0;
+}
+
+void Process::Suspend(bool suspended) {
+ if (m_process) {
+ m_process->SetActivity(suspended ? Kernel::Svc::ProcessActivity::Paused
+ : Kernel::Svc::ProcessActivity::Runnable);
+ }
+}
+
+} // namespace Service