Explorar o código

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.
Lioncash %!s(int64=7) %!d(string=hai) anos
pai
achega
0209de123b

+ 17 - 3
src/core/hle/kernel/address_arbiter.cpp

@@ -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);

+ 5 - 2
src/core/hle/kernel/address_arbiter.h

@@ -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;

+ 2 - 14
src/core/hle/kernel/svc.cpp

@@ -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)) {
-    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)
 // Signals to an address (via Address Arbiter)