diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 29 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 32 |
3 files changed, 56 insertions, 32 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0c8ea94fc..121f741fd 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -7,10 +7,12 @@ | |||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "core/core.h" | ||
| 10 | #include "core/hle/kernel/errors.h" | 11 | #include "core/hle/kernel/errors.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 12 | #include "core/hle/kernel/process.h" | 13 | #include "core/hle/kernel/process.h" |
| 13 | #include "core/hle/kernel/resource_limit.h" | 14 | #include "core/hle/kernel/resource_limit.h" |
| 15 | #include "core/hle/kernel/scheduler.h" | ||
| 14 | #include "core/hle/kernel/thread.h" | 16 | #include "core/hle/kernel/thread.h" |
| 15 | #include "core/hle/kernel/vm_manager.h" | 17 | #include "core/hle/kernel/vm_manager.h" |
| 16 | #include "core/memory.h" | 18 | #include "core/memory.h" |
| @@ -128,6 +130,33 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 128 | Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this); | 130 | Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this); |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 133 | void Process::PrepareForTermination() { | ||
| 134 | status = ProcessStatus::Exited; | ||
| 135 | |||
| 136 | const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) { | ||
| 137 | for (auto& thread : thread_list) { | ||
| 138 | if (thread->owner_process != this) | ||
| 139 | continue; | ||
| 140 | |||
| 141 | if (thread == GetCurrentThread()) | ||
| 142 | continue; | ||
| 143 | |||
| 144 | // TODO(Subv): When are the other running/ready threads terminated? | ||
| 145 | ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny || | ||
| 146 | thread->status == ThreadStatus::WaitSynchAll, | ||
| 147 | "Exiting processes with non-waiting threads is currently unimplemented"); | ||
| 148 | |||
| 149 | thread->Stop(); | ||
| 150 | } | ||
| 151 | }; | ||
| 152 | |||
| 153 | auto& system = Core::System::GetInstance(); | ||
| 154 | stop_threads(system.Scheduler(0)->GetThreadList()); | ||
| 155 | stop_threads(system.Scheduler(1)->GetThreadList()); | ||
| 156 | stop_threads(system.Scheduler(2)->GetThreadList()); | ||
| 157 | stop_threads(system.Scheduler(3)->GetThreadList()); | ||
| 158 | } | ||
| 159 | |||
| 131 | /** | 160 | /** |
| 132 | * Finds a free location for the TLS section of a thread. | 161 | * Finds a free location for the TLS section of a thread. |
| 133 | * @param tls_slots The TLS page array of the thread's owner process. | 162 | * @param tls_slots The TLS page array of the thread's owner process. |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 84027a31a..04d74e572 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -131,6 +131,16 @@ public: | |||
| 131 | return HANDLE_TYPE; | 131 | return HANDLE_TYPE; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | /// Gets the current status of the process | ||
| 135 | ProcessStatus GetStatus() const { | ||
| 136 | return status; | ||
| 137 | } | ||
| 138 | |||
| 139 | /// Gets the unique ID that identifies this particular process. | ||
| 140 | u32 GetProcessID() const { | ||
| 141 | return process_id; | ||
| 142 | } | ||
| 143 | |||
| 134 | /// Title ID corresponding to the process | 144 | /// Title ID corresponding to the process |
| 135 | u64 program_id; | 145 | u64 program_id; |
| 136 | 146 | ||
| @@ -154,11 +164,6 @@ public: | |||
| 154 | u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK; | 164 | u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK; |
| 155 | u32 allowed_thread_priority_mask = 0xFFFFFFFF; | 165 | u32 allowed_thread_priority_mask = 0xFFFFFFFF; |
| 156 | u32 is_virtual_address_memory_enabled = 0; | 166 | u32 is_virtual_address_memory_enabled = 0; |
| 157 | /// Current status of the process | ||
| 158 | ProcessStatus status; | ||
| 159 | |||
| 160 | /// The ID of this process | ||
| 161 | u32 process_id = 0; | ||
| 162 | 167 | ||
| 163 | /** | 168 | /** |
| 164 | * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them | 169 | * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them |
| @@ -171,6 +176,12 @@ public: | |||
| 171 | */ | 176 | */ |
| 172 | void Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size); | 177 | void Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size); |
| 173 | 178 | ||
| 179 | /** | ||
| 180 | * Prepares a process for termination by stopping all of its threads | ||
| 181 | * and clearing any other resources. | ||
| 182 | */ | ||
| 183 | void PrepareForTermination(); | ||
| 184 | |||
| 174 | void LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr); | 185 | void LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr); |
| 175 | 186 | ||
| 176 | /////////////////////////////////////////////////////////////////////////////////////////////// | 187 | /////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -195,6 +206,12 @@ private: | |||
| 195 | explicit Process(KernelCore& kernel); | 206 | explicit Process(KernelCore& kernel); |
| 196 | ~Process() override; | 207 | ~Process() override; |
| 197 | 208 | ||
| 209 | /// Current status of the process | ||
| 210 | ProcessStatus status; | ||
| 211 | |||
| 212 | /// The ID of this process | ||
| 213 | u32 process_id = 0; | ||
| 214 | |||
| 198 | // Memory used to back the allocations in the regular heap. A single vector is used to cover | 215 | // Memory used to back the allocations in the regular heap. A single vector is used to cover |
| 199 | // the entire virtual address space extents that bound the allocations, including any holes. | 216 | // the entire virtual address space extents that bound the allocations, including any holes. |
| 200 | // This makes deallocation and reallocation of holes fast and keeps process memory contiguous | 217 | // This makes deallocation and reallocation of holes fast and keeps process memory contiguous |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 371fc439e..0bc407098 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -169,7 +169,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | |||
| 169 | return ERR_INVALID_HANDLE; | 169 | return ERR_INVALID_HANDLE; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | *process_id = process->process_id; | 172 | *process_id = process->GetProcessID(); |
| 173 | return RESULT_SUCCESS; | 173 | return RESULT_SUCCESS; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| @@ -530,35 +530,13 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd | |||
| 530 | 530 | ||
| 531 | /// Exits the current process | 531 | /// Exits the current process |
| 532 | static void ExitProcess() { | 532 | static void ExitProcess() { |
| 533 | LOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id); | 533 | auto& current_process = Core::CurrentProcess(); |
| 534 | 534 | ||
| 535 | ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running, | 535 | LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); |
| 536 | ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, | ||
| 536 | "Process has already exited"); | 537 | "Process has already exited"); |
| 537 | 538 | ||
| 538 | Core::CurrentProcess()->status = ProcessStatus::Exited; | 539 | current_process->PrepareForTermination(); |
| 539 | |||
| 540 | auto stop_threads = [](const std::vector<SharedPtr<Thread>>& thread_list) { | ||
| 541 | for (auto& thread : thread_list) { | ||
| 542 | if (thread->owner_process != Core::CurrentProcess()) | ||
| 543 | continue; | ||
| 544 | |||
| 545 | if (thread == GetCurrentThread()) | ||
| 546 | continue; | ||
| 547 | |||
| 548 | // TODO(Subv): When are the other running/ready threads terminated? | ||
| 549 | ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny || | ||
| 550 | thread->status == ThreadStatus::WaitSynchAll, | ||
| 551 | "Exiting processes with non-waiting threads is currently unimplemented"); | ||
| 552 | |||
| 553 | thread->Stop(); | ||
| 554 | } | ||
| 555 | }; | ||
| 556 | |||
| 557 | auto& system = Core::System::GetInstance(); | ||
| 558 | stop_threads(system.Scheduler(0)->GetThreadList()); | ||
| 559 | stop_threads(system.Scheduler(1)->GetThreadList()); | ||
| 560 | stop_threads(system.Scheduler(2)->GetThreadList()); | ||
| 561 | stop_threads(system.Scheduler(3)->GetThreadList()); | ||
| 562 | 540 | ||
| 563 | // Kill the current thread | 541 | // Kill the current thread |
| 564 | GetCurrentThread()->Stop(); | 542 | GetCurrentThread()->Stop(); |