From 7e191dccc184ae85ce5ade2bca913ab331002481 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 21 Jun 2018 00:49:43 -0600 Subject: Kernel/Arbiters: Add stubs for 4.x SignalToAddress/WaitForAddres SVCs. --- src/core/hle/kernel/address_arbiter.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/core/hle/kernel/address_arbiter.h (limited to 'src/core/hle/kernel/address_arbiter.h') diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h new file mode 100644 index 000000000..3eba103dd --- /dev/null +++ b/src/core/hle/kernel/address_arbiter.h @@ -0,0 +1,32 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" + +namespace Kernel { + + namespace AddressArbiter { + enum class ArbitrationType { + WaitIfLessThan = 0, + DecrementAndWaitIfLessThan = 1, + WaitIfEqual = 2, + }; + + enum class SignalType { + Signal = 0, + IncrementAndSignalIfEqual = 1, + ModifyByWaitingCountAndSignalIfEqual = 2, + }; + + ResultCode SignalToAddress(VAddr address, s32 value, s32 num_to_wake); + ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); + ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); + + ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement); + ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); + } // namespace AddressArbiter + +} // namespace Kernel \ No newline at end of file -- cgit v1.2.3 From 4f81bc4e1bd12e4df7410c6790ba818d8dbba9c0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 21 Jun 2018 04:07:03 -0600 Subject: Kernel/Arbiters: Mostly implement SignalToAddress --- src/core/hle/kernel/address_arbiter.cpp | 110 ++++++++++++++++++++++++++++++-- src/core/hle/kernel/address_arbiter.h | 2 +- src/core/hle/kernel/svc.cpp | 2 +- src/core/hle/kernel/thread.h | 6 +- src/yuzu/debugger/wait_tree.cpp | 2 +- 5 files changed, 111 insertions(+), 11 deletions(-) (limited to 'src/core/hle/kernel/address_arbiter.h') diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 367c4520d..4556199ab 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -27,24 +27,122 @@ namespace Kernel { current_thread->WakeAfterDelay(timeout); Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); - return RESULT_SUCCESS; + return current_thread->arb_wait_result; + } + + // Gets the threads waiting on an address. + void GetThreadsWaitingOnAddress(std::vector> &waiting_threads, VAddr address) { + auto RetrieveWaitingThreads = + [](size_t core_index, std::vector>& waiting_threads, VAddr arb_addr) { + const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); + auto& thread_list = scheduler->GetThreadList(); + + for (auto& thread : thread_list) { + if (thread->arb_wait_address == arb_addr) + waiting_threads.push_back(thread); + } + }; + + // Retrieve a list of all threads that are waiting for this address. + RetrieveWaitingThreads(0, waiting_threads, address); + RetrieveWaitingThreads(1, waiting_threads, address); + RetrieveWaitingThreads(2, waiting_threads, address); + RetrieveWaitingThreads(3, waiting_threads, address); + // Sort them by priority, such that the highest priority ones come first. + std::sort(waiting_threads.begin(), waiting_threads.end(), + [](const SharedPtr& lhs, const SharedPtr& rhs) { + return lhs->current_priority < rhs->current_priority; + }); + } + + // Wake up num_to_wake (or all) threads in a vector. + void WakeThreads(std::vector> &waiting_threads, s32 num_to_wake) { + // Only process up to 'target' threads, unless 'target' is <= 0, in which case process + // them all. + size_t last = waiting_threads.size(); + if (num_to_wake > 0) + last = num_to_wake; + + // Signal the waiting threads. + // TODO: Rescheduling should not occur while waking threads. How can it be prevented? + for (size_t i = 0; i < last; i++) { + ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); + waiting_threads[i]->arb_wait_result = RESULT_SUCCESS; + waiting_threads[i]->ResumeFromWait(); + } + } // Signals an address being waited on. - ResultCode SignalToAddress(VAddr address, s32 value, s32 num_to_wake) { - // TODO + ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { + // Get threads waiting on the address. + std::vector> waiting_threads; + GetThreadsWaitingOnAddress(waiting_threads, address); + + WakeThreads(waiting_threads, num_to_wake); return RESULT_SUCCESS; } // Signals an address being waited on and increments its value if equal to the value argument. ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { - // TODO - return RESULT_SUCCESS; + // Ensure that we can write to the address. + if (!Memory::IsValidVirtualAddress(address)) { + return ERR_INVALID_ADDRESS_STATE; + } + + s32 cur_value; + // Get value, incrementing if equal. + { + // Increment if Equal must be an atomic operation. + std::lock_guard lock(HLE::g_hle_lock); + cur_value = (s32)Memory::Read32(address); + if (cur_value == value) { + Memory::Write32(address, (u32)(cur_value + 1)); + } + } + if (cur_value != value) { + return ERR_INVALID_STATE; + } + + return SignalToAddress(address, num_to_wake); } // Signals an address being waited on and modifies its value based on waiting thread count if equal to the value argument. ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { - // TODO + // Ensure that we can write to the address. + if (!Memory::IsValidVirtualAddress(address)) { + return ERR_INVALID_ADDRESS_STATE; + } + + // Get threads waiting on the address. + std::vector> waiting_threads; + GetThreadsWaitingOnAddress(waiting_threads, address); + + // Determine the modified value depending on the waiting count. + s32 updated_value; + if (waiting_threads.size() == 0) { + updated_value = value - 1; + } else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) { + updated_value = value + 1; + } else { + updated_value = value; + } + s32 cur_value; + // Perform an atomic update if equal. + { + std::lock_guard lock(HLE::g_hle_lock); + cur_value = (s32)Memory::Read32(address); + if (cur_value == value) { + Memory::Write32(address, (u32)(updated_value)); + } + } + + // Only continue if equal. + if (cur_value != value) { + return ERR_INVALID_STATE; + } + + WakeThreads(waiting_threads, num_to_wake); return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 3eba103dd..32d4a77a9 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -21,7 +21,7 @@ namespace Kernel { ModifyByWaitingCountAndSignalIfEqual = 2, }; - ResultCode SignalToAddress(VAddr address, s32 value, s32 num_to_wake); + ResultCode SignalToAddress(VAddr address, s32 num_to_wake); ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4b4831c08..24dd50938 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -726,7 +726,7 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to switch ((AddressArbiter::SignalType)type) { case AddressArbiter::SignalType::Signal: - return AddressArbiter::SignalToAddress(address, value, num_to_wake); + return AddressArbiter::SignalToAddress(address, num_to_wake); case AddressArbiter::SignalType::IncrementAndSignalIfEqual: return AddressArbiter::IncrementAndSignalToAddressIfEqual(address, value, num_to_wake); case AddressArbiter::SignalType::ModifyByWaitingCountAndSignalIfEqual: diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 79e5d6e5c..0a76bd222 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -230,8 +230,10 @@ public: VAddr condvar_wait_address; VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address Handle wait_handle; ///< The handle used to wait for the mutex. - VAddr arb_wait_address; ///< If waiting for an AddressArbiter, this is the address - ResultCode arb_wait_result; ///< If waiting for an AddressArbiter, this is the result that will be returned. + + // If waiting for an AddressArbiter, this is the address being waited on. + VAddr arb_wait_address; + ResultCode arb_wait_result{RESULT_SUCCESS}; ///< Result returned when done waiting on AddressArbiter. std::string name; diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 800e431bd..7101b381e 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -213,7 +213,7 @@ QString WaitTreeThread::GetText() const { case THREADSTATUS_WAIT_MUTEX: status = tr("waiting for mutex"); break; - case THREADSTATUS_WAIT_MUTEX: + case THREADSTATUS_WAIT_ARB: status = tr("waiting for address arbiter"); break; case THREADSTATUS_DORMANT: -- cgit v1.2.3 From 08d454e30ddf5031190790c977bfda9422a24118 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 21 Jun 2018 21:05:34 -0600 Subject: Run clang-format on PR. --- src/core/hle/kernel/address_arbiter.cpp | 313 ++++++++++++++++---------------- src/core/hle/kernel/address_arbiter.h | 44 ++--- src/core/hle/kernel/thread.h | 4 +- 3 files changed, 181 insertions(+), 180 deletions(-) (limited to 'src/core/hle/kernel/address_arbiter.h') diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 01c5bf61b..972911e42 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -14,160 +14,161 @@ #include "core/memory.h" namespace Kernel { - namespace AddressArbiter { - - // Performs actual address waiting logic. - ResultCode WaitForAddress(VAddr address, s64 timeout) { - SharedPtr current_thread = GetCurrentThread(); - current_thread->arb_wait_address = address; - current_thread->status = THREADSTATUS_WAIT_ARB; - current_thread->wakeup_callback = nullptr; - - current_thread->WakeAfterDelay(timeout); - - Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); - // This should never actually execute. - return RESULT_SUCCESS; - } - - // Gets the threads waiting on an address. - void GetThreadsWaitingOnAddress(std::vector> &waiting_threads, VAddr address) { - auto RetrieveWaitingThreads = - [](size_t core_index, std::vector>& waiting_threads, VAddr arb_addr) { - const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); - auto& thread_list = scheduler->GetThreadList(); - - for (auto& thread : thread_list) { - if (thread->arb_wait_address == arb_addr) - waiting_threads.push_back(thread); - } - }; - - // Retrieve a list of all threads that are waiting for this address. - RetrieveWaitingThreads(0, waiting_threads, address); - RetrieveWaitingThreads(1, waiting_threads, address); - RetrieveWaitingThreads(2, waiting_threads, address); - RetrieveWaitingThreads(3, waiting_threads, address); - // Sort them by priority, such that the highest priority ones come first. - std::sort(waiting_threads.begin(), waiting_threads.end(), - [](const SharedPtr& lhs, const SharedPtr& rhs) { - return lhs->current_priority < rhs->current_priority; - }); - } - - // Wake up num_to_wake (or all) threads in a vector. - void WakeThreads(std::vector> &waiting_threads, s32 num_to_wake) { - // Only process up to 'target' threads, unless 'target' is <= 0, in which case process - // them all. - size_t last = waiting_threads.size(); - if (num_to_wake > 0) - last = num_to_wake; - - // Signal the waiting threads. - // TODO: Rescheduling should not occur while waking threads. How can it be prevented? - for (size_t i = 0; i < last; i++) { - ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); - waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); - waiting_threads[i]->arb_wait_address = 0; - waiting_threads[i]->ResumeFromWait(); +namespace AddressArbiter { + +// Performs actual address waiting logic. +ResultCode WaitForAddress(VAddr address, s64 timeout) { + SharedPtr current_thread = GetCurrentThread(); + current_thread->arb_wait_address = address; + current_thread->status = THREADSTATUS_WAIT_ARB; + current_thread->wakeup_callback = nullptr; + + current_thread->WakeAfterDelay(timeout); + + Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); + // This should never actually execute. + return RESULT_SUCCESS; +} + +// Gets the threads waiting on an address. +void GetThreadsWaitingOnAddress(std::vector>& waiting_threads, VAddr address) { + auto RetrieveWaitingThreads = + [](size_t core_index, std::vector>& waiting_threads, VAddr arb_addr) { + const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); + auto& thread_list = scheduler->GetThreadList(); + + for (auto& thread : thread_list) { + if (thread->arb_wait_address == arb_addr) + waiting_threads.push_back(thread); } - - } - - // Signals an address being waited on. - ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { - // Get threads waiting on the address. - std::vector> waiting_threads; - GetThreadsWaitingOnAddress(waiting_threads, address); - - WakeThreads(waiting_threads, num_to_wake); - return RESULT_SUCCESS; - } - - // Signals an address being waited on and increments its value if equal to the value argument. - ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { - // Ensure that we can write to the address. - if (!Memory::IsValidVirtualAddress(address)) { - return ERR_INVALID_ADDRESS_STATE; - } - - if ((s32)Memory::Read32(address) == value) { - Memory::Write32(address, (u32)(value + 1)); - } else { - return ERR_INVALID_STATE; - } - - return SignalToAddress(address, num_to_wake); - } - - // Signals an address being waited on and modifies its value based on waiting thread count if equal to the value argument. - ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { - // Ensure that we can write to the address. - if (!Memory::IsValidVirtualAddress(address)) { - return ERR_INVALID_ADDRESS_STATE; - } - - // Get threads waiting on the address. - std::vector> waiting_threads; - GetThreadsWaitingOnAddress(waiting_threads, address); - - // Determine the modified value depending on the waiting count. - s32 updated_value; - if (waiting_threads.size() == 0) { - updated_value = value - 1; - } else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) { - updated_value = value + 1; - } else { - updated_value = value; - } - - if ((s32)Memory::Read32(address) == value) { - Memory::Write32(address, (u32)(updated_value)); - } else { - return ERR_INVALID_STATE; - } - - WakeThreads(waiting_threads, num_to_wake); - return RESULT_SUCCESS; - } - - // Waits on an address if the value passed is less than the argument value, optionally decrementing. - ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement) { - // Ensure that we can read the address. - if (!Memory::IsValidVirtualAddress(address)) { - return ERR_INVALID_ADDRESS_STATE; - } - - s32 cur_value = (s32)Memory::Read32(address); - if (cur_value < value) { - Memory::Write32(address, (u32)(cur_value - 1)); - } else { - return ERR_INVALID_STATE; - } - // Short-circuit without rescheduling, if timeout is zero. - if (timeout == 0) { - return RESULT_TIMEOUT; - } - - return WaitForAddress(address, timeout); - } - - // Waits on an address if the value passed is equal to the argument value. - ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { - // Ensure that we can read the address. - if (!Memory::IsValidVirtualAddress(address)) { - return ERR_INVALID_ADDRESS_STATE; - } - // Only wait for the address if equal. - if ((s32)Memory::Read32(address) != value) { - return ERR_INVALID_STATE; - } - // Short-circuit without rescheduling, if timeout is zero. - if (timeout == 0) { - return RESULT_TIMEOUT; - } - - return WaitForAddress(address, timeout); - } - } // namespace AddressArbiter -} // namespace Kernel \ No newline at end of file + }; + + // Retrieve a list of all threads that are waiting for this address. + RetrieveWaitingThreads(0, waiting_threads, address); + RetrieveWaitingThreads(1, waiting_threads, address); + RetrieveWaitingThreads(2, waiting_threads, address); + RetrieveWaitingThreads(3, waiting_threads, address); + // Sort them by priority, such that the highest priority ones come first. + std::sort(waiting_threads.begin(), waiting_threads.end(), + [](const SharedPtr& lhs, const SharedPtr& rhs) { + return lhs->current_priority < rhs->current_priority; + }); +} + +// Wake up num_to_wake (or all) threads in a vector. +void WakeThreads(std::vector>& waiting_threads, s32 num_to_wake) { + // Only process up to 'target' threads, unless 'target' is <= 0, in which case process + // them all. + size_t last = waiting_threads.size(); + if (num_to_wake > 0) + last = num_to_wake; + + // Signal the waiting threads. + // TODO: Rescheduling should not occur while waking threads. How can it be prevented? + for (size_t i = 0; i < last; i++) { + ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); + waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); + waiting_threads[i]->arb_wait_address = 0; + waiting_threads[i]->ResumeFromWait(); + } +} + +// Signals an address being waited on. +ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { + // Get threads waiting on the address. + std::vector> waiting_threads; + GetThreadsWaitingOnAddress(waiting_threads, address); + + WakeThreads(waiting_threads, num_to_wake); + return RESULT_SUCCESS; +} + +// Signals an address being waited on and increments its value if equal to the value argument. +ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { + // Ensure that we can write to the address. + if (!Memory::IsValidVirtualAddress(address)) { + return ERR_INVALID_ADDRESS_STATE; + } + + if ((s32)Memory::Read32(address) == value) { + Memory::Write32(address, (u32)(value + 1)); + } else { + return ERR_INVALID_STATE; + } + + return SignalToAddress(address, num_to_wake); +} + +// Signals an address being waited on and modifies its value based on waiting thread count if equal +// to the value argument. +ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, + s32 num_to_wake) { + // Ensure that we can write to the address. + if (!Memory::IsValidVirtualAddress(address)) { + return ERR_INVALID_ADDRESS_STATE; + } + + // Get threads waiting on the address. + std::vector> waiting_threads; + GetThreadsWaitingOnAddress(waiting_threads, address); + + // Determine the modified value depending on the waiting count. + s32 updated_value; + if (waiting_threads.size() == 0) { + updated_value = value - 1; + } else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) { + updated_value = value + 1; + } else { + updated_value = value; + } + + if ((s32)Memory::Read32(address) == value) { + Memory::Write32(address, (u32)(updated_value)); + } else { + return ERR_INVALID_STATE; + } + + WakeThreads(waiting_threads, num_to_wake); + return RESULT_SUCCESS; +} + +// Waits on an address if the value passed is less than the argument value, optionally decrementing. +ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement) { + // Ensure that we can read the address. + if (!Memory::IsValidVirtualAddress(address)) { + return ERR_INVALID_ADDRESS_STATE; + } + + s32 cur_value = (s32)Memory::Read32(address); + if (cur_value < value) { + Memory::Write32(address, (u32)(cur_value - 1)); + } else { + return ERR_INVALID_STATE; + } + // Short-circuit without rescheduling, if timeout is zero. + if (timeout == 0) { + return RESULT_TIMEOUT; + } + + return WaitForAddress(address, timeout); +} + +// Waits on an address if the value passed is equal to the argument value. +ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { + // Ensure that we can read the address. + if (!Memory::IsValidVirtualAddress(address)) { + return ERR_INVALID_ADDRESS_STATE; + } + // Only wait for the address if equal. + if ((s32)Memory::Read32(address) != value) { + return ERR_INVALID_STATE; + } + // Short-circuit without rescheduling, if timeout is zero. + if (timeout == 0) { + return RESULT_TIMEOUT; + } + + return WaitForAddress(address, timeout); +} +} // namespace AddressArbiter +} // namespace Kernel diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 32d4a77a9..f20f3dbc0 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -8,25 +8,25 @@ namespace Kernel { - namespace AddressArbiter { - enum class ArbitrationType { - WaitIfLessThan = 0, - DecrementAndWaitIfLessThan = 1, - WaitIfEqual = 2, - }; - - enum class SignalType { - Signal = 0, - IncrementAndSignalIfEqual = 1, - ModifyByWaitingCountAndSignalIfEqual = 2, - }; - - ResultCode SignalToAddress(VAddr address, s32 num_to_wake); - ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); - ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); - - ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement); - ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); - } // namespace AddressArbiter - -} // namespace Kernel \ No newline at end of file +namespace AddressArbiter { +enum class ArbitrationType { + WaitIfLessThan = 0, + DecrementAndWaitIfLessThan = 1, + WaitIfEqual = 2, +}; + +enum class SignalType { + Signal = 0, + IncrementAndSignalIfEqual = 1, + ModifyByWaitingCountAndSignalIfEqual = 2, +}; + +ResultCode SignalToAddress(VAddr address, s32 num_to_wake); +ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); +ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); + +ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement); +ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); +} // namespace AddressArbiter + +} // namespace Kernel diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 3851d1085..f1e759802 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -228,8 +228,8 @@ public: // If waiting on a ConditionVariable, this is the ConditionVariable address VAddr condvar_wait_address; - VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address - Handle wait_handle; ///< The handle used to wait for the mutex. + VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address + Handle wait_handle; ///< The handle used to wait for the mutex. // If waiting for an AddressArbiter, this is the address being waited on. VAddr arb_wait_address{0}; -- cgit v1.2.3