Przeglądaj źródła

Kernel: Correct Signal on Thread Death and Setup Sync Objects on Thread for Debugging

Fernando Sahmkow 6 lat temu
rodzic
commit
b4dc01f16a

+ 3 - 0
src/core/hle/kernel/synchronization.cpp

@@ -70,6 +70,8 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
         for (auto& object : sync_objects) {
             object->AddWaitingThread(SharedFrom(thread));
         }
+
+        thread->SetSynchronizationObjects(&sync_objects);
         thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
         thread->SetStatus(ThreadStatus::WaitSynch);
     }
@@ -83,6 +85,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
         SchedulerLock lock(kernel);
         ResultCode signaling_result = thread->GetSignalingResult();
         SynchronizationObject* signaling_object = thread->GetSignalingObject();
+        thread->SetSynchronizationObjects(nullptr);
         for (auto& obj : sync_objects) {
             obj->RemoveWaitingThread(SharedFrom(thread));
         }

+ 7 - 8
src/core/hle/kernel/thread.cpp

@@ -50,11 +50,11 @@ void Thread::Stop() {
     {
         SchedulerLock lock(kernel);
         // Cancel any outstanding wakeup events for this thread
-        Signal();
         Core::System::GetInstance().CoreTiming().UnscheduleEvent(
             kernel.ThreadWakeupCallbackEventType(), global_handle);
-        kernel.GlobalHandleTable().Close(global_handle);
         SetStatus(ThreadStatus::Dead);
+        Signal();
+        kernel.GlobalHandleTable().Close(global_handle);
 
         owner_process->UnregisterThread(this);
 
@@ -81,7 +81,6 @@ void Thread::CancelWakeupTimer() {
 }
 
 void Thread::ResumeFromWait() {
-    ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
     SchedulerLock lock(kernel);
     switch (status) {
     case ThreadStatus::Paused:
@@ -219,7 +218,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
     thread->processor_id = processor_id;
     thread->ideal_core = processor_id;
     thread->affinity_mask = 1ULL << processor_id;
-    thread->wait_objects.clear();
+    thread->wait_objects = nullptr;
     thread->mutex_wait_address = 0;
     thread->condvar_wait_address = 0;
     thread->wait_handle = 0;
@@ -272,9 +271,9 @@ void Thread::SetSynchronizationResults(SynchronizationObject* object, ResultCode
 }
 
 s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {
-    ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
-    const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
-    return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
+    ASSERT_MSG(!wait_objects->empty(), "Thread is not waiting for anything");
+    const auto match = std::find(wait_objects->rbegin(), wait_objects->rend(), object);
+    return static_cast<s32>(std::distance(match, wait_objects->rend()) - 1);
 }
 
 VAddr Thread::GetCommandBufferAddress() const {
@@ -389,7 +388,7 @@ void Thread::UpdatePriority() {
 }
 
 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) {
                             return object->ShouldWait(this);
                         });

+ 7 - 7
src/core/hle/kernel/thread.h

@@ -21,7 +21,7 @@ class Fiber;
 
 namespace Core {
 class System;
-}
+} // namespace Core
 
 namespace Kernel {
 
@@ -386,18 +386,18 @@ public:
     }
 
     const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
-        return wait_objects;
+        return *wait_objects;
     }
 
-    void SetSynchronizationObjects(ThreadSynchronizationObjects objects) {
-        wait_objects = std::move(objects);
+    void SetSynchronizationObjects(ThreadSynchronizationObjects* objects) {
+        wait_objects = objects;
     }
 
     void ClearSynchronizationObjects() {
-        for (const auto& waiting_object : wait_objects) {
+        for (const auto& waiting_object : *wait_objects) {
             waiting_object->RemoveWaitingThread(SharedFrom(this));
         }
-        wait_objects.clear();
+        wait_objects->clear();
     }
 
     /// 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
     /// passed to WaitSynchronization.
-    ThreadSynchronizationObjects wait_objects;
+    ThreadSynchronizationObjects* wait_objects;
 
     SynchronizationObject* signaling_object;
     ResultCode signaling_result{RESULT_SUCCESS};