summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/kernel.cpp3
-rw-r--r--src/core/hle/kernel/process.cpp3
-rw-r--r--src/core/hle/kernel/svc.cpp4
-rw-r--r--src/core/hle/kernel/thread.cpp5
-rw-r--r--src/core/hle/kernel/thread.h28
-rw-r--r--src/core/hle/kernel/wait_object.cpp29
-rw-r--r--src/yuzu/debugger/wait_tree.cpp11
7 files changed, 38 insertions, 45 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 4d58e7c69..a38ee117b 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -46,8 +46,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
46 46
47 bool resume = true; 47 bool resume = true;
48 48
49 if (thread->GetStatus() == ThreadStatus::WaitSynchAny || 49 if (thread->GetStatus() == ThreadStatus::WaitSynch ||
50 thread->GetStatus() == ThreadStatus::WaitSynchAll ||
51 thread->GetStatus() == ThreadStatus::WaitHLEEvent) { 50 thread->GetStatus() == ThreadStatus::WaitHLEEvent) {
52 // Remove the thread from each of its waiting objects' waitlists 51 // Remove the thread from each of its waiting objects' waitlists
53 for (const auto& object : thread->GetWaitObjects()) { 52 for (const auto& object : thread->GetWaitObjects()) {
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 4e94048da..0ace3d21c 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -150,8 +150,7 @@ void Process::PrepareForTermination() {
150 continue; 150 continue;
151 151
152 // TODO(Subv): When are the other running/ready threads terminated? 152 // TODO(Subv): When are the other running/ready threads terminated?
153 ASSERT_MSG(thread->GetStatus() == ThreadStatus::WaitSynchAny || 153 ASSERT_MSG(thread->GetStatus() == ThreadStatus::WaitSynch,
154 thread->GetStatus() == ThreadStatus::WaitSynchAll,
155 "Exiting processes with non-waiting threads is currently unimplemented"); 154 "Exiting processes with non-waiting threads is currently unimplemented");
156 155
157 thread->Stop(); 156 thread->Stop();
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index b25190882..ea3fdc315 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -424,7 +424,7 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han
424/// Default thread wakeup callback for WaitSynchronization 424/// Default thread wakeup callback for WaitSynchronization
425static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, 425static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
426 SharedPtr<WaitObject> object, std::size_t index) { 426 SharedPtr<WaitObject> object, std::size_t index) {
427 ASSERT(thread->GetStatus() == ThreadStatus::WaitSynchAny); 427 ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
428 428
429 if (reason == ThreadWakeupReason::Timeout) { 429 if (reason == ThreadWakeupReason::Timeout) {
430 thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); 430 thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
@@ -502,7 +502,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
502 } 502 }
503 503
504 thread->SetWaitObjects(std::move(objects)); 504 thread->SetWaitObjects(std::move(objects));
505 thread->SetStatus(ThreadStatus::WaitSynchAny); 505 thread->SetStatus(ThreadStatus::WaitSynch);
506 506
507 // Create an event to wake the thread up after the specified nanosecond delay has passed 507 // Create an event to wake the thread up after the specified nanosecond delay has passed
508 thread->WakeAfterDelay(nano_seconds); 508 thread->WakeAfterDelay(nano_seconds);
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 7d4fe9608..2abf9efca 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -101,8 +101,7 @@ void Thread::ResumeFromWait() {
101 ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); 101 ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
102 102
103 switch (status) { 103 switch (status) {
104 case ThreadStatus::WaitSynchAll: 104 case ThreadStatus::WaitSynch:
105 case ThreadStatus::WaitSynchAny:
106 case ThreadStatus::WaitHLEEvent: 105 case ThreadStatus::WaitHLEEvent:
107 case ThreadStatus::WaitSleep: 106 case ThreadStatus::WaitSleep:
108 case ThreadStatus::WaitIPC: 107 case ThreadStatus::WaitIPC:
@@ -143,7 +142,7 @@ void Thread::ResumeFromWait() {
143} 142}
144 143
145void Thread::CancelWait() { 144void Thread::CancelWait() {
146 ASSERT(GetStatus() == ThreadStatus::WaitSynchAny); 145 ASSERT(GetStatus() == ThreadStatus::WaitSynch);
147 SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED); 146 SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED);
148 ResumeFromWait(); 147 ResumeFromWait();
149} 148}
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index e3c457408..62ce7bfda 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -49,8 +49,7 @@ enum class ThreadStatus {
49 WaitHLEEvent, ///< Waiting for hle event to finish 49 WaitHLEEvent, ///< Waiting for hle event to finish
50 WaitSleep, ///< Waiting due to a SleepThread SVC 50 WaitSleep, ///< Waiting due to a SleepThread SVC
51 WaitIPC, ///< Waiting for the reply from an IPC request 51 WaitIPC, ///< Waiting for the reply from an IPC request
52 WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false 52 WaitSynch, ///< Waiting due to WaitSynchronization
53 WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true
54 WaitMutex, ///< Waiting due to an ArbitrateLock svc 53 WaitMutex, ///< Waiting due to an ArbitrateLock svc
55 WaitCondVar, ///< Waiting due to an WaitProcessWideKey svc 54 WaitCondVar, ///< Waiting due to an WaitProcessWideKey svc
56 WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc 55 WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc
@@ -185,24 +184,27 @@ public:
185 void CancelWakeupTimer(); 184 void CancelWakeupTimer();
186 185
187 /** 186 /**
188 * Sets the result after the thread awakens (from either WaitSynchronization SVC) 187 * Sets the result after the thread awakens (from svcWaitSynchronization)
189 * @param result Value to set to the returned result 188 * @param result Value to set to the returned result
190 */ 189 */
191 void SetWaitSynchronizationResult(ResultCode result); 190 void SetWaitSynchronizationResult(ResultCode result);
192 191
193 /** 192 /**
194 * Sets the output parameter value after the thread awakens (from WaitSynchronizationN SVC only) 193 * Sets the output parameter value after the thread awakens (from svcWaitSynchronization)
195 * @param output Value to set to the output parameter 194 * @param output Value to set to the output parameter
196 */ 195 */
197 void SetWaitSynchronizationOutput(s32 output); 196 void SetWaitSynchronizationOutput(s32 output);
198 197
199 /** 198 /**
200 * Retrieves the index that this particular object occupies in the list of objects 199 * Retrieves the index that this particular object occupies in the list of objects
201 * that the thread passed to WaitSynchronizationN, starting the search from the last element. 200 * that the thread passed to WaitSynchronization, starting the search from the last element.
202 * It is used to set the output value of WaitSynchronizationN when the thread is awakened. 201 *
202 * It is used to set the output index of WaitSynchronization when the thread is awakened.
203 *
203 * When a thread wakes up due to an object signal, the kernel will use the index of the last 204 * When a thread wakes up due to an object signal, the kernel will use the index of the last
204 * matching object in the wait objects list in case of having multiple instances of the same 205 * matching object in the wait objects list in case of having multiple instances of the same
205 * object in the list. 206 * object in the list.
207 *
206 * @param object Object to query the index of. 208 * @param object Object to query the index of.
207 */ 209 */
208 s32 GetWaitObjectIndex(const WaitObject* object) const; 210 s32 GetWaitObjectIndex(const WaitObject* object) const;
@@ -239,13 +241,9 @@ public:
239 */ 241 */
240 VAddr GetCommandBufferAddress() const; 242 VAddr GetCommandBufferAddress() const;
241 243
242 /** 244 /// Returns whether this thread is waiting on objects from a WaitSynchronization call.
243 * Returns whether this thread is waiting for all the objects in 245 bool IsSleepingOnWait() const {
244 * its wait list to become ready, as a result of a WaitSynchronizationN call 246 return status == ThreadStatus::WaitSynch;
245 * with wait_all = true.
246 */
247 bool IsSleepingOnWaitAll() const {
248 return status == ThreadStatus::WaitSynchAll;
249 } 247 }
250 248
251 ThreadContext& GetContext() { 249 ThreadContext& GetContext() {
@@ -423,7 +421,7 @@ private:
423 Process* owner_process; 421 Process* owner_process;
424 422
425 /// Objects that the thread is waiting on, in the same order as they were 423 /// Objects that the thread is waiting on, in the same order as they were
426 /// passed to WaitSynchronization1/N. 424 /// passed to WaitSynchronization.
427 ThreadWaitObjects wait_objects; 425 ThreadWaitObjects wait_objects;
428 426
429 /// List of threads that are waiting for a mutex that is held by this thread. 427 /// List of threads that are waiting for a mutex that is held by this thread.
@@ -449,7 +447,7 @@ private:
449 Handle callback_handle = 0; 447 Handle callback_handle = 0;
450 448
451 /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread 449 /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
452 /// was waiting via WaitSynchronizationN then the object will be the last object that became 450 /// was waiting via WaitSynchronization then the object will be the last object that became
453 /// available. In case of a timeout, the object will be nullptr. 451 /// available. In case of a timeout, the object will be nullptr.
454 WakeupCallback wakeup_callback; 452 WakeupCallback wakeup_callback;
455 453
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index 90580ed93..38d8a6e0c 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -38,8 +38,7 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
38 const ThreadStatus thread_status = thread->GetStatus(); 38 const ThreadStatus thread_status = thread->GetStatus();
39 39
40 // The list of waiting threads must not contain threads that are not waiting to be awakened. 40 // The list of waiting threads must not contain threads that are not waiting to be awakened.
41 ASSERT_MSG(thread_status == ThreadStatus::WaitSynchAny || 41 ASSERT_MSG(thread_status == ThreadStatus::WaitSynch ||
42 thread_status == ThreadStatus::WaitSynchAll ||
43 thread_status == ThreadStatus::WaitHLEEvent, 42 thread_status == ThreadStatus::WaitHLEEvent,
44 "Inconsistent thread statuses in waiting_threads"); 43 "Inconsistent thread statuses in waiting_threads");
45 44
@@ -49,10 +48,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
49 if (ShouldWait(thread.get())) 48 if (ShouldWait(thread.get()))
50 continue; 49 continue;
51 50
52 // A thread is ready to run if it's either in ThreadStatus::WaitSynchAny or 51 // A thread is ready to run if it's either in ThreadStatus::WaitSynch
53 // in ThreadStatus::WaitSynchAll and the rest of the objects it is waiting on are ready. 52 // and the rest of the objects it is waiting on are ready.
54 bool ready_to_run = true; 53 bool ready_to_run = true;
55 if (thread_status == ThreadStatus::WaitSynchAll) { 54 if (thread_status == ThreadStatus::WaitSynch) {
56 ready_to_run = thread->AllWaitObjectsReady(); 55 ready_to_run = thread->AllWaitObjectsReady();
57 } 56 }
58 57
@@ -68,33 +67,35 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
68void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { 67void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
69 ASSERT(!ShouldWait(thread.get())); 68 ASSERT(!ShouldWait(thread.get()));
70 69
71 if (!thread) 70 if (!thread) {
72 return; 71 return;
72 }
73 73
74 if (!thread->IsSleepingOnWaitAll()) { 74 if (thread->IsSleepingOnWait()) {
75 Acquire(thread.get());
76 } else {
77 for (const auto& object : thread->GetWaitObjects()) { 75 for (const auto& object : thread->GetWaitObjects()) {
78 ASSERT(!object->ShouldWait(thread.get())); 76 ASSERT(!object->ShouldWait(thread.get()));
79 object->Acquire(thread.get()); 77 object->Acquire(thread.get());
80 } 78 }
79 } else {
80 Acquire(thread.get());
81 } 81 }
82 82
83 const std::size_t index = thread->GetWaitObjectIndex(this); 83 const std::size_t index = thread->GetWaitObjectIndex(this);
84 84
85 for (const auto& object : thread->GetWaitObjects()) 85 for (const auto& object : thread->GetWaitObjects()) {
86 object->RemoveWaitingThread(thread.get()); 86 object->RemoveWaitingThread(thread.get());
87 }
87 thread->ClearWaitObjects(); 88 thread->ClearWaitObjects();
88 89
89 thread->CancelWakeupTimer(); 90 thread->CancelWakeupTimer();
90 91
91 bool resume = true; 92 bool resume = true;
92 93 if (thread->HasWakeupCallback()) {
93 if (thread->HasWakeupCallback())
94 resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index); 94 resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index);
95 95 }
96 if (resume) 96 if (resume) {
97 thread->ResumeFromWait(); 97 thread->ResumeFromWait();
98 }
98} 99}
99 100
100void WaitObject::WakeupAllWaitingThreads() { 101void WaitObject::WakeupAllWaitingThreads() {
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 593bb681f..85b095688 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -227,8 +227,7 @@ QString WaitTreeThread::GetText() const {
227 case Kernel::ThreadStatus::WaitIPC: 227 case Kernel::ThreadStatus::WaitIPC:
228 status = tr("waiting for IPC reply"); 228 status = tr("waiting for IPC reply");
229 break; 229 break;
230 case Kernel::ThreadStatus::WaitSynchAll: 230 case Kernel::ThreadStatus::WaitSynch:
231 case Kernel::ThreadStatus::WaitSynchAny:
232 status = tr("waiting for objects"); 231 status = tr("waiting for objects");
233 break; 232 break;
234 case Kernel::ThreadStatus::WaitMutex: 233 case Kernel::ThreadStatus::WaitMutex:
@@ -269,8 +268,7 @@ QColor WaitTreeThread::GetColor() const {
269 return QColor(Qt::GlobalColor::darkRed); 268 return QColor(Qt::GlobalColor::darkRed);
270 case Kernel::ThreadStatus::WaitSleep: 269 case Kernel::ThreadStatus::WaitSleep:
271 return QColor(Qt::GlobalColor::darkYellow); 270 return QColor(Qt::GlobalColor::darkYellow);
272 case Kernel::ThreadStatus::WaitSynchAll: 271 case Kernel::ThreadStatus::WaitSynch:
273 case Kernel::ThreadStatus::WaitSynchAny:
274 case Kernel::ThreadStatus::WaitMutex: 272 case Kernel::ThreadStatus::WaitMutex:
275 case Kernel::ThreadStatus::WaitCondVar: 273 case Kernel::ThreadStatus::WaitCondVar:
276 case Kernel::ThreadStatus::WaitArb: 274 case Kernel::ThreadStatus::WaitArb:
@@ -325,10 +323,9 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
325 list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); 323 list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex")));
326 } 324 }
327 325
328 if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynchAny || 326 if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) {
329 thread.GetStatus() == Kernel::ThreadStatus::WaitSynchAll) {
330 list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjects(), 327 list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjects(),
331 thread.IsSleepingOnWaitAll())); 328 thread.IsSleepingOnWait()));
332 } 329 }
333 330
334 list.push_back(std::make_unique<WaitTreeCallstack>(thread)); 331 list.push_back(std::make_unique<WaitTreeCallstack>(thread));