diff options
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f9d821a80..111c496b9 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -244,20 +244,23 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 244 | return; | 244 | return; |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | bool resume = true; | ||
| 248 | |||
| 247 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | 249 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || |
| 248 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { | 250 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { |
| 249 | 251 | ||
| 250 | // Invoke the wakeup callback before clearing the wait objects | ||
| 251 | if (thread->wakeup_callback) | ||
| 252 | thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr); | ||
| 253 | |||
| 254 | // Remove the thread from each of its waiting objects' waitlists | 252 | // Remove the thread from each of its waiting objects' waitlists |
| 255 | for (auto& object : thread->wait_objects) | 253 | for (auto& object : thread->wait_objects) |
| 256 | object->RemoveWaitingThread(thread.get()); | 254 | object->RemoveWaitingThread(thread.get()); |
| 257 | thread->wait_objects.clear(); | 255 | thread->wait_objects.clear(); |
| 256 | |||
| 257 | // Invoke the wakeup callback before clearing the wait objects | ||
| 258 | if (thread->wakeup_callback) | ||
| 259 | resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0); | ||
| 258 | } | 260 | } |
| 259 | 261 | ||
| 260 | thread->ResumeFromWait(); | 262 | if (resume) |
| 263 | thread->ResumeFromWait(); | ||
| 261 | } | 264 | } |
| 262 | 265 | ||
| 263 | void Thread::WakeAfterDelay(s64 nanoseconds) { | 266 | void Thread::WakeAfterDelay(s64 nanoseconds) { |
| @@ -268,6 +271,10 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { | |||
| 268 | CoreTiming::ScheduleEvent(nsToCycles(nanoseconds), ThreadWakeupEventType, callback_handle); | 271 | CoreTiming::ScheduleEvent(nsToCycles(nanoseconds), ThreadWakeupEventType, callback_handle); |
| 269 | } | 272 | } |
| 270 | 273 | ||
| 274 | void Thread::CancelWakeupTimer() { | ||
| 275 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); | ||
| 276 | } | ||
| 277 | |||
| 271 | void Thread::ResumeFromWait() { | 278 | void Thread::ResumeFromWait() { |
| 272 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); | 279 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); |
| 273 | 280 | ||
| @@ -444,7 +451,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 444 | // Map the page to the current process' address space. | 451 | // Map the page to the current process' address space. |
| 445 | // TODO(Subv): Find the correct MemoryState for this region. | 452 | // TODO(Subv): Find the correct MemoryState for this region. |
| 446 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, | 453 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, |
| 447 | linheap_memory, offset, Memory::PAGE_SIZE, MemoryState::ThreadLocalStorage); | 454 | linheap_memory, offset, Memory::PAGE_SIZE, |
| 455 | MemoryState::ThreadLocalStorage); | ||
| 448 | } | 456 | } |
| 449 | 457 | ||
| 450 | // Mark the slot as used | 458 | // Mark the slot as used |
| @@ -501,7 +509,8 @@ SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority, | |||
| 501 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); | 509 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); |
| 502 | 510 | ||
| 503 | // Register 1 must be a handle to the main thread | 511 | // Register 1 must be a handle to the main thread |
| 504 | thread->guest_handle = Kernel::g_handle_table.Create(thread).Unwrap();; | 512 | thread->guest_handle = Kernel::g_handle_table.Create(thread).Unwrap(); |
| 513 | |||
| 505 | thread->context.cpu_registers[1] = thread->guest_handle; | 514 | thread->context.cpu_registers[1] = thread->guest_handle; |
| 506 | 515 | ||
| 507 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires | 516 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires |
| @@ -572,4 +581,4 @@ const std::vector<SharedPtr<Thread>>& GetThreadList() { | |||
| 572 | return thread_list; | 581 | return thread_list; |
| 573 | } | 582 | } |
| 574 | 583 | ||
| 575 | } // namespace | 584 | } // namespace Kernel |