From c5aefe42aaec7afa29d317709cacc8524f7add20 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 11 Feb 2020 10:46:25 -0400 Subject: Kernel: Change WaitObject to Synchronization object. In order to better reflect RE. --- src/core/hle/kernel/svc.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9cae5c73d..39552a176 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -435,7 +435,8 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han /// Default thread wakeup callback for WaitSynchronization static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object, std::size_t index) { + std::shared_ptr object, + std::size_t index) { ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); if (reason == ThreadWakeupReason::Timeout) { @@ -473,13 +474,13 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr auto* const thread = system.CurrentScheduler().GetCurrentThread(); - using ObjectPtr = Thread::ThreadWaitObjects::value_type; - Thread::ThreadWaitObjects objects(handle_count); + using ObjectPtr = Thread::ThreadSynchronizationObjects::value_type; + Thread::ThreadSynchronizationObjects objects(handle_count); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); for (u64 i = 0; i < handle_count; ++i) { const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); - const auto object = handle_table.Get(handle); + const auto object = handle_table.Get(handle); if (object == nullptr) { LOG_ERROR(Kernel_SVC, "Object is a nullptr"); @@ -496,7 +497,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr if (itr != objects.end()) { // We found a ready object, acquire it and set the result value - WaitObject* object = itr->get(); + SynchronizationObject* object = itr->get(); object->Acquire(thread); *index = static_cast(std::distance(objects.begin(), itr)); return RESULT_SUCCESS; @@ -519,7 +520,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr object->AddWaitingThread(SharedFrom(thread)); } - thread->SetWaitObjects(std::move(objects)); + thread->SetSynchronizationObjects(std::move(objects)); thread->SetStatus(ThreadStatus::WaitSynch); // Create an event to wake the thread up after the specified nanosecond delay has passed -- cgit v1.2.3 From d23d504d776007c1244a85ac1b7bb67c407067b2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 11 Feb 2020 17:36:39 -0400 Subject: Kernel: Refactor synchronization to better match RE --- src/core/hle/kernel/svc.cpp | 67 +++++---------------------------------------- 1 file changed, 7 insertions(+), 60 deletions(-) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 39552a176..86c660cdf 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, - std::shared_ptr 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(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(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 -- cgit v1.2.3 From 2bc949628dfa2efe9a18660b9d662e2a25cef9f9 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 13 Feb 2020 17:01:44 -0400 Subject: Core: Address Feedback --- src/core/hle/kernel/svc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 86c660cdf..fd91779a3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -474,7 +474,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr objects[i] = object; } auto& synchronization = kernel.Synchronization(); - auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); + const auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); *index = handle_result; return result; } -- cgit v1.2.3