diff options
| author | bunnei <bunneidev@gmail.com> | 2023-04-01 01:54:36 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-01 01:54:36 -0700 |
| commit | 0730dc6c44d8b589efeb80d974650c72ba44c4f7 (patch) | |
| tree | 90ebabf2585fef813efec5e3f751dc9914407416 /src/core/hle/kernel/k_condition_variable.cpp | |
| parent | fbf0a9c9762bf2a7ea4a4da3ea8419e32e15beba (diff) | |
| parent | 9efd95cda50605c52a9652b5ad01e09e6fd86106 (diff) | |
Merge pull request #10005 from liamwhite/kernel-atomics
kernel: fix unbounded stack usage in atomics
Diffstat (limited to 'src/core/hle/kernel/k_condition_variable.cpp')
| -rw-r--r-- | src/core/hle/kernel/k_condition_variable.cpp | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 73017cf99..efbac0e6a 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -33,21 +33,26 @@ bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u auto& monitor = system.Monitor(); const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); - // Load the value from the address. - const auto expected = monitor.ExclusiveRead32(current_core, GetInteger(address)); + u32 expected{}; - // Orr in the new mask. - u32 value = expected | new_orr_mask; + while (true) { + // Load the value from the address. + expected = monitor.ExclusiveRead32(current_core, GetInteger(address)); - // If the value is zero, use the if_zero value, otherwise use the newly orr'd value. - if (!expected) { - value = if_zero; - } + // Orr in the new mask. + u32 value = expected | new_orr_mask; + + // If the value is zero, use the if_zero value, otherwise use the newly orr'd value. + if (!expected) { + value = if_zero; + } + + // Try to store. + if (monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) { + break; + } - // Try to store. - if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), value)) { // If we failed to store, try again. - return UpdateLockAtomic(system, out, address, if_zero, new_orr_mask); } // We're done. |
