citra-emu
/
citra
Archived
1
0
Fork 0

Mutex: Properly lock the mutex when a thread enters it

Also resume only the next immediate thread waiting for the mutex when it is released, instead of resuming them all.
This commit is contained in:
Subv 2014-12-05 23:40:43 -05:00
parent 17fae11fc7
commit e3c8e4901c
1 changed files with 9 additions and 12 deletions

View File

@ -27,17 +27,13 @@ public:
std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex
std::string name; ///< Name of mutex (optional) std::string name; ///< Name of mutex (optional)
ResultVal<bool> SyncRequest() override {
// TODO(bunnei): ImplementMe
locked = true;
return MakeResult<bool>(false);
}
ResultVal<bool> WaitSynchronization() override { ResultVal<bool> WaitSynchronization() override {
// TODO(bunnei): ImplementMe
bool wait = locked; bool wait = locked;
if (locked) { if (locked) {
Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle());
} else {
// Lock the mutex when the first thread accesses it
locked = true;
} }
return MakeResult<bool>(wait); return MakeResult<bool>(wait);
@ -90,16 +86,17 @@ bool ReleaseMutex(Mutex* mutex) {
MutexEraseLock(mutex); MutexEraseLock(mutex);
// Find the next waiting thread for the mutex... // Find the next waiting thread for the mutex...
while (!mutex->waiting_threads.empty()) { if (mutex->waiting_threads.empty()) {
// Reset mutex lock thread handle, nothing is waiting
mutex->locked = false;
mutex->lock_thread = -1;
} else {
// Resume the next waiting thread and re-lock the mutex
std::vector<Handle>::iterator iter = mutex->waiting_threads.begin(); std::vector<Handle>::iterator iter = mutex->waiting_threads.begin();
ReleaseMutexForThread(mutex, *iter); ReleaseMutexForThread(mutex, *iter);
mutex->waiting_threads.erase(iter); mutex->waiting_threads.erase(iter);
} }
// Reset mutex lock thread handle, nothing is waiting
mutex->locked = false;
mutex->lock_thread = -1;
return true; return true;
} }