diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index 178dbe447..62c445635 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -1201,9 +1201,11 @@ DECLARE_XBOXKRNL_EXPORT2(ExAcquireReadWriteLockExclusive, kThreading, void ExReleaseReadWriteLock(pointer_t lock_ptr) { auto old_irql = xeKeKfAcquireSpinLock(&lock_ptr->spin_lock); - lock_ptr->lock_count--; - if (lock_ptr->lock_count < 0) { + int32_t lock_count = --lock_ptr->lock_count; + + if (lock_count < 0) { + lock_ptr->readers_entry_count = 0; xeKeKfReleaseSpinLock(&lock_ptr->spin_lock, old_irql); return; } @@ -1220,14 +1222,17 @@ void ExReleaseReadWriteLock(pointer_t lock_ptr) { } } - auto count = lock_ptr->readers_entry_count--; - xeKeKfReleaseSpinLock(&lock_ptr->spin_lock, old_irql); - if (!count) { - xeKeSetEvent(&lock_ptr->writer_event, 1, 0); + auto readers_entry_count = --lock_ptr->readers_entry_count; + if (readers_entry_count) { + xeKeKfReleaseSpinLock(&lock_ptr->spin_lock, old_irql); + return; } + + lock_ptr->writers_waiting_count--; + xeKeKfReleaseSpinLock(&lock_ptr->spin_lock, old_irql); + xeKeSetEvent(&lock_ptr->writer_event, 1, 0); } -DECLARE_XBOXKRNL_EXPORT2(ExReleaseReadWriteLock, kThreading, kImplemented, - kSketchy); +DECLARE_XBOXKRNL_EXPORT1(ExReleaseReadWriteLock, kThreading, kImplemented); // NOTE: This function is very commonly inlined, and probably won't be called! pointer_result_t InterlockedPushEntrySList(