summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/process.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2018-12-04 19:08:56 -0500
committerGravatar Lioncash2018-12-04 20:14:59 -0500
commitc7462ce71241fe6c8dfee48a859c63a6b1fd84fb (patch)
tree0350cdf3dcb0cae57573b7b2d869875c16f9b840 /src/core/hle/kernel/process.cpp
parentkernel/readable_event: Add member function for enforcing a strict reset contract (diff)
downloadyuzu-c7462ce71241fe6c8dfee48a859c63a6b1fd84fb.tar.gz
yuzu-c7462ce71241fe6c8dfee48a859c63a6b1fd84fb.tar.xz
yuzu-c7462ce71241fe6c8dfee48a859c63a6b1fd84fb.zip
kernel/process: Make Process a WaitObject
Process instances can be waited upon for state changes. This is also utilized by svcResetSignal, which will be modified in an upcoming change. This simply puts all of the WaitObject related machinery in place.
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
-rw-r--r--src/core/hle/kernel/process.cpp42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 4ecb8c926..211bf6686 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -9,6 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/file_sys/program_metadata.h" 11#include "core/file_sys/program_metadata.h"
12#include "core/hle/kernel/errors.h"
12#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
14#include "core/hle/kernel/resource_limit.h" 15#include "core/hle/kernel/resource_limit.h"
@@ -48,6 +49,21 @@ SharedPtr<ResourceLimit> Process::GetResourceLimit() const {
48 return resource_limit; 49 return resource_limit;
49} 50}
50 51
52ResultCode Process::ClearSignalState() {
53 if (status == ProcessStatus::Exited) {
54 LOG_ERROR(Kernel, "called on a terminated process instance.");
55 return ERR_INVALID_STATE;
56 }
57
58 if (!is_signaled) {
59 LOG_ERROR(Kernel, "called on a process instance that isn't signaled.");
60 return ERR_INVALID_STATE;
61 }
62
63 is_signaled = false;
64 return RESULT_SUCCESS;
65}
66
51void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { 67void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
52 program_id = metadata.GetTitleID(); 68 program_id = metadata.GetTitleID();
53 is_64bit_process = metadata.Is64BitProgram(); 69 is_64bit_process = metadata.Is64BitProgram();
@@ -137,13 +153,13 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
137 .Unwrap(); 153 .Unwrap();
138 154
139 vm_manager.LogLayout(); 155 vm_manager.LogLayout();
140 status = ProcessStatus::Running; 156 ChangeStatus(ProcessStatus::Running);
141 157
142 Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this); 158 Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this);
143} 159}
144 160
145void Process::PrepareForTermination() { 161void Process::PrepareForTermination() {
146 status = ProcessStatus::Exited; 162 ChangeStatus(ProcessStatus::Exiting);
147 163
148 const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) { 164 const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) {
149 for (auto& thread : thread_list) { 165 for (auto& thread : thread_list) {
@@ -167,6 +183,8 @@ void Process::PrepareForTermination() {
167 stop_threads(system.Scheduler(1).GetThreadList()); 183 stop_threads(system.Scheduler(1).GetThreadList());
168 stop_threads(system.Scheduler(2).GetThreadList()); 184 stop_threads(system.Scheduler(2).GetThreadList());
169 stop_threads(system.Scheduler(3).GetThreadList()); 185 stop_threads(system.Scheduler(3).GetThreadList());
186
187 ChangeStatus(ProcessStatus::Exited);
170} 188}
171 189
172/** 190/**
@@ -265,7 +283,25 @@ ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {
265 return vm_manager.UnmapRange(dst_addr, size); 283 return vm_manager.UnmapRange(dst_addr, size);
266} 284}
267 285
268Kernel::Process::Process(KernelCore& kernel) : Object{kernel} {} 286Kernel::Process::Process(KernelCore& kernel) : WaitObject{kernel} {}
269Kernel::Process::~Process() {} 287Kernel::Process::~Process() {}
270 288
289void Process::Acquire(Thread* thread) {
290 ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");
291}
292
293bool Process::ShouldWait(Thread* thread) const {
294 return !is_signaled;
295}
296
297void Process::ChangeStatus(ProcessStatus new_status) {
298 if (status == new_status) {
299 return;
300 }
301
302 status = new_status;
303 is_signaled = true;
304 WakeupAllWaitingThreads();
305}
306
271} // namespace Kernel 307} // namespace Kernel