diff options
| author | bunnei <bunneidev@gmail.com> | 2022-01-21 17:10:11 -0800 |
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2022-01-21 17:12:06 -0800 |
| commit | b3f8d2491db60f67c88c76cd0d6c483aad34c708 (patch) | |
| tree | 8220ac1a9435933b995c4eab0e2e334daad3af11 /src/core/hle/kernel/k_thread.cpp | |
| parent | 8f2630de0a82731e2e9adfb4cf1203339128d61e (diff) | |
hle: kernel: KThread: Ensure host (dummy) threads block on locking.
- But do not enter the priority queue, as otherwise they will be scheduled.
- Allows dummy threads to use guest synchronization primitives.
Diffstat (limited to 'src/core/hle/kernel/k_thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 4cbf12c113..f42abb8a11 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -1075,12 +1075,46 @@ ResultCode KThread::Sleep(s64 timeout) { return ResultSuccess; } +void KThread::IfDummyThreadTryWait() { + if (!IsDummyThread()) { + return; + } + + if (GetState() != ThreadState::Waiting) { + return; + } + + // Block until we can grab the lock. + KScopedSpinLock lk{dummy_wait_lock}; +} + +void KThread::IfDummyThreadBeginWait() { + if (!IsDummyThread()) { + return; + } + + // Ensure the thread will block when IfDummyThreadTryWait is called. + dummy_wait_lock.Lock(); +} + +void KThread::IfDummyThreadEndWait() { + if (!IsDummyThread()) { + return; + } + + // Ensure the thread will no longer block. + dummy_wait_lock.Unlock(); +} + void KThread::BeginWait(KThreadQueue* queue) { // Set our state as waiting. SetState(ThreadState::Waiting); // Set our wait queue. wait_queue = queue; + + // Special case for dummy threads to ensure they block. + IfDummyThreadBeginWait(); } void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, ResultCode wait_result_) { @@ -1106,6 +1140,9 @@ void KThread::EndWait(ResultCode wait_result_) { } wait_queue->EndWait(this, wait_result_); + + // Special case for dummy threads to wakeup if necessary. + IfDummyThreadEndWait(); } } |
