diff options
| author | 2019-03-20 18:53:48 -0400 | |
|---|---|---|
| committer | 2019-04-02 00:48:40 -0400 | |
| commit | 28719ee3b4884d182126bddf639e1711b0744b22 (patch) | |
| tree | 3c8f4310e23117c330979c2c149d24a82104f04c /src/core/hle/kernel/svc.cpp | |
| parent | kernel/svc: Implement svcGetProcessList (diff) | |
| download | yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.gz yuzu-28719ee3b4884d182126bddf639e1711b0744b22.tar.xz yuzu-28719ee3b4884d182126bddf639e1711b0744b22.zip | |
kernel/svc: Implement svcGetThreadList
Similarly like svcGetProcessList, this retrieves the list of threads
from the current process. In the kernel itself, a process instance
maintains a list of threads, which are used within this function.
Threads are registered to a process' thread list at thread
initialization, and unregistered from the list upon thread destruction
(if said thread has a non-null owning process).
We assert on the debug event case, as we currently don't implement
kernel debug objects.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 3cd948bb5..23c768f57 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -2020,6 +2020,46 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids, | |||
| 2020 | return RESULT_SUCCESS; | 2020 | return RESULT_SUCCESS; |
| 2021 | } | 2021 | } |
| 2022 | 2022 | ||
| 2023 | ResultCode 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 | |||
| 2023 | namespace { | 2063 | namespace { |
| 2024 | struct FunctionDef { | 2064 | struct FunctionDef { |
| 2025 | using Func = void(); | 2065 | using Func = void(); |
| @@ -2133,7 +2173,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 2133 | {0x63, nullptr, "GetDebugEvent"}, | 2173 | {0x63, nullptr, "GetDebugEvent"}, |
| 2134 | {0x64, nullptr, "ContinueDebugEvent"}, | 2174 | {0x64, nullptr, "ContinueDebugEvent"}, |
| 2135 | {0x65, SvcWrap<GetProcessList>, "GetProcessList"}, | 2175 | {0x65, SvcWrap<GetProcessList>, "GetProcessList"}, |
| 2136 | {0x66, nullptr, "GetThreadList"}, | 2176 | {0x66, SvcWrap<GetThreadList>, "GetThreadList"}, |
| 2137 | {0x67, nullptr, "GetDebugThreadContext"}, | 2177 | {0x67, nullptr, "GetDebugThreadContext"}, |
| 2138 | {0x68, nullptr, "SetDebugThreadContext"}, | 2178 | {0x68, nullptr, "SetDebugThreadContext"}, |
| 2139 | {0x69, nullptr, "QueryDebugProcessMemory"}, | 2179 | {0x69, nullptr, "QueryDebugProcessMemory"}, |