|
|
|
@ -35,8 +35,11 @@ bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address |
|
|
|
|
|
|
|
// TODO(bunnei): We should call CanAccessAtomic(..) here.
|
|
|
|
|
|
|
|
s32 current_value{}; |
|
|
|
|
|
|
|
while (true) { |
|
|
|
// Load the value from the address.
|
|
|
|
const s32 current_value = |
|
|
|
current_value = |
|
|
|
static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address))); |
|
|
|
|
|
|
|
// Compare it to the desired one.
|
|
|
|
@ -45,14 +48,17 @@ bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address |
|
|
|
const s32 decrement_value = current_value - 1; |
|
|
|
|
|
|
|
// Decrement and try to store.
|
|
|
|
if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), |
|
|
|
if (monitor.ExclusiveWrite32(current_core, GetInteger(address), |
|
|
|
static_cast<u32>(decrement_value))) { |
|
|
|
// If we failed to store, try again.
|
|
|
|
DecrementIfLessThan(system, out, address, value); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
// If we failed to store, try again.
|
|
|
|
} else { |
|
|
|
// Otherwise, clear our exclusive hold and finish
|
|
|
|
monitor.ClearExclusive(current_core); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// We're done.
|
|
|
|
@ -70,8 +76,11 @@ bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 |
|
|
|
|
|
|
|
// TODO(bunnei): We should call CanAccessAtomic(..) here.
|
|
|
|
|
|
|
|
s32 current_value{}; |
|
|
|
|
|
|
|
// Load the value from the address.
|
|
|
|
const s32 current_value = |
|
|
|
while (true) { |
|
|
|
current_value = |
|
|
|
static_cast<s32>(monitor.ExclusiveRead32(current_core, GetInteger(address))); |
|
|
|
|
|
|
|
// Compare it to the desired one.
|
|
|
|
@ -79,14 +88,17 @@ bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 |
|
|
|
// If equal, we want to try to write the new value.
|
|
|
|
|
|
|
|
// Try to store.
|
|
|
|
if (!monitor.ExclusiveWrite32(current_core, GetInteger(address), |
|
|
|
if (monitor.ExclusiveWrite32(current_core, GetInteger(address), |
|
|
|
static_cast<u32>(new_value))) { |
|
|
|
// If we failed to store, try again.
|
|
|
|
UpdateIfEqual(system, out, address, value, new_value); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
// If we failed to store, try again.
|
|
|
|
} else { |
|
|
|
// Otherwise, clear our exclusive hold and finish.
|
|
|
|
monitor.ClearExclusive(current_core); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// We're done.
|
|
|
|
|