From dc70a87af1576e29dd6fda1d0313aca260982498 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 21 Jun 2018 20:25:57 -0600 Subject: Kernel/Arbiters: HLE is atomic, adjust code to reflect that. --- src/core/hle/kernel/address_arbiter.cpp | 49 +++++++++------------------------ src/core/hle/kernel/thread.h | 1 - 2 files changed, 13 insertions(+), 37 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 63cdcb559..01c5bf61b 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -20,14 +20,14 @@ namespace Kernel { ResultCode WaitForAddress(VAddr address, s64 timeout) { SharedPtr current_thread = GetCurrentThread(); current_thread->arb_wait_address = address; - current_thread->arb_wait_result = RESULT_TIMEOUT; current_thread->status = THREADSTATUS_WAIT_ARB; current_thread->wakeup_callback = nullptr; current_thread->WakeAfterDelay(timeout); Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); - return current_thread->arb_wait_result; + // This should never actually execute. + return RESULT_SUCCESS; } // Gets the threads waiting on an address. @@ -67,7 +67,7 @@ namespace Kernel { // 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]->SetWaitSynchronizationResult(RESULT_SUCCESS); waiting_threads[i]->arb_wait_address = 0; waiting_threads[i]->ResumeFromWait(); } @@ -91,17 +91,9 @@ namespace Kernel { 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) { + if ((s32)Memory::Read32(address) == value) { + Memory::Write32(address, (u32)(value + 1)); + } else { return ERR_INVALID_STATE; } @@ -128,18 +120,10 @@ namespace Kernel { } 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) { + if ((s32)Memory::Read32(address) == value) { + Memory::Write32(address, (u32)(updated_value)); + } else { return ERR_INVALID_STATE; } @@ -154,17 +138,10 @@ namespace Kernel { return ERR_INVALID_ADDRESS_STATE; } - s32 cur_value; - // Get value, decrementing if less than - { - // Decrement if less than 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) { + 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. diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 7a28f3c1c..3851d1085 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -233,7 +233,6 @@ public: // If waiting for an AddressArbiter, this is the address being waited on. VAddr arb_wait_address{0}; - ResultCode arb_wait_result{RESULT_SUCCESS}; ///< Result returned when done waiting on AddressArbiter. std::string name; -- cgit v1.2.3