summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/mutex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/mutex.cpp')
-rw-r--r--src/core/hle/kernel/mutex.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 18325db57..ebe3f6050 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -9,6 +9,7 @@
9#include "common/assert.h" 9#include "common/assert.h"
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/arm/exclusive_monitor.h"
12#include "core/hle/kernel/errors.h" 13#include "core/hle/kernel/errors.h"
13#include "core/hle/kernel/handle_table.h" 14#include "core/hle/kernel/handle_table.h"
14#include "core/hle/kernel/kernel.h" 15#include "core/hle/kernel/kernel.h"
@@ -133,8 +134,12 @@ std::pair<ResultCode, std::shared_ptr<Thread>> Mutex::Unlock(std::shared_ptr<Thr
133 } 134 }
134 135
135 auto [new_owner, num_waiters] = GetHighestPriorityMutexWaitingThread(owner, address); 136 auto [new_owner, num_waiters] = GetHighestPriorityMutexWaitingThread(owner, address);
137 auto& monitor = system.Monitor();
138 const std::size_t current_core = system.CurrentCoreIndex();
136 if (new_owner == nullptr) { 139 if (new_owner == nullptr) {
137 system.Memory().Write32(address, 0); 140 do {
141 monitor.SetExclusive(current_core, address);
142 } while (!monitor.ExclusiveWrite32(current_core, address, 0));
138 return {RESULT_SUCCESS, nullptr}; 143 return {RESULT_SUCCESS, nullptr};
139 } 144 }
140 // Transfer the ownership of the mutex from the previous owner to the new one. 145 // Transfer the ownership of the mutex from the previous owner to the new one.
@@ -145,9 +150,12 @@ std::pair<ResultCode, std::shared_ptr<Thread>> Mutex::Unlock(std::shared_ptr<Thr
145 mutex_value |= Mutex::MutexHasWaitersFlag; 150 mutex_value |= Mutex::MutexHasWaitersFlag;
146 } 151 }
147 new_owner->SetSynchronizationResults(nullptr, RESULT_SUCCESS); 152 new_owner->SetSynchronizationResults(nullptr, RESULT_SUCCESS);
148 new_owner->ResumeFromWait();
149 new_owner->SetLockOwner(nullptr); 153 new_owner->SetLockOwner(nullptr);
150 system.Memory().Write32(address, mutex_value); 154 new_owner->ResumeFromWait();
155
156 do {
157 monitor.SetExclusive(current_core, address);
158 } while (!monitor.ExclusiveWrite32(current_core, address, mutex_value));
151 return {RESULT_SUCCESS, new_owner}; 159 return {RESULT_SUCCESS, new_owner};
152} 160}
153 161