diff options
author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2020-02-11 17:36:39 -0400 |
---|---|---|
committer | FernandoS27 <fsahmkow27@gmail.com> | 2020-02-11 18:47:31 -0400 |
commit | d23d504d776007c1244a85ac1b7bb67c407067b2 (patch) | |
tree | d6e992004bf752819084d648ca8b81fd1fc1db18 /src/core/hle/kernel/svc.cpp | |
parent | c5aefe42aaec7afa29d317709cacc8524f7add20 (diff) |
Kernel: Refactor synchronization to better match RE
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 67 |
1 files changed, 7 insertions, 60 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 39552a1760..86c660cdfd 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -32,6 +32,7 @@ #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_wrap.h" +#include "core/hle/kernel/synchronization.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/transfer_memory.h" #include "core/hle/kernel/writable_event.h" @@ -433,23 +434,6 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han return ERR_INVALID_HANDLE; } -/// Default thread wakeup callback for WaitSynchronization -static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, - std::shared_ptr<SynchronizationObject> object, - std::size_t index) { - ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return true; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); - return true; -}; - /// Wait for the given handles to synchronize, timeout after the specified nanoseconds static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address, u64 handle_count, s64 nano_seconds) { @@ -473,10 +457,10 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr } auto* const thread = system.CurrentScheduler().GetCurrentThread(); - + auto& kernel = system.Kernel(); using ObjectPtr = Thread::ThreadSynchronizationObjects::value_type; Thread::ThreadSynchronizationObjects objects(handle_count); - const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); for (u64 i = 0; i < handle_count; ++i) { const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); @@ -489,47 +473,10 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr objects[i] = object; } - - // Find the first object that is acquirable in the provided list of objects - auto itr = std::find_if(objects.begin(), objects.end(), [thread](const ObjectPtr& object) { - return !object->ShouldWait(thread); - }); - - if (itr != objects.end()) { - // We found a ready object, acquire it and set the result value - SynchronizationObject* object = itr->get(); - object->Acquire(thread); - *index = static_cast<s32>(std::distance(objects.begin(), itr)); - return RESULT_SUCCESS; - } - - // No objects were ready to be acquired, prepare to suspend the thread. - - // If a timeout value of 0 was provided, just return the Timeout error code instead of - // suspending the thread. - if (nano_seconds == 0) { - return RESULT_TIMEOUT; - } - - if (thread->IsSyncCancelled()) { - thread->SetSyncCancelled(false); - return ERR_SYNCHRONIZATION_CANCELED; - } - - for (auto& object : objects) { - object->AddWaitingThread(SharedFrom(thread)); - } - - thread->SetSynchronizationObjects(std::move(objects)); - thread->SetStatus(ThreadStatus::WaitSynch); - - // Create an event to wake the thread up after the specified nanosecond delay has passed - thread->WakeAfterDelay(nano_seconds); - thread->SetWakeupCallback(DefaultThreadWakeupCallback); - - system.PrepareReschedule(thread->GetProcessorID()); - - return RESULT_TIMEOUT; + auto& synchronization = kernel.Synchronization(); + auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); + *index = handle_result; + return result; } /// Resumes a thread waiting on WaitSynchronization |