diff options
| author | 2020-03-04 22:46:22 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:26 -0400 | |
| commit | a6bce296ad3fa8e7da66df3d32cd148448ac0abb (patch) | |
| tree | 8f34d1546bb17d88b04a9aabdf62b01bbcc10eb5 /src/core/hle/kernel/mutex.cpp | |
| parent | SVC: Correct svcWaitForAddress and svcSignalToAddress. (diff) | |
| download | yuzu-a6bce296ad3fa8e7da66df3d32cd148448ac0abb.tar.gz yuzu-a6bce296ad3fa8e7da66df3d32cd148448ac0abb.tar.xz yuzu-a6bce296ad3fa8e7da66df3d32cd148448ac0abb.zip | |
Mutex: Correct Result writting to clear exclusivity.
Diffstat (limited to 'src/core/hle/kernel/mutex.cpp')
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 14 |
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 | ||