summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2021-04-11 12:49:51 -0700
committerGravatar bunnei2021-05-05 16:40:51 -0700
commit2cb6106523a87ae78d3a6b92c34b3b1d2817415e (patch)
tree64303177f862736efc1cdd4d22475c4f428458a1
parenthle: kernel: svc: Migrate GetProcessId, CancelSynchronization, SetThreadActiv... (diff)
downloadyuzu-2cb6106523a87ae78d3a6b92c34b3b1d2817415e.tar.gz
yuzu-2cb6106523a87ae78d3a6b92c34b3b1d2817415e.tar.xz
yuzu-2cb6106523a87ae78d3a6b92c34b3b1d2817415e.zip
hle: kernel: svc: Migrate GetThreadContext, GetThreadCoreMask.
-rw-r--r--src/core/hle/kernel/svc.cpp61
1 files changed, 59 insertions, 2 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index fae4c7209..b83ee3e69 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1100,7 +1100,55 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand
1100 LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, 1100 LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context,
1101 thread_handle); 1101 thread_handle);
1102 1102
1103 __debugbreak(); 1103 auto& kernel = system.Kernel();
1104
1105 // Get the thread from its handle.
1106 KScopedAutoObject thread =
1107 kernel.CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle);
1108 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
1109
1110 // Require the handle be to a non-current thread in the current process.
1111 const auto* current_process = kernel.CurrentProcess();
1112 R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId);
1113
1114 // Verify that the thread isn't terminated.
1115 R_UNLESS(thread->GetState() != ThreadState::Terminated, ResultTerminationRequested);
1116
1117 /// Check that the thread is not the current one.
1118 /// NOTE: Nintendo does not check this, and thus the following loop will deadlock.
1119 R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultInvalidId);
1120
1121 // Try to get the thread context until the thread isn't current on any core.
1122 while (true) {
1123 KScopedSchedulerLock sl{kernel};
1124
1125 // TODO(bunnei): Enforce that thread is suspended for debug here.
1126
1127 // If the thread's raw state isn't runnable, check if it's current on some core.
1128 if (thread->GetRawState() != ThreadState::Runnable) {
1129 bool current = false;
1130 for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) {
1131 if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) {
1132 current = true;
1133 }
1134 break;
1135 }
1136
1137 // If the thread is current, retry until it isn't.
1138 if (current) {
1139 continue;
1140 }
1141 }
1142
1143 // Get the thread context.
1144 std::vector<u8> context;
1145 R_TRY(thread->GetThreadContext3(context));
1146
1147 // Copy the thread context to user space.
1148 system.Memory().WriteBlock(out_context, context.data(), context.size());
1149
1150 return RESULT_SUCCESS;
1151 }
1104 1152
1105 return RESULT_SUCCESS; 1153 return RESULT_SUCCESS;
1106} 1154}
@@ -1885,7 +1933,16 @@ static ResultCode CreateTransferMemory32(Core::System& system, Handle* handle, u
1885 1933
1886static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, 1934static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id,
1887 u64* out_affinity_mask) { 1935 u64* out_affinity_mask) {
1888 __debugbreak(); 1936 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
1937
1938 // Get the thread from its handle.
1939 KScopedAutoObject thread =
1940 system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle);
1941 R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
1942
1943 // Get the core mask.
1944 R_TRY(thread->GetCoreMask(out_core_id, out_affinity_mask));
1945
1889 return RESULT_SUCCESS; 1946 return RESULT_SUCCESS;
1890} 1947}
1891 1948