summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/address_arbiter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/address_arbiter.cpp')
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp52
1 files changed, 32 insertions, 20 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index de0a9064e..98d07fa5b 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -21,7 +21,7 @@
namespace Kernel {
namespace {
// Wake up num_to_wake (or all) threads in a vector.
-void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) {
+void WakeThreads(const std::vector<std::shared_ptr<Thread>>& waiting_threads, s32 num_to_wake) {
auto& system = Core::System::GetInstance();
// Only process up to 'target' threads, unless 'target' is <= 0, in which case process
// them all.
@@ -59,35 +59,41 @@ ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 v
}
ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) {
- const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
+ const std::vector<std::shared_ptr<Thread>> waiting_threads =
+ GetThreadsWaitingOnAddress(address);
WakeThreads(waiting_threads, num_to_wake);
return RESULT_SUCCESS;
}
ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value,
s32 num_to_wake) {
+ auto& memory = system.Memory();
+
// Ensure that we can write to the address.
- if (!Memory::IsValidVirtualAddress(address)) {
+ if (!memory.IsValidVirtualAddress(address)) {
return ERR_INVALID_ADDRESS_STATE;
}
- if (static_cast<s32>(Memory::Read32(address)) != value) {
+ if (static_cast<s32>(memory.Read32(address)) != value) {
return ERR_INVALID_STATE;
}
- Memory::Write32(address, static_cast<u32>(value + 1));
+ memory.Write32(address, static_cast<u32>(value + 1));
return SignalToAddressOnly(address, num_to_wake);
}
ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
s32 num_to_wake) {
+ auto& memory = system.Memory();
+
// Ensure that we can write to the address.
- if (!Memory::IsValidVirtualAddress(address)) {
+ if (!memory.IsValidVirtualAddress(address)) {
return ERR_INVALID_ADDRESS_STATE;
}
// Get threads waiting on the address.
- const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
+ const std::vector<std::shared_ptr<Thread>> waiting_threads =
+ GetThreadsWaitingOnAddress(address);
// Determine the modified value depending on the waiting count.
s32 updated_value;
@@ -107,11 +113,11 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a
}
}
- if (static_cast<s32>(Memory::Read32(address)) != value) {
+ if (static_cast<s32>(memory.Read32(address)) != value) {
return ERR_INVALID_STATE;
}
- Memory::Write32(address, static_cast<u32>(updated_value));
+ memory.Write32(address, static_cast<u32>(updated_value));
WakeThreads(waiting_threads, num_to_wake);
return RESULT_SUCCESS;
}
@@ -132,18 +138,20 @@ ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s
ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
bool should_decrement) {
+ auto& memory = system.Memory();
+
// Ensure that we can read the address.
- if (!Memory::IsValidVirtualAddress(address)) {
+ if (!memory.IsValidVirtualAddress(address)) {
return ERR_INVALID_ADDRESS_STATE;
}
- const s32 cur_value = static_cast<s32>(Memory::Read32(address));
+ const s32 cur_value = static_cast<s32>(memory.Read32(address));
if (cur_value >= value) {
return ERR_INVALID_STATE;
}
if (should_decrement) {
- Memory::Write32(address, static_cast<u32>(cur_value - 1));
+ memory.Write32(address, static_cast<u32>(cur_value - 1));
}
// Short-circuit without rescheduling, if timeout is zero.
@@ -155,15 +163,19 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
}
ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) {
+ auto& memory = system.Memory();
+
// Ensure that we can read the address.
- if (!Memory::IsValidVirtualAddress(address)) {
+ if (!memory.IsValidVirtualAddress(address)) {
return ERR_INVALID_ADDRESS_STATE;
}
+
// Only wait for the address if equal.
- if (static_cast<s32>(Memory::Read32(address)) != value) {
+ if (static_cast<s32>(memory.Read32(address)) != value) {
return ERR_INVALID_STATE;
}
- // Short-circuit without rescheduling, if timeout is zero.
+
+ // Short-circuit without rescheduling if timeout is zero.
if (timeout == 0) {
return RESULT_TIMEOUT;
}
@@ -172,21 +184,21 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
}
ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) {
- SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
+ Thread* current_thread = system.CurrentScheduler().GetCurrentThread();
current_thread->SetArbiterWaitAddress(address);
current_thread->SetStatus(ThreadStatus::WaitArb);
current_thread->InvalidateWakeupCallback();
-
current_thread->WakeAfterDelay(timeout);
system.PrepareReschedule(current_thread->GetProcessorID());
return RESULT_TIMEOUT;
}
-std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr address) const {
+std::vector<std::shared_ptr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(
+ VAddr address) const {
// Retrieve all threads that are waiting for this address.
- std::vector<SharedPtr<Thread>> threads;
+ std::vector<std::shared_ptr<Thread>> threads;
const auto& scheduler = system.GlobalScheduler();
const auto& thread_list = scheduler.GetThreadList();
@@ -198,7 +210,7 @@ std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr
// Sort them by priority, such that the highest priority ones come first.
std::sort(threads.begin(), threads.end(),
- [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
+ [](const std::shared_ptr<Thread>& lhs, const std::shared_ptr<Thread>& rhs) {
return lhs->GetPriority() < rhs->GetPriority();
});