mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Thread: Remove the idle thread
Instead just use nullptr to represent no thread is active.
This commit is contained in:
		
							parent
							
								
									10eb8b0c02
								
							
						
					
					
						commit
						4f7a055081
					
				@ -24,9 +24,9 @@ ARM_Interface*     g_sys_core = nullptr;  ///< ARM11 system (OS) core
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Run the core CPU loop
 | 
					/// Run the core CPU loop
 | 
				
			||||||
void RunLoop(int tight_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
 | 
					    // 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");
 | 
					        LOG_TRACE(Core_ARM11, "Idling");
 | 
				
			||||||
        CoreTiming::Idle();
 | 
					        CoreTiming::Idle();
 | 
				
			||||||
        CoreTiming::Advance();
 | 
					        CoreTiming::Advance();
 | 
				
			||||||
 | 
				
			|||||||
@ -157,7 +157,7 @@ static void PriorityBoostStarvedThreads() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        u64 delta = current_ticks - thread->last_running_ticks;
 | 
					        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);
 | 
					            const s32 priority = std::max(ready_queue.get_first()->current_priority - 1, 0);
 | 
				
			||||||
            thread->BoostPriority(priority);
 | 
					            thread->BoostPriority(priority);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -169,8 +169,6 @@ static void PriorityBoostStarvedThreads() {
 | 
				
			|||||||
 * @param new_thread The thread to switch to
 | 
					 * @param new_thread The thread to switch to
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void SwitchContext(Thread* new_thread) {
 | 
					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();
 | 
					    Thread* previous_thread = GetCurrentThread();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Save context for previous thread
 | 
					    // Save context for previous thread
 | 
				
			||||||
@ -188,6 +186,8 @@ static void SwitchContext(Thread* new_thread) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Load context of new thread
 | 
					    // Load context of new thread
 | 
				
			||||||
    if (new_thread) {
 | 
					    if (new_thread) {
 | 
				
			||||||
 | 
					        DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        current_thread = new_thread;
 | 
					        current_thread = new_thread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ready_queue.remove(new_thread->current_priority, new_thread);
 | 
					        ready_queue.remove(new_thread->current_priority, new_thread);
 | 
				
			||||||
@ -215,6 +215,10 @@ static Thread* PopNextReadyThread() {
 | 
				
			|||||||
        // We have to do better than the current thread.
 | 
					        // We have to do better than the current thread.
 | 
				
			||||||
        // This call returns null when that's not possible.
 | 
					        // This call returns null when that's not possible.
 | 
				
			||||||
        next = ready_queue.pop_first_better(thread->current_priority);
 | 
					        next = ready_queue.pop_first_better(thread->current_priority);
 | 
				
			||||||
 | 
					        if (!next) {
 | 
				
			||||||
 | 
					            // Otherwise just keep going with the current thread
 | 
				
			||||||
 | 
					            next = thread;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    } else  {
 | 
					    } else  {
 | 
				
			||||||
        next = ready_queue.pop_first();
 | 
					        next = ready_queue.pop_first();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -448,16 +452,6 @@ void Thread::BoostPriority(s32 priority) {
 | 
				
			|||||||
    current_priority = 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) {
 | 
					SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) {
 | 
				
			||||||
    DEBUG_ASSERT(!GetCurrentThread());
 | 
					    DEBUG_ASSERT(!GetCurrentThread());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -474,24 +468,25 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reschedule() {
 | 
					void Reschedule() {
 | 
				
			||||||
    Thread* prev = GetCurrentThread();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    PriorityBoostStarvedThreads();
 | 
					    PriorityBoostStarvedThreads();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Thread* cur = GetCurrentThread();
 | 
				
			||||||
    Thread* next = PopNextReadyThread();
 | 
					    Thread* next = PopNextReadyThread();
 | 
				
			||||||
    HLE::g_reschedule = false;
 | 
					    HLE::g_reschedule = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (next != nullptr) {
 | 
					    // Don't bother switching to the same thread
 | 
				
			||||||
        LOG_TRACE(Kernel, "context switch %u -> %u", prev->GetObjectId(), next->GetObjectId());
 | 
					    if (next == cur)
 | 
				
			||||||
        SwitchContext(next);
 | 
					        return;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        LOG_TRACE(Kernel, "cannot context switch from %u, no higher priority thread!", prev->GetObjectId());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (auto& thread : thread_list) {
 | 
					    if (cur && next) {
 | 
				
			||||||
            LOG_TRACE(Kernel, "\tid=%u prio=0x%02X, status=0x%08X", thread->GetObjectId(), 
 | 
					        LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId());
 | 
				
			||||||
                      thread->current_priority, thread->status);
 | 
					    } 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) {
 | 
					void Thread::SetWaitSynchronizationResult(ResultCode result) {
 | 
				
			||||||
@ -516,9 +511,6 @@ void ThreadingInit() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    thread_list.clear();
 | 
					    thread_list.clear();
 | 
				
			||||||
    ready_queue.clear();
 | 
					    ready_queue.clear();
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Setup the idle thread
 | 
					 | 
				
			||||||
    SetupIdleThread();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ThreadingShutdown() {
 | 
					void ThreadingShutdown() {
 | 
				
			||||||
 | 
				
			|||||||
@ -71,12 +71,6 @@ public:
 | 
				
			|||||||
    bool ShouldWait() override;
 | 
					    bool ShouldWait() override;
 | 
				
			||||||
    void Acquire() 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
 | 
					     * Gets the thread's current priority
 | 
				
			||||||
     * @return The current thread's priority
 | 
					     * @return The current thread's priority
 | 
				
			||||||
@ -168,9 +162,6 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::string name;
 | 
					    std::string name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Whether this thread is intended to never actually be executed, i.e. always idle
 | 
					 | 
				
			||||||
    bool idle = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    Thread();
 | 
					    Thread();
 | 
				
			||||||
    ~Thread() override;
 | 
					    ~Thread() override;
 | 
				
			||||||
@ -228,14 +219,6 @@ void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wa
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void WaitCurrentThread_ArbitrateAddress(VAddr wait_address);
 | 
					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
 | 
					 * Initialize threading
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user