mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 10:44:49 +01:00 
			
		
		
		
	hle: kernel: svc: Migrate GetThreadContext, GetThreadCoreMask.
This commit is contained in:
		
							parent
							
								
									76a0814142
								
							
						
					
					
						commit
						2cb6106523
					
				| @ -1100,7 +1100,55 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand | ||||
|     LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, | ||||
|               thread_handle); | ||||
| 
 | ||||
|     __debugbreak(); | ||||
|     auto& kernel = system.Kernel(); | ||||
| 
 | ||||
|     // Get the thread from its handle.
 | ||||
|     KScopedAutoObject thread = | ||||
|         kernel.CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); | ||||
|     R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); | ||||
| 
 | ||||
|     // Require the handle be to a non-current thread in the current process.
 | ||||
|     const auto* current_process = kernel.CurrentProcess(); | ||||
|     R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId); | ||||
| 
 | ||||
|     // Verify that the thread isn't terminated.
 | ||||
|     R_UNLESS(thread->GetState() != ThreadState::Terminated, ResultTerminationRequested); | ||||
| 
 | ||||
|     /// Check that the thread is not the current one.
 | ||||
|     /// NOTE: Nintendo does not check this, and thus the following loop will deadlock.
 | ||||
|     R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultInvalidId); | ||||
| 
 | ||||
|     // Try to get the thread context until the thread isn't current on any core.
 | ||||
|     while (true) { | ||||
|         KScopedSchedulerLock sl{kernel}; | ||||
| 
 | ||||
|         // TODO(bunnei): Enforce that thread is suspended for debug here.
 | ||||
| 
 | ||||
|         // If the thread's raw state isn't runnable, check if it's current on some core.
 | ||||
|         if (thread->GetRawState() != ThreadState::Runnable) { | ||||
|             bool current = false; | ||||
|             for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||||
|                 if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) { | ||||
|                     current = true; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             // If the thread is current, retry until it isn't.
 | ||||
|             if (current) { | ||||
|                 continue; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Get the thread context.
 | ||||
|         std::vector<u8> context; | ||||
|         R_TRY(thread->GetThreadContext3(context)); | ||||
| 
 | ||||
|         // Copy the thread context to user space.
 | ||||
|         system.Memory().WriteBlock(out_context, context.data(), context.size()); | ||||
| 
 | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| @ -1885,7 +1933,16 @@ static ResultCode CreateTransferMemory32(Core::System& system, Handle* handle, u | ||||
| 
 | ||||
| static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, | ||||
|                                     u64* out_affinity_mask) { | ||||
|     __debugbreak(); | ||||
|     LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); | ||||
| 
 | ||||
|     // Get the thread from its handle.
 | ||||
|     KScopedAutoObject thread = | ||||
|         system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); | ||||
|     R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); | ||||
| 
 | ||||
|     // Get the core mask.
 | ||||
|     R_TRY(thread->GetCoreMask(out_core_id, out_affinity_mask)); | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user