mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Kernel: Correct Signal on Thread Death and Setup Sync Objects on Thread for Debugging
This commit is contained in:
		
							parent
							
								
									75e10578f1
								
							
						
					
					
						commit
						b4dc01f16a
					
				@ -70,6 +70,8 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
 | 
				
			|||||||
        for (auto& object : sync_objects) {
 | 
					        for (auto& object : sync_objects) {
 | 
				
			||||||
            object->AddWaitingThread(SharedFrom(thread));
 | 
					            object->AddWaitingThread(SharedFrom(thread));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        thread->SetSynchronizationObjects(&sync_objects);
 | 
				
			||||||
        thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
 | 
					        thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
 | 
				
			||||||
        thread->SetStatus(ThreadStatus::WaitSynch);
 | 
					        thread->SetStatus(ThreadStatus::WaitSynch);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -83,6 +85,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
 | 
				
			|||||||
        SchedulerLock lock(kernel);
 | 
					        SchedulerLock lock(kernel);
 | 
				
			||||||
        ResultCode signaling_result = thread->GetSignalingResult();
 | 
					        ResultCode signaling_result = thread->GetSignalingResult();
 | 
				
			||||||
        SynchronizationObject* signaling_object = thread->GetSignalingObject();
 | 
					        SynchronizationObject* signaling_object = thread->GetSignalingObject();
 | 
				
			||||||
 | 
					        thread->SetSynchronizationObjects(nullptr);
 | 
				
			||||||
        for (auto& obj : sync_objects) {
 | 
					        for (auto& obj : sync_objects) {
 | 
				
			||||||
            obj->RemoveWaitingThread(SharedFrom(thread));
 | 
					            obj->RemoveWaitingThread(SharedFrom(thread));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -50,11 +50,11 @@ void Thread::Stop() {
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        SchedulerLock lock(kernel);
 | 
					        SchedulerLock lock(kernel);
 | 
				
			||||||
        // Cancel any outstanding wakeup events for this thread
 | 
					        // Cancel any outstanding wakeup events for this thread
 | 
				
			||||||
        Signal();
 | 
					 | 
				
			||||||
        Core::System::GetInstance().CoreTiming().UnscheduleEvent(
 | 
					        Core::System::GetInstance().CoreTiming().UnscheduleEvent(
 | 
				
			||||||
            kernel.ThreadWakeupCallbackEventType(), global_handle);
 | 
					            kernel.ThreadWakeupCallbackEventType(), global_handle);
 | 
				
			||||||
        kernel.GlobalHandleTable().Close(global_handle);
 | 
					 | 
				
			||||||
        SetStatus(ThreadStatus::Dead);
 | 
					        SetStatus(ThreadStatus::Dead);
 | 
				
			||||||
 | 
					        Signal();
 | 
				
			||||||
 | 
					        kernel.GlobalHandleTable().Close(global_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        owner_process->UnregisterThread(this);
 | 
					        owner_process->UnregisterThread(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -81,7 +81,6 @@ void Thread::CancelWakeupTimer() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Thread::ResumeFromWait() {
 | 
					void Thread::ResumeFromWait() {
 | 
				
			||||||
    ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
 | 
					 | 
				
			||||||
    SchedulerLock lock(kernel);
 | 
					    SchedulerLock lock(kernel);
 | 
				
			||||||
    switch (status) {
 | 
					    switch (status) {
 | 
				
			||||||
    case ThreadStatus::Paused:
 | 
					    case ThreadStatus::Paused:
 | 
				
			||||||
@ -219,7 +218,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
 | 
				
			|||||||
    thread->processor_id = processor_id;
 | 
					    thread->processor_id = processor_id;
 | 
				
			||||||
    thread->ideal_core = processor_id;
 | 
					    thread->ideal_core = processor_id;
 | 
				
			||||||
    thread->affinity_mask = 1ULL << processor_id;
 | 
					    thread->affinity_mask = 1ULL << processor_id;
 | 
				
			||||||
    thread->wait_objects.clear();
 | 
					    thread->wait_objects = nullptr;
 | 
				
			||||||
    thread->mutex_wait_address = 0;
 | 
					    thread->mutex_wait_address = 0;
 | 
				
			||||||
    thread->condvar_wait_address = 0;
 | 
					    thread->condvar_wait_address = 0;
 | 
				
			||||||
    thread->wait_handle = 0;
 | 
					    thread->wait_handle = 0;
 | 
				
			||||||
@ -272,9 +271,9 @@ void Thread::SetSynchronizationResults(SynchronizationObject* object, ResultCode
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {
 | 
					s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {
 | 
				
			||||||
    ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
 | 
					    ASSERT_MSG(!wait_objects->empty(), "Thread is not waiting for anything");
 | 
				
			||||||
    const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
 | 
					    const auto match = std::find(wait_objects->rbegin(), wait_objects->rend(), object);
 | 
				
			||||||
    return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
 | 
					    return static_cast<s32>(std::distance(match, wait_objects->rend()) - 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VAddr Thread::GetCommandBufferAddress() const {
 | 
					VAddr Thread::GetCommandBufferAddress() const {
 | 
				
			||||||
@ -389,7 +388,7 @@ void Thread::UpdatePriority() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Thread::AllSynchronizationObjectsReady() const {
 | 
					bool Thread::AllSynchronizationObjectsReady() const {
 | 
				
			||||||
    return std::none_of(wait_objects.begin(), wait_objects.end(),
 | 
					    return std::none_of(wait_objects->begin(), wait_objects->end(),
 | 
				
			||||||
                        [this](const std::shared_ptr<SynchronizationObject>& object) {
 | 
					                        [this](const std::shared_ptr<SynchronizationObject>& object) {
 | 
				
			||||||
                            return object->ShouldWait(this);
 | 
					                            return object->ShouldWait(this);
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ class Fiber;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Core {
 | 
					namespace Core {
 | 
				
			||||||
class System;
 | 
					class System;
 | 
				
			||||||
}
 | 
					} // namespace Core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -386,18 +386,18 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
 | 
					    const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
 | 
				
			||||||
        return wait_objects;
 | 
					        return *wait_objects;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void SetSynchronizationObjects(ThreadSynchronizationObjects objects) {
 | 
					    void SetSynchronizationObjects(ThreadSynchronizationObjects* objects) {
 | 
				
			||||||
        wait_objects = std::move(objects);
 | 
					        wait_objects = objects;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ClearSynchronizationObjects() {
 | 
					    void ClearSynchronizationObjects() {
 | 
				
			||||||
        for (const auto& waiting_object : wait_objects) {
 | 
					        for (const auto& waiting_object : *wait_objects) {
 | 
				
			||||||
            waiting_object->RemoveWaitingThread(SharedFrom(this));
 | 
					            waiting_object->RemoveWaitingThread(SharedFrom(this));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        wait_objects.clear();
 | 
					        wait_objects->clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Determines whether all the objects this thread is waiting on are ready.
 | 
					    /// Determines whether all the objects this thread is waiting on are ready.
 | 
				
			||||||
@ -595,7 +595,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Objects that the thread is waiting on, in the same order as they were
 | 
					    /// Objects that the thread is waiting on, in the same order as they were
 | 
				
			||||||
    /// passed to WaitSynchronization.
 | 
					    /// passed to WaitSynchronization.
 | 
				
			||||||
    ThreadSynchronizationObjects wait_objects;
 | 
					    ThreadSynchronizationObjects* wait_objects;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SynchronizationObject* signaling_object;
 | 
					    SynchronizationObject* signaling_object;
 | 
				
			||||||
    ResultCode signaling_result{RESULT_SUCCESS};
 | 
					    ResultCode signaling_result{RESULT_SUCCESS};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user