mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #751 from yuriks/idle-thread
Thread: Remove the idle thread
This commit is contained in:
		
						commit
						ee8da4c356
					
				
					 3 changed files with 21 additions and 46 deletions
				
			
		|  | @ -24,9 +24,9 @@ ARM_Interface*     g_sys_core = nullptr;  ///< ARM11 system (OS) core | |||
| 
 | ||||
| /// Run the core CPU loop
 | ||||
| void RunLoop(int tight_loop) { | ||||
|     // If the current thread is an idle thread, then don't execute instructions,
 | ||||
|     // If we don't have a currently active thread then don't execute instructions,
 | ||||
|     // instead advance to the next event and try to yield to the next thread
 | ||||
|     if (Kernel::GetCurrentThread()->IsIdle()) { | ||||
|     if (Kernel::GetCurrentThread() == nullptr) { | ||||
|         LOG_TRACE(Core_ARM11, "Idling"); | ||||
|         CoreTiming::Idle(); | ||||
|         CoreTiming::Advance(); | ||||
|  |  | |||
|  | @ -158,7 +158,7 @@ static void PriorityBoostStarvedThreads() { | |||
| 
 | ||||
|         u64 delta = current_ticks - thread->last_running_ticks; | ||||
| 
 | ||||
|         if (thread->status == THREADSTATUS_READY && delta > boost_timeout && !thread->idle) { | ||||
|         if (thread->status == THREADSTATUS_READY && delta > boost_timeout) { | ||||
|             const s32 priority = std::max(ready_queue.get_first()->current_priority - 1, 0); | ||||
|             thread->BoostPriority(priority); | ||||
|         } | ||||
|  | @ -170,8 +170,6 @@ static void PriorityBoostStarvedThreads() { | |||
|  * @param new_thread The thread to switch to | ||||
|  */ | ||||
| static void SwitchContext(Thread* new_thread) { | ||||
|     DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); | ||||
| 
 | ||||
|     Thread* previous_thread = GetCurrentThread(); | ||||
| 
 | ||||
|     // Save context for previous thread
 | ||||
|  | @ -189,6 +187,8 @@ static void SwitchContext(Thread* new_thread) { | |||
| 
 | ||||
|     // Load context of new thread
 | ||||
|     if (new_thread) { | ||||
|         DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); | ||||
| 
 | ||||
|         current_thread = new_thread; | ||||
| 
 | ||||
|         ready_queue.remove(new_thread->current_priority, new_thread); | ||||
|  | @ -216,6 +216,10 @@ static Thread* PopNextReadyThread() { | |||
|         // We have to do better than the current thread.
 | ||||
|         // This call returns null when that's not possible.
 | ||||
|         next = ready_queue.pop_first_better(thread->current_priority); | ||||
|         if (!next) { | ||||
|             // Otherwise just keep going with the current thread
 | ||||
|             next = thread; | ||||
|         } | ||||
|     } else  { | ||||
|         next = ready_queue.pop_first(); | ||||
|     } | ||||
|  | @ -452,16 +456,6 @@ void Thread::BoostPriority(s32 priority) { | |||
|     current_priority = priority; | ||||
| } | ||||
| 
 | ||||
| SharedPtr<Thread> SetupIdleThread() { | ||||
|     // We need to pass a few valid values to get around parameter checking in Thread::Create.
 | ||||
|     // TODO(yuriks): Figure out a way to avoid passing the bogus VAddr parameter
 | ||||
|     auto thread = Thread::Create("idle", Memory::TLS_AREA_VADDR, THREADPRIO_LOWEST, 0, | ||||
|             THREADPROCESSORID_0, 0).MoveFrom(); | ||||
| 
 | ||||
|     thread->idle = true; | ||||
|     return thread; | ||||
| } | ||||
| 
 | ||||
| SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) { | ||||
|     DEBUG_ASSERT(!GetCurrentThread()); | ||||
| 
 | ||||
|  | @ -478,24 +472,25 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) { | |||
| } | ||||
| 
 | ||||
| void Reschedule() { | ||||
|     Thread* prev = GetCurrentThread(); | ||||
| 
 | ||||
|     PriorityBoostStarvedThreads(); | ||||
| 
 | ||||
|     Thread* cur = GetCurrentThread(); | ||||
|     Thread* next = PopNextReadyThread(); | ||||
|     HLE::g_reschedule = false; | ||||
| 
 | ||||
|     if (next != nullptr) { | ||||
|         LOG_TRACE(Kernel, "context switch %u -> %u", prev->GetObjectId(), next->GetObjectId()); | ||||
|         SwitchContext(next); | ||||
|     } else { | ||||
|         LOG_TRACE(Kernel, "cannot context switch from %u, no higher priority thread!", prev->GetObjectId()); | ||||
|     // Don't bother switching to the same thread
 | ||||
|     if (next == cur) | ||||
|         return; | ||||
| 
 | ||||
|         for (auto& thread : thread_list) { | ||||
|             LOG_TRACE(Kernel, "\tid=%u prio=0x%02X, status=0x%08X", thread->GetObjectId(),  | ||||
|                       thread->current_priority, thread->status); | ||||
|         } | ||||
|     if (cur && next) { | ||||
|         LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId()); | ||||
|     } else if (cur) { | ||||
|         LOG_TRACE(Kernel, "context switch %u -> idle", cur->GetObjectId()); | ||||
|     } else { | ||||
|         LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId()); | ||||
|     } | ||||
|      | ||||
|     SwitchContext(next); | ||||
| } | ||||
| 
 | ||||
| void Thread::SetWaitSynchronizationResult(ResultCode result) { | ||||
|  | @ -520,9 +515,6 @@ void ThreadingInit() { | |||
| 
 | ||||
|     thread_list.clear(); | ||||
|     ready_queue.clear(); | ||||
| 
 | ||||
|     // Setup the idle thread
 | ||||
|     SetupIdleThread(); | ||||
| } | ||||
| 
 | ||||
| void ThreadingShutdown() { | ||||
|  |  | |||
|  | @ -72,12 +72,6 @@ public: | |||
|     bool ShouldWait() override; | ||||
|     void Acquire() override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Checks if the thread is an idle (stub) thread | ||||
|      * @return True if the thread is an idle (stub) thread, false otherwise | ||||
|      */ | ||||
|     inline bool IsIdle() const { return idle; } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Gets the thread's current priority | ||||
|      * @return The current thread's priority | ||||
|  | @ -170,9 +164,6 @@ public: | |||
| 
 | ||||
|     std::string name; | ||||
| 
 | ||||
|     /// Whether this thread is intended to never actually be executed, i.e. always idle
 | ||||
|     bool idle = false; | ||||
| 
 | ||||
| private: | ||||
|     Thread(); | ||||
|     ~Thread() override; | ||||
|  | @ -230,14 +221,6 @@ void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wa | |||
|  */ | ||||
| void WaitCurrentThread_ArbitrateAddress(VAddr wait_address); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets up the idle thread, this is a thread that is intended to never execute instructions, | ||||
|  * only to advance the timing. It is scheduled when there are no other ready threads in the thread queue | ||||
|  * and will try to yield on every call. | ||||
|  * @return The handle of the idle thread | ||||
|  */ | ||||
| SharedPtr<Thread> SetupIdleThread(); | ||||
| 
 | ||||
| /**
 | ||||
|  * Initialize threading | ||||
|  */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue