aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/address_arbiter.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2015-12-28 22:23:51 -0500
committerbunnei <bunneidev@gmail.com>2015-12-28 22:23:51 -0500
commit73740d74ed1dabccc8304a0ac4cfb737c91864ba (patch)
treeb152c877f36be3f1f5da562b469207be9006bdd5 /src/core/hle/kernel/address_arbiter.cpp
parent23f5d5a7761aaaeadbe942d22ddb316f18ca9037 (diff)
parent29032ce9b6de56de60c146832bd88b06062fccac (diff)
Merge pull request #1300 from Subv/arbitrateaddress
SVC: Fixed ArbitrateAddress to behave as it does on hardware.
Diffstat (limited to 'src/core/hle/kernel/address_arbiter.cpp')
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 195286422..5c3c47acf 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -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;
}