kernel/svc: Move address arbiter waiting behind a unified API function
Rather than let the service call itself work out which function is the proper one to call, we can make that a behavior of the arbiter itself, so we don't need to directly expose those implementation details.
This commit is contained in:
		@@ -92,6 +92,20 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s32 value,
 | 
			
		||||
                                          s64 timeout_ns) {
 | 
			
		||||
    switch (type) {
 | 
			
		||||
    case ArbitrationType::WaitIfLessThan:
 | 
			
		||||
        return WaitForAddressIfLessThan(address, value, timeout_ns, false);
 | 
			
		||||
    case ArbitrationType::DecrementAndWaitIfLessThan:
 | 
			
		||||
        return WaitForAddressIfLessThan(address, value, timeout_ns, true);
 | 
			
		||||
    case ArbitrationType::WaitIfEqual:
 | 
			
		||||
        return WaitForAddressIfEqual(address, value, timeout_ns);
 | 
			
		||||
    default:
 | 
			
		||||
        return ERR_INVALID_ENUM_VALUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
 | 
			
		||||
                                                    bool should_decrement) {
 | 
			
		||||
    // Ensure that we can read the address.
 | 
			
		||||
@@ -113,7 +127,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
 | 
			
		||||
        return RESULT_TIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return WaitForAddress(address, timeout);
 | 
			
		||||
    return WaitForAddressImpl(address, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) {
 | 
			
		||||
@@ -130,10 +144,10 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
 | 
			
		||||
        return RESULT_TIMEOUT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return WaitForAddress(address, timeout);
 | 
			
		||||
    return WaitForAddressImpl(address, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode AddressArbiter::WaitForAddress(VAddr address, s64 timeout) {
 | 
			
		||||
ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) {
 | 
			
		||||
    SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
 | 
			
		||||
    current_thread->SetArbiterWaitAddress(address);
 | 
			
		||||
    current_thread->SetStatus(ThreadStatus::WaitArb);
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,10 @@ public:
 | 
			
		||||
    ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
 | 
			
		||||
                                                             s32 num_to_wake);
 | 
			
		||||
 | 
			
		||||
    /// Waits on an address with a particular arbitration type.
 | 
			
		||||
    ResultCode WaitForAddress(VAddr address, ArbitrationType type, s32 value, s64 timeout_ns);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /// Waits on an address if the value passed is less than the argument value,
 | 
			
		||||
    /// optionally decrementing.
 | 
			
		||||
    ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
 | 
			
		||||
@@ -59,9 +63,8 @@ public:
 | 
			
		||||
    /// Waits on an address if the value passed is equal to the argument value.
 | 
			
		||||
    ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    // Waits on the given address with a timeout in nanoseconds
 | 
			
		||||
    ResultCode WaitForAddress(VAddr address, s64 timeout);
 | 
			
		||||
    ResultCode WaitForAddressImpl(VAddr address, s64 timeout);
 | 
			
		||||
 | 
			
		||||
    // Gets the threads waiting on an address.
 | 
			
		||||
    std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
 | 
			
		||||
 
 | 
			
		||||
@@ -1479,21 +1479,9 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
 | 
			
		||||
        return ERR_INVALID_ADDRESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
 | 
			
		||||
    auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
 | 
			
		||||
    switch (static_cast<AddressArbiter::ArbitrationType>(type)) {
 | 
			
		||||
    case AddressArbiter::ArbitrationType::WaitIfLessThan:
 | 
			
		||||
        return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, false);
 | 
			
		||||
    case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan:
 | 
			
		||||
        return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, true);
 | 
			
		||||
    case AddressArbiter::ArbitrationType::WaitIfEqual:
 | 
			
		||||
        return address_arbiter.WaitForAddressIfEqual(address, value, timeout);
 | 
			
		||||
    default:
 | 
			
		||||
        LOG_ERROR(Kernel_SVC,
 | 
			
		||||
                  "Invalid arbitration type, expected WaitIfLessThan, DecrementAndWaitIfLessThan "
 | 
			
		||||
                  "or WaitIfEqual but got {}",
 | 
			
		||||
                  type);
 | 
			
		||||
        return ERR_INVALID_ENUM_VALUE;
 | 
			
		||||
    }
 | 
			
		||||
    return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Signals to an address (via Address Arbiter)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user