forked from eden-emu/eden
		
	SVC: Correct CreateThread, StartThread, ExitThread, SleepThread.
This commit is contained in:
		
							parent
							
								
									fb1d75a788
								
							
						
					
					
						commit
						451344e9ae
					
				
					 3 changed files with 31 additions and 37 deletions
				
			
		|  | @ -1464,13 +1464,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | |||
| 
 | ||||
|     ASSERT(thread->GetStatus() == ThreadStatus::Dormant); | ||||
| 
 | ||||
|     thread->ResumeFromWait(); | ||||
| 
 | ||||
|     if (thread->GetStatus() == ThreadStatus::Ready) { | ||||
|         system.PrepareReschedule(thread->GetProcessorID()); | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
|     return thread->Start(); | ||||
| } | ||||
| 
 | ||||
| /// Called when a thread exits
 | ||||
|  | @ -1478,9 +1472,8 @@ static void ExitThread(Core::System& system) { | |||
|     LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | ||||
| 
 | ||||
|     auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | ||||
|     current_thread->Stop(); | ||||
|     system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); | ||||
|     system.PrepareReschedule(); | ||||
|     current_thread->Stop(); | ||||
| } | ||||
| 
 | ||||
| /// Sleep the current thread
 | ||||
|  | @ -1500,13 +1493,13 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
|     if (nanoseconds <= 0) { | ||||
|         switch (static_cast<SleepType>(nanoseconds)) { | ||||
|         case SleepType::YieldWithoutLoadBalancing: | ||||
|             is_redundant = current_thread->YieldSimple(); | ||||
|             current_thread->YieldSimple(); | ||||
|             break; | ||||
|         case SleepType::YieldWithLoadBalancing: | ||||
|             is_redundant = current_thread->YieldAndBalanceLoad(); | ||||
|             current_thread->YieldAndBalanceLoad(); | ||||
|             break; | ||||
|         case SleepType::YieldAndWaitForLoadBalancing: | ||||
|             is_redundant = current_thread->YieldAndWaitForLoadBalancing(); | ||||
|             current_thread->YieldAndWaitForLoadBalancing(); | ||||
|             break; | ||||
|         default: | ||||
|             UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); | ||||
|  | @ -1514,7 +1507,6 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
|     } else { | ||||
|         current_thread->Sleep(nanoseconds); | ||||
|     } | ||||
|     system.PrepareReschedule(current_thread->GetProcessorID()); | ||||
| } | ||||
| 
 | ||||
| /// Wait process wide key atomic
 | ||||
|  |  | |||
|  | @ -56,12 +56,6 @@ void Thread::Stop() { | |||
|     SetStatus(ThreadStatus::Dead); | ||||
|     Signal(); | ||||
| 
 | ||||
|     // Clean up any dangling references in objects that this thread was waiting for
 | ||||
|     for (auto& wait_object : wait_objects) { | ||||
|         wait_object->RemoveWaitingThread(SharedFrom(this)); | ||||
|     } | ||||
|     wait_objects.clear(); | ||||
| 
 | ||||
|     owner_process->UnregisterThread(this); | ||||
| 
 | ||||
|     // Mark the TLS slot in the thread's page as free.
 | ||||
|  | @ -138,6 +132,12 @@ void Thread::OnWakeUp() { | |||
|     SetStatus(ThreadStatus::Ready); | ||||
| } | ||||
| 
 | ||||
| ResultCode Thread::Start() { | ||||
|     SchedulerLock lock(kernel); | ||||
|     SetStatus(ThreadStatus::Ready); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| void Thread::CancelWait() { | ||||
|     if (GetSchedulingStatus() != ThreadSchedStatus::Paused) { | ||||
|         is_sync_cancelled = true; | ||||
|  | @ -188,7 +188,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy | |||
|                                                   void* thread_start_parameter) { | ||||
|     auto& kernel = system.Kernel(); | ||||
|     // Check if priority is in ranged. Lowest priority -> highest priority id.
 | ||||
|     if (priority > THREADPRIO_LOWEST && (type_flags & THREADTYPE_IDLE == 0)) { | ||||
|     if (priority > THREADPRIO_LOWEST && ((type_flags & THREADTYPE_IDLE) == 0)) { | ||||
|         LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); | ||||
|         return ERR_INVALID_THREAD_PRIORITY; | ||||
|     } | ||||
|  | @ -416,7 +416,7 @@ void Thread::SetActivity(ThreadActivity value) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void Thread::Sleep(s64 nanoseconds) { | ||||
| ResultCode Thread::Sleep(s64 nanoseconds) { | ||||
|     Handle event_handle{}; | ||||
|     { | ||||
|         SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); | ||||
|  | @ -427,33 +427,31 @@ void Thread::Sleep(s64 nanoseconds) { | |||
|         auto& time_manager = kernel.TimeManager(); | ||||
|         time_manager.UnscheduleTimeEvent(event_handle); | ||||
|     } | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| bool Thread::YieldSimple() { | ||||
|     bool result{}; | ||||
| ResultCode Thread::YieldSimple() { | ||||
|     { | ||||
|         SchedulerLock lock(kernel); | ||||
|         result = kernel.GlobalScheduler().YieldThread(this); | ||||
|         kernel.GlobalScheduler().YieldThread(this); | ||||
|     } | ||||
|     return result; | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| bool Thread::YieldAndBalanceLoad() { | ||||
|     bool result{}; | ||||
| ResultCode Thread::YieldAndBalanceLoad() { | ||||
|     { | ||||
|         SchedulerLock lock(kernel); | ||||
|         result = kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this); | ||||
|         kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this); | ||||
|     } | ||||
|     return result; | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| bool Thread::YieldAndWaitForLoadBalancing() { | ||||
|     bool result{}; | ||||
| ResultCode Thread::YieldAndWaitForLoadBalancing() { | ||||
|     { | ||||
|         SchedulerLock lock(kernel); | ||||
|         result = kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this); | ||||
|         kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this); | ||||
|     } | ||||
|     return result; | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { | ||||
|  |  | |||
|  | @ -236,6 +236,8 @@ public: | |||
| 
 | ||||
|     void OnWakeUp(); | ||||
| 
 | ||||
|     ResultCode Start(); | ||||
| 
 | ||||
|     /// Cancels a waiting operation that this thread may or may not be within.
 | ||||
|     ///
 | ||||
|     /// When the thread is within a waiting state, this will set the thread's
 | ||||
|  | @ -470,16 +472,16 @@ public: | |||
|     void SetActivity(ThreadActivity value); | ||||
| 
 | ||||
|     /// Sleeps this thread for the given amount of nanoseconds.
 | ||||
|     void Sleep(s64 nanoseconds); | ||||
|     ResultCode Sleep(s64 nanoseconds); | ||||
| 
 | ||||
|     /// Yields this thread without rebalancing loads.
 | ||||
|     bool YieldSimple(); | ||||
|     ResultCode YieldSimple(); | ||||
| 
 | ||||
|     /// Yields this thread and does a load rebalancing.
 | ||||
|     bool YieldAndBalanceLoad(); | ||||
|     ResultCode YieldAndBalanceLoad(); | ||||
| 
 | ||||
|     /// Yields this thread and if the core is left idle, loads are rebalanced
 | ||||
|     bool YieldAndWaitForLoadBalancing(); | ||||
|     ResultCode YieldAndWaitForLoadBalancing(); | ||||
| 
 | ||||
|     void IncrementYieldCount() { | ||||
|         yield_count++; | ||||
|  | @ -603,6 +605,8 @@ private: | |||
|     bool is_running = false; | ||||
|     bool is_sync_cancelled = false; | ||||
| 
 | ||||
|     bool will_be_terminated{}; | ||||
| 
 | ||||
|     std::string name; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fernando Sahmkow
						Fernando Sahmkow