forked from suyu/suyu
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:
parent
3b63a46ca4
commit
0209de123b
3 changed files with 24 additions and 19 deletions
|
@ -92,6 +92,20 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a
|
||||||
return RESULT_SUCCESS;
|
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,
|
ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
|
||||||
bool should_decrement) {
|
bool should_decrement) {
|
||||||
// Ensure that we can read the address.
|
// Ensure that we can read the address.
|
||||||
|
@ -113,7 +127,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
|
||||||
return RESULT_TIMEOUT;
|
return RESULT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return WaitForAddress(address, timeout);
|
return WaitForAddressImpl(address, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 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 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();
|
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||||
current_thread->SetArbiterWaitAddress(address);
|
current_thread->SetArbiterWaitAddress(address);
|
||||||
current_thread->SetStatus(ThreadStatus::WaitArb);
|
current_thread->SetStatus(ThreadStatus::WaitArb);
|
||||||
|
|
|
@ -51,6 +51,10 @@ public:
|
||||||
ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
|
ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
|
||||||
s32 num_to_wake);
|
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,
|
/// Waits on an address if the value passed is less than the argument value,
|
||||||
/// optionally decrementing.
|
/// optionally decrementing.
|
||||||
ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
|
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.
|
/// Waits on an address if the value passed is equal to the argument value.
|
||||||
ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout);
|
ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout);
|
||||||
|
|
||||||
private:
|
|
||||||
// Waits on the given address with a timeout in nanoseconds
|
// 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.
|
// Gets the threads waiting on an address.
|
||||||
std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
|
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;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
|
||||||
auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
|
auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
|
||||||
switch (static_cast<AddressArbiter::ArbitrationType>(type)) {
|
return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signals to an address (via Address Arbiter)
|
// Signals to an address (via Address Arbiter)
|
||||||
|
|
Loading…
Reference in a new issue