From 0209de123b0e8dfd793d23c6a9cb825ea6da5b8e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 7 Mar 2019 18:34:22 -0500 Subject: 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. --- src/core/hle/kernel/address_arbiter.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/address_arbiter.cpp') diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 9780a7849..b6269c708 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -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 current_thread = system.CurrentScheduler().GetCurrentThread(); current_thread->SetArbiterWaitAddress(address); current_thread->SetStatus(ThreadStatus::WaitArb); -- cgit v1.2.3 From b7f331afa3db235db39eca041fef720873f3091a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 7 Mar 2019 18:42:44 -0500 Subject: kernel/svc: Move address arbiter signaling behind a unified API function Similar to how WaitForAddress was isolated to its own function, we can also move the necessary conditional checking into the address arbiter class itself, allowing us to hide the implementation details of it from public use. --- src/core/hle/kernel/address_arbiter.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/address_arbiter.cpp') diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index b6269c708..352190da8 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -42,7 +42,21 @@ void WakeThreads(const std::vector>& waiting_threads, s32 num_ AddressArbiter::AddressArbiter(Core::System& system) : system{system} {} AddressArbiter::~AddressArbiter() = default; -ResultCode AddressArbiter::SignalToAddress(VAddr address, s32 num_to_wake) { +ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 value, + s32 num_to_wake) { + switch (type) { + case SignalType::Signal: + return SignalToAddressOnly(address, num_to_wake); + case SignalType::IncrementAndSignalIfEqual: + return IncrementAndSignalToAddressIfEqual(address, value, num_to_wake); + case SignalType::ModifyByWaitingCountAndSignalIfEqual: + return ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, num_to_wake); + default: + return ERR_INVALID_ENUM_VALUE; + } +} + +ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) { const std::vector> waiting_threads = GetThreadsWaitingOnAddress(address); WakeThreads(waiting_threads, num_to_wake); return RESULT_SUCCESS; @@ -60,7 +74,7 @@ ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 } Memory::Write32(address, static_cast(value + 1)); - return SignalToAddress(address, num_to_wake); + return SignalToAddressOnly(address, num_to_wake); } ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, -- cgit v1.2.3