diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.h | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 16 |
3 files changed, 24 insertions, 19 deletions
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 | |||
| 92 | return RESULT_SUCCESS; | 92 | return RESULT_SUCCESS; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s32 value, | ||
| 96 | s64 timeout_ns) { | ||
| 97 | switch (type) { | ||
| 98 | case ArbitrationType::WaitIfLessThan: | ||
| 99 | return WaitForAddressIfLessThan(address, value, timeout_ns, false); | ||
| 100 | case ArbitrationType::DecrementAndWaitIfLessThan: | ||
| 101 | return WaitForAddressIfLessThan(address, value, timeout_ns, true); | ||
| 102 | case ArbitrationType::WaitIfEqual: | ||
| 103 | return WaitForAddressIfEqual(address, value, timeout_ns); | ||
| 104 | default: | ||
| 105 | return ERR_INVALID_ENUM_VALUE; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 95 | ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, | 109 | ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, |
| 96 | bool should_decrement) { | 110 | bool should_decrement) { |
| 97 | // Ensure that we can read the address. | 111 | // Ensure that we can read the address. |
| @@ -113,7 +127,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6 | |||
| 113 | return RESULT_TIMEOUT; | 127 | return RESULT_TIMEOUT; |
| 114 | } | 128 | } |
| 115 | 129 | ||
| 116 | return WaitForAddress(address, timeout); | 130 | return WaitForAddressImpl(address, timeout); |
| 117 | } | 131 | } |
| 118 | 132 | ||
| 119 | ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { | 133 | ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { |
| @@ -130,10 +144,10 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t | |||
| 130 | return RESULT_TIMEOUT; | 144 | return RESULT_TIMEOUT; |
| 131 | } | 145 | } |
| 132 | 146 | ||
| 133 | return WaitForAddress(address, timeout); | 147 | return WaitForAddressImpl(address, timeout); |
| 134 | } | 148 | } |
| 135 | 149 | ||
| 136 | ResultCode AddressArbiter::WaitForAddress(VAddr address, s64 timeout) { | 150 | ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) { |
| 137 | SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread(); | 151 | SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread(); |
| 138 | current_thread->SetArbiterWaitAddress(address); | 152 | current_thread->SetArbiterWaitAddress(address); |
| 139 | current_thread->SetStatus(ThreadStatus::WaitArb); | 153 | current_thread->SetStatus(ThreadStatus::WaitArb); |
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index e0c36f2e3..ebda75b2a 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h | |||
| @@ -51,6 +51,10 @@ public: | |||
| 51 | ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, | 51 | ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, |
| 52 | s32 num_to_wake); | 52 | s32 num_to_wake); |
| 53 | 53 | ||
| 54 | /// Waits on an address with a particular arbitration type. | ||
| 55 | ResultCode WaitForAddress(VAddr address, ArbitrationType type, s32 value, s64 timeout_ns); | ||
| 56 | |||
| 57 | private: | ||
| 54 | /// Waits on an address if the value passed is less than the argument value, | 58 | /// Waits on an address if the value passed is less than the argument value, |
| 55 | /// optionally decrementing. | 59 | /// optionally decrementing. |
| 56 | ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, | 60 | ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, |
| @@ -59,9 +63,8 @@ public: | |||
| 59 | /// Waits on an address if the value passed is equal to the argument value. | 63 | /// Waits on an address if the value passed is equal to the argument value. |
| 60 | ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); | 64 | ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); |
| 61 | 65 | ||
| 62 | private: | ||
| 63 | // Waits on the given address with a timeout in nanoseconds | 66 | // Waits on the given address with a timeout in nanoseconds |
| 64 | ResultCode WaitForAddress(VAddr address, s64 timeout); | 67 | ResultCode WaitForAddressImpl(VAddr address, s64 timeout); |
| 65 | 68 | ||
| 66 | // Gets the threads waiting on an address. | 69 | // Gets the threads waiting on an address. |
| 67 | std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const; | 70 | std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7f5c0cc86..82ceb235c 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1479,21 +1479,9 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 1479 | return ERR_INVALID_ADDRESS; | 1479 | return ERR_INVALID_ADDRESS; |
| 1480 | } | 1480 | } |
| 1481 | 1481 | ||
| 1482 | const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type); | ||
| 1482 | auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter(); | 1483 | auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter(); |
| 1483 | switch (static_cast<AddressArbiter::ArbitrationType>(type)) { | 1484 | return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); |
| 1484 | case AddressArbiter::ArbitrationType::WaitIfLessThan: | ||
| 1485 | return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, false); | ||
| 1486 | case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan: | ||
| 1487 | return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, true); | ||
| 1488 | case AddressArbiter::ArbitrationType::WaitIfEqual: | ||
| 1489 | return address_arbiter.WaitForAddressIfEqual(address, value, timeout); | ||
| 1490 | default: | ||
| 1491 | LOG_ERROR(Kernel_SVC, | ||
| 1492 | "Invalid arbitration type, expected WaitIfLessThan, DecrementAndWaitIfLessThan " | ||
| 1493 | "or WaitIfEqual but got {}", | ||
| 1494 | type); | ||
| 1495 | return ERR_INVALID_ENUM_VALUE; | ||
| 1496 | } | ||
| 1497 | } | 1485 | } |
| 1498 | 1486 | ||
| 1499 | // Signals to an address (via Address Arbiter) | 1487 | // Signals to an address (via Address Arbiter) |