summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2019-04-02 21:40:39 -0400
committerGravatar GitHub2019-04-02 21:40:39 -0400
commite796351a0de70d75993e326b8828229416216d91 (patch)
tree0f5b340a115a98383202f3a848987ddd3ce361b2
parentMerge pull request #2313 from lioncash/reslimit (diff)
parentkernel/svc: Implement svcGetThreadList (diff)
downloadyuzu-e796351a0de70d75993e326b8828229416216d91.tar.gz
yuzu-e796351a0de70d75993e326b8828229416216d91.tar.xz
yuzu-e796351a0de70d75993e326b8828229416216d91.zip
Merge pull request #2270 from lioncash/plist
kernel/svc: Implement svcGetProcessList and svcGetThreadList
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/kernel.cpp4
-rw-r--r--src/core/hle/kernel/kernel.h3
-rw-r--r--src/core/hle/kernel/process.cpp8
-rw-r--r--src/core/hle/kernel/process.h17
-rw-r--r--src/core/hle/kernel/svc.cpp81
-rw-r--r--src/core/hle/kernel/svc_wrap.h8
-rw-r--r--src/core/hle/kernel/thread.cpp4
7 files changed, 123 insertions, 2 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index f4339a5cd..3f14bfa86 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -191,6 +191,10 @@ const Process* KernelCore::CurrentProcess() const {
191 return impl->current_process; 191 return impl->current_process;
192} 192}
193 193
194const std::vector<SharedPtr<Process>>& KernelCore::GetProcessList() const {
195 return impl->process_list;
196}
197
194void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) { 198void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
195 impl->named_ports.emplace(std::move(name), std::move(port)); 199 impl->named_ports.emplace(std::move(name), std::move(port));
196} 200}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 03ea5b659..6b8738599 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -72,6 +72,9 @@ public:
72 /// Retrieves a const pointer to the current process. 72 /// Retrieves a const pointer to the current process.
73 const Process* CurrentProcess() const; 73 const Process* CurrentProcess() const;
74 74
75 /// Retrieves the list of processes.
76 const std::vector<SharedPtr<Process>>& GetProcessList() const;
77
75 /// Adds a port to the named port table 78 /// Adds a port to the named port table
76 void AddNamedPort(std::string name, SharedPtr<ClientPort> port); 79 void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
77 80
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 955769503..52f253d1e 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -80,6 +80,14 @@ u64 Process::GetTotalPhysicalMemoryUsed() const {
80 return vm_manager.GetCurrentHeapSize() + main_thread_stack_size + code_memory_size; 80 return vm_manager.GetCurrentHeapSize() + main_thread_stack_size + code_memory_size;
81} 81}
82 82
83void Process::RegisterThread(const Thread* thread) {
84 thread_list.push_back(thread);
85}
86
87void Process::UnregisterThread(const Thread* thread) {
88 thread_list.remove(thread);
89}
90
83ResultCode Process::ClearSignalState() { 91ResultCode Process::ClearSignalState() {
84 if (status == ProcessStatus::Exited) { 92 if (status == ProcessStatus::Exited) {
85 LOG_ERROR(Kernel, "called on a terminated process instance."); 93 LOG_ERROR(Kernel, "called on a terminated process instance.");
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 732d12170..f9ddc937c 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8#include <bitset> 8#include <bitset>
9#include <cstddef> 9#include <cstddef>
10#include <list>
10#include <string> 11#include <string>
11#include <vector> 12#include <vector>
12#include <boost/container/static_vector.hpp> 13#include <boost/container/static_vector.hpp>
@@ -189,6 +190,19 @@ public:
189 /// Retrieves the total physical memory used by this process in bytes. 190 /// Retrieves the total physical memory used by this process in bytes.
190 u64 GetTotalPhysicalMemoryUsed() const; 191 u64 GetTotalPhysicalMemoryUsed() const;
191 192
193 /// Gets the list of all threads created with this process as their owner.
194 const std::list<const Thread*>& GetThreadList() const {
195 return thread_list;
196 }
197
198 /// Registers a thread as being created under this process,
199 /// adding it to this process' thread list.
200 void RegisterThread(const Thread* thread);
201
202 /// Unregisters a thread from this process, removing it
203 /// from this process' thread list.
204 void UnregisterThread(const Thread* thread);
205
192 /// Clears the signaled state of the process if and only if it's signaled. 206 /// Clears the signaled state of the process if and only if it's signaled.
193 /// 207 ///
194 /// @pre The process must not be already terminated. If this is called on a 208 /// @pre The process must not be already terminated. If this is called on a
@@ -308,6 +322,9 @@ private:
308 /// Random values for svcGetInfo RandomEntropy 322 /// Random values for svcGetInfo RandomEntropy
309 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy; 323 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;
310 324
325 /// List of threads that are running with this process as their owner.
326 std::list<const Thread*> thread_list;
327
311 /// System context 328 /// System context
312 Core::System& system; 329 Core::System& system;
313 330
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 76a8b0191..23c768f57 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1983,6 +1983,83 @@ static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource
1983 return RESULT_SUCCESS; 1983 return RESULT_SUCCESS;
1984} 1984}
1985 1985
1986static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
1987 u32 out_process_ids_size) {
1988 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
1989 out_process_ids, out_process_ids_size);
1990
1991 // If the supplied size is negative or greater than INT32_MAX / sizeof(u64), bail.
1992 if ((out_process_ids_size & 0xF0000000) != 0) {
1993 LOG_ERROR(Kernel_SVC,
1994 "Supplied size outside [0, 0x0FFFFFFF] range. out_process_ids_size={}",
1995 out_process_ids_size);
1996 return ERR_OUT_OF_RANGE;
1997 }
1998
1999 const auto& kernel = Core::System::GetInstance().Kernel();
2000 const auto& vm_manager = kernel.CurrentProcess()->VMManager();
2001 const auto total_copy_size = out_process_ids_size * sizeof(u64);
2002
2003 if (out_process_ids_size > 0 &&
2004 !vm_manager.IsWithinAddressSpace(out_process_ids, total_copy_size)) {
2005 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
2006 out_process_ids, out_process_ids + total_copy_size);
2007 return ERR_INVALID_ADDRESS_STATE;
2008 }
2009
2010 const auto& process_list = kernel.GetProcessList();
2011 const auto num_processes = process_list.size();
2012 const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes);
2013
2014 for (std::size_t i = 0; i < copy_amount; ++i) {
2015 Memory::Write64(out_process_ids, process_list[i]->GetProcessID());
2016 out_process_ids += sizeof(u64);
2017 }
2018
2019 *out_num_processes = static_cast<u32>(num_processes);
2020 return RESULT_SUCCESS;
2021}
2022
2023ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thread_ids_size,
2024 Handle debug_handle) {
2025 // TODO: Handle this case when debug events are supported.
2026 UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
2027
2028 LOG_DEBUG(Kernel_SVC, "called. out_thread_ids=0x{:016X}, out_thread_ids_size={}",
2029 out_thread_ids, out_thread_ids_size);
2030
2031 // If the size is negative or larger than INT32_MAX / sizeof(u64)
2032 if ((out_thread_ids_size & 0xF0000000) != 0) {
2033 LOG_ERROR(Kernel_SVC, "Supplied size outside [0, 0x0FFFFFFF] range. size={}",
2034 out_thread_ids_size);
2035 return ERR_OUT_OF_RANGE;
2036 }
2037
2038 const auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess();
2039 const auto& vm_manager = current_process->VMManager();
2040 const auto total_copy_size = out_thread_ids_size * sizeof(u64);
2041
2042 if (out_thread_ids_size > 0 &&
2043 !vm_manager.IsWithinAddressSpace(out_thread_ids, total_copy_size)) {
2044 LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
2045 out_thread_ids, out_thread_ids + total_copy_size);
2046 return ERR_INVALID_ADDRESS_STATE;
2047 }
2048
2049 const auto& thread_list = current_process->GetThreadList();
2050 const auto num_threads = thread_list.size();
2051 const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads);
2052
2053 auto list_iter = thread_list.cbegin();
2054 for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) {
2055 Memory::Write64(out_thread_ids, (*list_iter)->GetThreadID());
2056 out_thread_ids += sizeof(u64);
2057 }
2058
2059 *out_num_threads = static_cast<u32>(num_threads);
2060 return RESULT_SUCCESS;
2061}
2062
1986namespace { 2063namespace {
1987struct FunctionDef { 2064struct FunctionDef {
1988 using Func = void(); 2065 using Func = void();
@@ -2095,8 +2172,8 @@ static const FunctionDef SVC_Table[] = {
2095 {0x62, nullptr, "TerminateDebugProcess"}, 2172 {0x62, nullptr, "TerminateDebugProcess"},
2096 {0x63, nullptr, "GetDebugEvent"}, 2173 {0x63, nullptr, "GetDebugEvent"},
2097 {0x64, nullptr, "ContinueDebugEvent"}, 2174 {0x64, nullptr, "ContinueDebugEvent"},
2098 {0x65, nullptr, "GetProcessList"}, 2175 {0x65, SvcWrap<GetProcessList>, "GetProcessList"},
2099 {0x66, nullptr, "GetThreadList"}, 2176 {0x66, SvcWrap<GetThreadList>, "GetThreadList"},
2100 {0x67, nullptr, "GetDebugThreadContext"}, 2177 {0x67, nullptr, "GetDebugThreadContext"},
2101 {0x68, nullptr, "SetDebugThreadContext"}, 2178 {0x68, nullptr, "SetDebugThreadContext"},
2102 {0x69, nullptr, "QueryDebugProcessMemory"}, 2179 {0x69, nullptr, "QueryDebugProcessMemory"},
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 2a2c2c5ea..b3733680f 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -78,6 +78,14 @@ void SvcWrap() {
78 FuncReturn(retval); 78 FuncReturn(retval);
79} 79}
80 80
81template <ResultCode func(u32*, u64, u32)>
82void SvcWrap() {
83 u32 param_1 = 0;
84 const u32 retval = func(&param_1, Param(1), static_cast<u32>(Param(2))).raw;
85 Core::CurrentArmInterface().SetReg(1, param_1);
86 FuncReturn(retval);
87}
88
81template <ResultCode func(u64*, u32)> 89template <ResultCode func(u64*, u32)>
82void SvcWrap() { 90void SvcWrap() {
83 u64 param_1 = 0; 91 u64 param_1 = 0;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index fa3ac3abc..3ec3710b2 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -62,6 +62,8 @@ void Thread::Stop() {
62 } 62 }
63 wait_objects.clear(); 63 wait_objects.clear();
64 64
65 owner_process->UnregisterThread(this);
66
65 // Mark the TLS slot in the thread's page as free. 67 // Mark the TLS slot in the thread's page as free.
66 owner_process->FreeTLSSlot(tls_address); 68 owner_process->FreeTLSSlot(tls_address);
67} 69}
@@ -202,6 +204,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
202 thread->scheduler->AddThread(thread); 204 thread->scheduler->AddThread(thread);
203 thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread); 205 thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread);
204 206
207 thread->owner_process->RegisterThread(thread.get());
208
205 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used 209 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
206 // to initialize the context 210 // to initialize the context
207 ResetThreadContext(thread->context, stack_top, entry_point, arg); 211 ResetThreadContext(thread->context, stack_top, entry_point, arg);