mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	SVC: Fixed ArbitrateAddress to behave as it does on hardware.
This was verified with hwtests that i plan to upload later on.
This commit is contained in:
		@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user