summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2017-01-04 11:37:19 -0500
committerGravatar Subv2017-01-05 09:40:15 -0500
commit7f1dca8cd26fe9be0080efee4e456630960af459 (patch)
tree5eae30d01e21d54e529a1074bbc5cbf3cde8ff6a /src
parentKernel: Remove Thread::wait_objects_index and use wait_objects to hold all th... (diff)
downloadyuzu-7f1dca8cd26fe9be0080efee4e456630960af459.tar.gz
yuzu-7f1dca8cd26fe9be0080efee4e456630960af459.tar.xz
yuzu-7f1dca8cd26fe9be0080efee4e456630960af459.zip
Kernel: Remove a thread from all of its waiting objects' waiting_threads list when it is awoken.
This fixes a potential bug where threads would not get removed from said list if they awoke after waiting with WaitSynchronizationN with wait_all = false
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/kernel.cpp22
1 files changed, 4 insertions, 18 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 955f50a9b..47d4df69c 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -32,19 +32,6 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
32} 32}
33 33
34SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { 34SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
35 // Remove the threads that are ready or already running from our waitlist
36 auto to_remove = waiting_threads.end();
37 do {
38 to_remove = std::find_if(waiting_threads.begin(), waiting_threads.end(),
39 [](const SharedPtr<Thread>& thread) {
40 return thread->status == THREADSTATUS_RUNNING ||
41 thread->status == THREADSTATUS_READY ||
42 thread->status == THREADSTATUS_DEAD;
43 });
44 // Call RemoveWaitingThread so that child classes can override the behavior.
45 RemoveWaitingThread(to_remove->get());
46 } while (to_remove != waiting_threads.end());
47
48 Thread* candidate = nullptr; 35 Thread* candidate = nullptr;
49 s32 candidate_priority = THREADPRIO_LOWEST + 1; 36 s32 candidate_priority = THREADPRIO_LOWEST + 1;
50 37
@@ -86,17 +73,16 @@ void WaitObject::WakeupAllWaitingThreads() {
86 } else { 73 } else {
87 for (auto& object : thread->wait_objects) { 74 for (auto& object : thread->wait_objects) {
88 object->Acquire(thread.get()); 75 object->Acquire(thread.get());
89 object->RemoveWaitingThread(thread.get());
90 } 76 }
91 // Note: This case doesn't update the output index of WaitSynchronizationN. 77 // Note: This case doesn't update the output index of WaitSynchronizationN.
92 // Clear the thread's waitlist
93 thread->wait_objects.clear();
94 } 78 }
95 79
80 for (auto& object : thread->wait_objects)
81 object->RemoveWaitingThread(thread.get());
82 thread->wait_objects.clear();
83
96 thread->SetWaitSynchronizationResult(RESULT_SUCCESS); 84 thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
97 thread->ResumeFromWait(); 85 thread->ResumeFromWait();
98 // Note: Removing the thread from the object's waitlist will be
99 // done by GetHighestPriorityReadyThread.
100 } 86 }
101} 87}
102 88