diff options
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 33 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.h | 3 |
2 files changed, 20 insertions, 16 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 9f7166ca4..a811db392 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -21,7 +21,7 @@ namespace Kernel { | |||
| 21 | */ | 21 | */ |
| 22 | static void ResumeWaitingThread(Mutex* mutex) { | 22 | static void ResumeWaitingThread(Mutex* mutex) { |
| 23 | // Reset mutex lock thread handle, nothing is waiting | 23 | // Reset mutex lock thread handle, nothing is waiting |
| 24 | mutex->locked = false; | 24 | mutex->lock_count = 0; |
| 25 | mutex->holding_thread = nullptr; | 25 | mutex->holding_thread = nullptr; |
| 26 | 26 | ||
| 27 | // Find the next waiting thread for the mutex... | 27 | // Find the next waiting thread for the mutex... |
| @@ -44,8 +44,7 @@ Mutex::~Mutex() {} | |||
| 44 | SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) { | 44 | SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) { |
| 45 | SharedPtr<Mutex> mutex(new Mutex); | 45 | SharedPtr<Mutex> mutex(new Mutex); |
| 46 | 46 | ||
| 47 | mutex->initial_locked = initial_locked; | 47 | mutex->lock_count = 0; |
| 48 | mutex->locked = false; | ||
| 49 | mutex->name = std::move(name); | 48 | mutex->name = std::move(name); |
| 50 | mutex->holding_thread = nullptr; | 49 | mutex->holding_thread = nullptr; |
| 51 | 50 | ||
| @@ -57,7 +56,7 @@ SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) { | |||
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | bool Mutex::ShouldWait() { | 58 | bool Mutex::ShouldWait() { |
| 60 | return locked && holding_thread != GetCurrentThread(); | 59 | return lock_count > 0 && holding_thread != GetCurrentThread();; |
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | void Mutex::Acquire() { | 62 | void Mutex::Acquire() { |
| @@ -66,21 +65,27 @@ void Mutex::Acquire() { | |||
| 66 | 65 | ||
| 67 | void Mutex::Acquire(SharedPtr<Thread> thread) { | 66 | void Mutex::Acquire(SharedPtr<Thread> thread) { |
| 68 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); | 67 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); |
| 69 | if (locked) | ||
| 70 | return; | ||
| 71 | 68 | ||
| 72 | locked = true; | 69 | // Actually "acquire" the mutex only if we don't already have it... |
| 70 | if (lock_count == 0) { | ||
| 71 | thread->held_mutexes.insert(this); | ||
| 72 | holding_thread = std::move(thread); | ||
| 73 | } | ||
| 73 | 74 | ||
| 74 | thread->held_mutexes.insert(this); | 75 | lock_count++; |
| 75 | holding_thread = std::move(thread); | ||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | void Mutex::Release() { | 78 | void Mutex::Release() { |
| 79 | if (!locked) | 79 | // Only release if the mutex is held... |
| 80 | return; | 80 | if (lock_count > 0) { |
| 81 | 81 | lock_count--; | |
| 82 | holding_thread->held_mutexes.erase(this); | 82 | |
| 83 | ResumeWaitingThread(this); | 83 | // Yield to the next thread only if we've fully released the mutex... |
| 84 | if (lock_count == 0) { | ||
| 85 | holding_thread->held_mutexes.erase(this); | ||
| 86 | ResumeWaitingThread(this); | ||
| 87 | } | ||
| 88 | } | ||
| 84 | } | 89 | } |
| 85 | 90 | ||
| 86 | } // namespace | 91 | } // namespace |
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 548403614..d6d5328be 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h | |||
| @@ -30,8 +30,7 @@ public: | |||
| 30 | static const HandleType HANDLE_TYPE = HandleType::Mutex; | 30 | static const HandleType HANDLE_TYPE = HandleType::Mutex; |
| 31 | HandleType GetHandleType() const override { return HANDLE_TYPE; } | 31 | HandleType GetHandleType() const override { return HANDLE_TYPE; } |
| 32 | 32 | ||
| 33 | bool initial_locked; ///< Initial lock state when mutex was created | 33 | int lock_count; ///< Number of times the mutex has been acquired |
| 34 | bool locked; ///< Current locked state | ||
| 35 | std::string name; ///< Name of mutex (optional) | 34 | std::string name; ///< Name of mutex (optional) |
| 36 | SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex | 35 | SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex |
| 37 | 36 | ||