diff options
author | bunnei <bunneidev@gmail.com> | 2014-12-11 04:52:55 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2014-12-11 04:52:55 +0100 |
commit | 3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e (patch) | |
tree | 59d94738da7ef6f31ddbc8d4cbfbd58f578e25d8 /src/core/hle/kernel/mutex.cpp | |
parent | Merge pull request #239 from linkmauve/country-codes (diff) | |
parent | Mutex: Remove some forward declarations (diff) | |
download | yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.tar yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.tar.gz yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.tar.bz2 yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.tar.lz yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.tar.xz yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.tar.zst yuzu-3a75c8069e9c044f6a8f2fd80c7d35ea245a9f6e.zip |
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/mutex.cpp | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index d07e9761b..5a173e129 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -27,21 +27,7 @@ public: std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex std::string name; ///< Name of mutex (optional) - ResultVal<bool> SyncRequest() override { - // TODO(bunnei): ImplementMe - locked = true; - return MakeResult<bool>(false); - } - - ResultVal<bool> WaitSynchronization() override { - // TODO(bunnei): ImplementMe - bool wait = locked; - if (locked) { - Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); - } - - return MakeResult<bool>(wait); - } + ResultVal<bool> WaitSynchronization() override; }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -49,21 +35,46 @@ public: typedef std::multimap<Handle, Handle> MutexMap; static MutexMap g_mutex_held_locks; -void MutexAcquireLock(Mutex* mutex, Handle thread) { +/** + * Acquires the specified mutex for the specified thread + * @param mutex Mutex that is to be acquired + * @param thread Thread that will acquired + */ +void MutexAcquireLock(Mutex* mutex, Handle thread = GetCurrentThreadHandle()) { g_mutex_held_locks.insert(std::make_pair(thread, mutex->GetHandle())); mutex->lock_thread = thread; } -void MutexAcquireLock(Mutex* mutex) { - Handle thread = GetCurrentThreadHandle(); +bool ReleaseMutexForThread(Mutex* mutex, Handle thread) { MutexAcquireLock(mutex, thread); + Kernel::ResumeThreadFromWait(thread); + return true; +} + +/** + * Resumes a thread waiting for the specified mutex + * @param mutex The mutex that some thread is waiting on + */ +void ResumeWaitingThread(Mutex* mutex) { + // Find the next waiting thread for the mutex... + 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(); + ReleaseMutexForThread(mutex, *iter); + mutex->waiting_threads.erase(iter); + } } void MutexEraseLock(Mutex* mutex) { Handle handle = mutex->GetHandle(); auto locked = g_mutex_held_locks.equal_range(mutex->lock_thread); for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { - if ((*iter).second == handle) { + if (iter->second == handle) { g_mutex_held_locks.erase(iter); break; } @@ -71,6 +82,19 @@ void MutexEraseLock(Mutex* mutex) { mutex->lock_thread = -1; } +void ReleaseThreadMutexes(Handle thread) { + auto locked = g_mutex_held_locks.equal_range(thread); + + // Release every mutex that the thread holds, and resume execution on the waiting threads + for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { + Mutex* mutex = g_object_pool.GetFast<Mutex>(iter->second); + ResumeWaitingThread(mutex); + } + + // Erase all the locks that this thread holds + g_mutex_held_locks.erase(thread); +} + bool LockMutex(Mutex* mutex) { // Mutex alread locked? if (mutex->locked) { @@ -80,26 +104,9 @@ bool LockMutex(Mutex* mutex) { return true; } -bool ReleaseMutexForThread(Mutex* mutex, Handle thread) { - MutexAcquireLock(mutex, thread); - Kernel::ResumeThreadFromWait(thread); - return true; -} - bool ReleaseMutex(Mutex* mutex) { MutexEraseLock(mutex); - - // Find the next waiting thread for the mutex... - while (!mutex->waiting_threads.empty()) { - std::vector<Handle>::iterator iter = mutex->waiting_threads.begin(); - ReleaseMutexForThread(mutex, *iter); - mutex->waiting_threads.erase(iter); - } - - // Reset mutex lock thread handle, nothing is waiting - mutex->locked = false; - mutex->lock_thread = -1; - + ResumeWaitingThread(mutex); return true; } @@ -157,4 +164,17 @@ Handle CreateMutex(bool initial_locked, const std::string& name) { return handle; } +ResultVal<bool> Mutex::WaitSynchronization() { + bool wait = locked; + if (locked) { + Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); + } + else { + // Lock the mutex when the first thread accesses it + locked = true; + MutexAcquireLock(this); + } + + return MakeResult<bool>(wait); +} } // namespace |