mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Merge pull request #480 from Subv/arb_2
AddrArbiter: Implement arbitration types 3 and 4.
This commit is contained in:
		@@ -29,7 +29,7 @@ public:
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
/// Arbitrate an address
 | 
			
		||||
ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) {
 | 
			
		||||
ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value, u64 nanoseconds) {
 | 
			
		||||
    Object* object = Kernel::g_handle_table.GetGeneric(handle).get();
 | 
			
		||||
    if (object == nullptr)
 | 
			
		||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
			
		||||
@@ -55,7 +55,13 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
 | 
			
		||||
            HLE::Reschedule(__func__);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    
 | 
			
		||||
    case ArbitrationType::WaitIfLessThanWithTimeout:
 | 
			
		||||
        if ((s32)Memory::Read32(address) <= value) {
 | 
			
		||||
            Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address);
 | 
			
		||||
            Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds);
 | 
			
		||||
            HLE::Reschedule(__func__);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case ArbitrationType::DecrementAndWaitIfLessThan:
 | 
			
		||||
    {
 | 
			
		||||
        s32 memory_value = Memory::Read32(address) - 1;
 | 
			
		||||
@@ -66,6 +72,17 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout:
 | 
			
		||||
    {
 | 
			
		||||
        s32 memory_value = Memory::Read32(address) - 1;
 | 
			
		||||
        Memory::Write32(address, memory_value);
 | 
			
		||||
        if (memory_value <= value) {
 | 
			
		||||
            Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address);
 | 
			
		||||
            Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds);
 | 
			
		||||
            HLE::Reschedule(__func__);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        LOG_ERROR(Kernel, "unknown type=%d", type);
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ enum class ArbitrationType : u32 {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Arbitrate an address
 | 
			
		||||
ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value);
 | 
			
		||||
ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value, u64 nanoseconds);
 | 
			
		||||
 | 
			
		||||
/// Create an address arbiter
 | 
			
		||||
Handle CreateAddressArbiter(const std::string& name = "Unknown");
 | 
			
		||||
 
 | 
			
		||||
@@ -194,7 +194,7 @@ static Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value,
 | 
			
		||||
    LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", arbiter,
 | 
			
		||||
        address, type, value);
 | 
			
		||||
    return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type),
 | 
			
		||||
            address, value).raw;
 | 
			
		||||
            address, value, nanoseconds).raw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user