|
|
|
@ -45,30 +45,32 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
|
|
|
|
|
|
|
|
|
|
// Wait current thread (acquire the arbiter)...
|
|
|
|
|
case ArbitrationType::WaitIfLessThan:
|
|
|
|
|
if ((s32)Memory::Read32(address) <= value) {
|
|
|
|
|
if ((s32)Memory::Read32(address) < value) {
|
|
|
|
|
Kernel::WaitCurrentThread_ArbitrateAddress(address);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ArbitrationType::WaitIfLessThanWithTimeout:
|
|
|
|
|
if ((s32)Memory::Read32(address) <= value) {
|
|
|
|
|
if ((s32)Memory::Read32(address) < value) {
|
|
|
|
|
Kernel::WaitCurrentThread_ArbitrateAddress(address);
|
|
|
|
|
GetCurrentThread()->WakeAfterDelay(nanoseconds);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ArbitrationType::DecrementAndWaitIfLessThan:
|
|
|
|
|
{
|
|
|
|
|
s32 memory_value = Memory::Read32(address) - 1;
|
|
|
|
|
Memory::Write32(address, memory_value);
|
|
|
|
|
if (memory_value <= value) {
|
|
|
|
|
s32 memory_value = Memory::Read32(address);
|
|
|
|
|
if (memory_value < value) {
|
|
|
|
|
// Only change the memory value if the thread should wait
|
|
|
|
|
Memory::Write32(address, (s32)memory_value - 1);
|
|
|
|
|
Kernel::WaitCurrentThread_ArbitrateAddress(address);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout:
|
|
|
|
|
{
|
|
|
|
|
s32 memory_value = Memory::Read32(address) - 1;
|
|
|
|
|
Memory::Write32(address, memory_value);
|
|
|
|
|
if (memory_value <= value) {
|
|
|
|
|
s32 memory_value = Memory::Read32(address);
|
|
|
|
|
if (memory_value < value) {
|
|
|
|
|
// Only change the memory value if the thread should wait
|
|
|
|
|
Memory::Write32(address, (s32)memory_value - 1);
|
|
|
|
|
Kernel::WaitCurrentThread_ArbitrateAddress(address);
|
|
|
|
|
GetCurrentThread()->WakeAfterDelay(nanoseconds);
|
|
|
|
|
}
|
|
|
|
@ -82,6 +84,13 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
|
|
|
|
|
|
|
|
|
|
HLE::Reschedule(__func__);
|
|
|
|
|
|
|
|
|
|
// The calls that use a timeout seem to always return a Timeout error even if they did not put the thread to sleep
|
|
|
|
|
if (type == ArbitrationType::WaitIfLessThanWithTimeout ||
|
|
|
|
|
type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) {
|
|
|
|
|
|
|
|
|
|
return ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
|
|
|
|
|
ErrorSummary::StatusChanged, ErrorLevel::Info);
|
|
|
|
|
}
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|