summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/object.cpp2
-rw-r--r--src/core/hle/kernel/process.cpp42
-rw-r--r--src/core/hle/kernel/process.h30
3 files changed, 68 insertions, 6 deletions
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index bb1b68778..0ea851a74 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -15,6 +15,7 @@ bool Object::IsWaitable() const {
15 switch (GetHandleType()) { 15 switch (GetHandleType()) {
16 case HandleType::ReadableEvent: 16 case HandleType::ReadableEvent:
17 case HandleType::Thread: 17 case HandleType::Thread:
18 case HandleType::Process:
18 case HandleType::Timer: 19 case HandleType::Timer:
19 case HandleType::ServerPort: 20 case HandleType::ServerPort:
20 case HandleType::ServerSession: 21 case HandleType::ServerSession:
@@ -23,7 +24,6 @@ bool Object::IsWaitable() const {
23 case HandleType::Unknown: 24 case HandleType::Unknown:
24 case HandleType::WritableEvent: 25 case HandleType::WritableEvent:
25 case HandleType::SharedMemory: 26 case HandleType::SharedMemory:
26 case HandleType::Process:
27 case HandleType::AddressArbiter: 27 case HandleType::AddressArbiter:
28 case HandleType::ResourceLimit: 28 case HandleType::ResourceLimit:
29 case HandleType::ClientPort: 29 case HandleType::ClientPort:
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
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 49345aa66..bcb9ac4b8 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -14,9 +14,10 @@
14#include "common/bit_field.h" 14#include "common/bit_field.h"
15#include "common/common_types.h" 15#include "common/common_types.h"
16#include "core/hle/kernel/handle_table.h" 16#include "core/hle/kernel/handle_table.h"
17#include "core/hle/kernel/object.h"
18#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
19#include "core/hle/kernel/vm_manager.h" 18#include "core/hle/kernel/vm_manager.h"
19#include "core/hle/kernel/wait_object.h"
20#include "core/hle/result.h"
20 21
21namespace FileSys { 22namespace FileSys {
22class ProgramMetadata; 23class ProgramMetadata;
@@ -117,7 +118,7 @@ struct CodeSet final {
117 VAddr entrypoint = 0; 118 VAddr entrypoint = 0;
118}; 119};
119 120
120class Process final : public Object { 121class Process final : public WaitObject {
121public: 122public:
122 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; 123 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
123 124
@@ -212,6 +213,16 @@ public:
212 return random_entropy.at(index); 213 return random_entropy.at(index);
213 } 214 }
214 215
216 /// Clears the signaled state of the process if and only if it's signaled.
217 ///
218 /// @pre The process must not be already terminated. If this is called on a
219 /// terminated process, then ERR_INVALID_STATE will be returned.
220 ///
221 /// @pre The process must be in a signaled state. If this is called on a
222 /// process instance that is not signaled, ERR_INVALID_STATE will be
223 /// returned.
224 ResultCode ClearSignalState();
225
215 /** 226 /**
216 * Loads process-specifics configuration info with metadata provided 227 * Loads process-specifics configuration info with metadata provided
217 * by an executable. 228 * by an executable.
@@ -260,6 +271,17 @@ private:
260 explicit Process(KernelCore& kernel); 271 explicit Process(KernelCore& kernel);
261 ~Process() override; 272 ~Process() override;
262 273
274 /// Checks if the specified thread should wait until this process is available.
275 bool ShouldWait(Thread* thread) const override;
276
277 /// Acquires/locks this process for the specified thread if it's available.
278 void Acquire(Thread* thread) override;
279
280 /// Changes the process status. If the status is different
281 /// from the current process status, then this will trigger
282 /// a process signal.
283 void ChangeStatus(ProcessStatus new_status);
284
263 /// Memory manager for this process. 285 /// Memory manager for this process.
264 Kernel::VMManager vm_manager; 286 Kernel::VMManager vm_manager;
265 287
@@ -305,6 +327,10 @@ private:
305 /// specified by metadata provided to the process during loading. 327 /// specified by metadata provided to the process during loading.
306 bool is_64bit_process = true; 328 bool is_64bit_process = true;
307 329
330 /// Whether or not this process is signaled. This occurs
331 /// upon the process changing to a different state.
332 bool is_signaled = false;
333
308 /// Total running time for the process in ticks. 334 /// Total running time for the process in ticks.
309 u64 total_process_running_time_ticks = 0; 335 u64 total_process_running_time_ticks = 0;
310 336