summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-01 14:38:34 -0500
committerGravatar bunnei2018-01-01 14:38:34 -0500
commitaa7c824ea422152e3e8ac4586a9b94d2c755c23d (patch)
tree31dbb609273a9bb4b66b3f40ef0de6fabe7daf2e /src
parentsvc: Implement svcUnlockMutex. (diff)
downloadyuzu-aa7c824ea422152e3e8ac4586a9b94d2c755c23d.tar.gz
yuzu-aa7c824ea422152e3e8ac4586a9b94d2c755c23d.tar.xz
yuzu-aa7c824ea422152e3e8ac4586a9b94d2c755c23d.zip
svc: Implement svcExitProcess.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/process.cpp32
-rw-r--r--src/core/hle/kernel/process.h13
-rw-r--r--src/core/hle/svc.cpp43
3 files changed, 77 insertions, 11 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 35cf6dc95..8e74059ea 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <memory> 6#include <memory>
6#include "common/assert.h" 7#include "common/assert.h"
7#include "common/common_funcs.h" 8#include "common/common_funcs.h"
@@ -16,6 +17,9 @@
16 17
17namespace Kernel { 18namespace Kernel {
18 19
20// Lists all processes that exist in the current session.
21static std::vector<SharedPtr<Process>> process_list;
22
19SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) { 23SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
20 SharedPtr<CodeSet> codeset(new CodeSet); 24 SharedPtr<CodeSet> codeset(new CodeSet);
21 25
@@ -36,7 +40,9 @@ SharedPtr<Process> Process::Create(std::string&& name) {
36 process->name = std::move(name); 40 process->name = std::move(name);
37 process->flags.raw = 0; 41 process->flags.raw = 0;
38 process->flags.memory_region.Assign(MemoryRegion::APPLICATION); 42 process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
43 process->status = ProcessStatus::Created;
39 44
45 process_list.push_back(process);
40 return process; 46 return process;
41} 47}
42 48
@@ -129,6 +135,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
129 } 135 }
130 136
131 vm_manager.LogLayout(Log::Level::Debug); 137 vm_manager.LogLayout(Log::Level::Debug);
138 status = ProcessStatus::Running;
132 139
133 Kernel::SetupMainThread(entry_point, main_thread_priority, this); 140 Kernel::SetupMainThread(entry_point, main_thread_priority, this);
134} 141}
@@ -137,11 +144,11 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
137 memory_region = GetMemoryRegion(flags.memory_region); 144 memory_region = GetMemoryRegion(flags.memory_region);
138 145
139 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, 146 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
140 MemoryState memory_state) { 147 MemoryState memory_state) {
141 auto vma = vm_manager 148 auto vma = vm_manager
142 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, segment.size, 149 .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset,
143 memory_state) 150 segment.size, memory_state)
144 .Unwrap(); 151 .Unwrap();
145 vm_manager.Reprotect(vma, permissions); 152 vm_manager.Reprotect(vma, permissions);
146 misc_memory_used += segment.size; 153 misc_memory_used += segment.size;
147 memory_region->used += segment.size; 154 memory_region->used += segment.size;
@@ -299,5 +306,20 @@ ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {
299Kernel::Process::Process() {} 306Kernel::Process::Process() {}
300Kernel::Process::~Process() {} 307Kernel::Process::~Process() {}
301 308
302SharedPtr<Process> g_current_process; 309void ClearProcessList() {
310 process_list.clear();
311}
312
313SharedPtr<Process> GetProcessById(u32 process_id) {
314 auto itr = std::find_if(
315 process_list.begin(), process_list.end(),
316 [&](const SharedPtr<Process>& process) { return process->process_id == process_id; });
317
318 if (itr == process_list.end())
319 return nullptr;
320
321 return *itr;
303} 322}
323
324SharedPtr<Process> g_current_process;
325} // namespace Kernel
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 3ea8c298f..305275387 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -8,6 +8,7 @@
8#include <cstddef> 8#include <cstddef>
9#include <memory> 9#include <memory>
10#include <string> 10#include <string>
11#include <vector>
11#include <boost/container/static_vector.hpp> 12#include <boost/container/static_vector.hpp>
12#include "common/bit_field.h" 13#include "common/bit_field.h"
13#include "common/common_types.h" 14#include "common/common_types.h"
@@ -48,6 +49,8 @@ union ProcessFlags {
48 BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). 49 BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
49}; 50};
50 51
52enum class ProcessStatus { Created, Running, Exited };
53
51class ResourceLimit; 54class ResourceLimit;
52struct MemoryRegionInfo; 55struct MemoryRegionInfo;
53 56
@@ -124,6 +127,8 @@ public:
124 u16 kernel_version = 0; 127 u16 kernel_version = 0;
125 /// The default CPU for this process, threads are scheduled on this cpu by default. 128 /// The default CPU for this process, threads are scheduled on this cpu by default.
126 u8 ideal_processor = 0; 129 u8 ideal_processor = 0;
130 /// Current status of the process
131 ProcessStatus status;
127 132
128 /// The id of this process 133 /// The id of this process
129 u32 process_id = next_process_id++; 134 u32 process_id = next_process_id++;
@@ -181,11 +186,15 @@ public:
181 186
182 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 187 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
183 188
184
185private: 189private:
186 Process(); 190 Process();
187 ~Process() override; 191 ~Process() override;
188}; 192};
189 193
194void ClearProcessList();
195
196/// Retrieves a process from the current list of processes.
197SharedPtr<Process> GetProcessById(u32 process_id);
198
190extern SharedPtr<Process> g_current_process; 199extern SharedPtr<Process> g_current_process;
191} 200} // namespace Kernel
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index cba94eac3..1ba61d807 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -9,6 +9,8 @@
9#include "core/hle/kernel/client_port.h" 9#include "core/hle/kernel/client_port.h"
10#include "core/hle/kernel/client_session.h" 10#include "core/hle/kernel/client_session.h"
11#include "core/hle/kernel/handle_table.h" 11#include "core/hle/kernel/handle_table.h"
12#include "core/hle/kernel/mutex.h"
13#include "core/hle/kernel/object_address_table.h"
12#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 15#include "core/hle/kernel/resource_limit.h"
14#include "core/hle/kernel/sync_object.h" 16#include "core/hle/kernel/sync_object.h"
@@ -45,7 +47,7 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
45/// Unmaps a region that was previously mapped with svcMapMemory 47/// Unmaps a region that was previously mapped with svcMapMemory
46static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 48static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
47 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr, 49 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
48 src_addr, size); 50 src_addr, size);
49 return Kernel::g_current_process->UnmapMemory(dst_addr, src_addr, size); 51 return Kernel::g_current_process->UnmapMemory(dst_addr, src_addr, size);
50} 52}
51 53
@@ -99,7 +101,8 @@ static ResultCode SendSyncRequest(Kernel::Handle handle) {
99static ResultCode GetThreadId(u32* thread_id, Kernel::Handle thread_handle) { 101static ResultCode GetThreadId(u32* thread_id, Kernel::Handle thread_handle) {
100 LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); 102 LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
101 103
102 const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle); 104 const SharedPtr<Kernel::Thread> thread =
105 Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle);
103 if (!thread) { 106 if (!thread) {
104 return ERR_INVALID_HANDLE; 107 return ERR_INVALID_HANDLE;
105 } 108 }
@@ -177,7 +180,7 @@ static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
177} 180}
178 181
179/// Used to output a message on a debug hardware unit - does nothing on a retail unit 182/// Used to output a message on a debug hardware unit - does nothing on a retail unit
180static void OutputDebugString(VAddr address, int len) { 183static void OutputDebugString(VAddr address, s32 len) {
181 std::vector<char> string(len); 184 std::vector<char> string(len);
182 Memory::ReadBlock(address, string.data(), len); 185 Memory::ReadBlock(address, string.data(), len);
183 LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data()); 186 LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
@@ -272,6 +275,38 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
272 return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr); 275 return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr);
273} 276}
274 277
278/// Exits the current process
279static void ExitProcess() {
280 LOG_INFO(Kernel_SVC, "Process %u exiting", Kernel::g_current_process->process_id);
281
282 ASSERT_MSG(Kernel::g_current_process->status == Kernel::ProcessStatus::Running,
283 "Process has already exited");
284
285 Kernel::g_current_process->status = Kernel::ProcessStatus::Exited;
286
287 // Stop all the process threads that are currently waiting for objects.
288 auto& thread_list = Kernel::GetThreadList();
289 for (auto& thread : thread_list) {
290 if (thread->owner_process != Kernel::g_current_process)
291 continue;
292
293 if (thread == Kernel::GetCurrentThread())
294 continue;
295
296 // TODO(Subv): When are the other running/ready threads terminated?
297 ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
298 thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
299 "Exiting processes with non-waiting threads is currently unimplemented");
300
301 thread->Stop();
302 }
303
304 // Kill the current thread
305 Kernel::GetCurrentThread()->Stop();
306
307 Core::System::GetInstance().PrepareReschedule();
308}
309
275/// Creates a new thread 310/// Creates a new thread
276static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, 311static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top,
277 u32 priority, s32 processor_id) { 312 u32 priority, s32 processor_id) {
@@ -400,7 +435,7 @@ static const FunctionDef SVC_Table[] = {
400 {0x04, HLE::Wrap<MapMemory>, "svcMapMemory"}, 435 {0x04, HLE::Wrap<MapMemory>, "svcMapMemory"},
401 {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"}, 436 {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"},
402 {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"}, 437 {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"},
403 {0x07, nullptr, "svcExitProcess"}, 438 {0x07, HLE::Wrap<ExitProcess>, "svcExitProcess"},
404 {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"}, 439 {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"},
405 {0x09, HLE::Wrap<StartThread>, "svcStartThread"}, 440 {0x09, HLE::Wrap<StartThread>, "svcStartThread"},
406 {0x0A, HLE::Wrap<ExitThread>, "svcExitThread"}, 441 {0x0A, HLE::Wrap<ExitThread>, "svcExitThread"},