summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 61378211f..690cb20b3 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -247,12 +247,15 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
247 247
248 if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || 248 if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
249 thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { 249 thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) {
250 thread->wait_set_output = false; 250
251 // Invoke the wakeup callback before clearing the wait objects
252 if (thread->wakeup_callback)
253 thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr);
254
251 // Remove the thread from each of its waiting objects' waitlists 255 // Remove the thread from each of its waiting objects' waitlists
252 for (auto& object : thread->wait_objects) 256 for (auto& object : thread->wait_objects)
253 object->RemoveWaitingThread(thread.get()); 257 object->RemoveWaitingThread(thread.get());
254 thread->wait_objects.clear(); 258 thread->wait_objects.clear();
255 thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
256 } 259 }
257 260
258 thread->ResumeFromWait(); 261 thread->ResumeFromWait();
@@ -278,6 +281,9 @@ void Thread::ResumeFromWait() {
278 break; 281 break;
279 282
280 case THREADSTATUS_READY: 283 case THREADSTATUS_READY:
284 // The thread's wakeup callback must have already been cleared when the thread was first
285 // awoken.
286 ASSERT(wakeup_callback == nullptr);
281 // If the thread is waiting on multiple wait objects, it might be awoken more than once 287 // If the thread is waiting on multiple wait objects, it might be awoken more than once
282 // before actually resuming. We can ignore subsequent wakeups if the thread status has 288 // before actually resuming. We can ignore subsequent wakeups if the thread status has
283 // already been set to THREADSTATUS_READY. 289 // already been set to THREADSTATUS_READY.
@@ -293,6 +299,8 @@ void Thread::ResumeFromWait() {
293 return; 299 return;
294 } 300 }
295 301
302 wakeup_callback = nullptr;
303
296 ready_queue.push_back(current_priority, this); 304 ready_queue.push_back(current_priority, this);
297 status = THREADSTATUS_READY; 305 status = THREADSTATUS_READY;
298 Core::System::GetInstance().PrepareReschedule(); 306 Core::System::GetInstance().PrepareReschedule();
@@ -394,7 +402,6 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
394 thread->nominal_priority = thread->current_priority = priority; 402 thread->nominal_priority = thread->current_priority = priority;
395 thread->last_running_ticks = CoreTiming::GetTicks(); 403 thread->last_running_ticks = CoreTiming::GetTicks();
396 thread->processor_id = processor_id; 404 thread->processor_id = processor_id;
397 thread->wait_set_output = false;
398 thread->wait_objects.clear(); 405 thread->wait_objects.clear();
399 thread->wait_address = 0; 406 thread->wait_address = 0;
400 thread->name = std::move(name); 407 thread->name = std::move(name);