diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 2 | 
2 files changed, 18 insertions, 9 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;  } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c08fc1c7a..bf32f653d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -300,7 +300,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {      thread->waitsynch_waited = false; -    if (thread->status == THREADSTATUS_WAIT_SYNCH) { +    if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) {          thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,                                                          ErrorSummary::StatusChanged, ErrorLevel::Info));  | 
