From b94e57665369ab1c944c51586912f758ad4b86b1 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 24 Jun 2023 21:30:09 -0400 Subject: kernel: Synchronize --- src/core/hle/kernel/svc/svc_synchronization.cpp | 41 ++++++++++++------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'src/core/hle/kernel/svc/svc_synchronization.cpp') diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 53df5bcd8..f02d03f30 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp @@ -47,21 +47,35 @@ Result ResetSignal(Core::System& system, Handle handle) { R_THROW(ResultInvalidHandle); } -static Result WaitSynchronization(Core::System& system, int32_t* out_index, const Handle* handles, - int32_t num_handles, int64_t timeout_ns) { +/// Wait for the given handles to synchronize, timeout after the specified nanoseconds +Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_handles, + int32_t num_handles, int64_t timeout_ns) { + LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles, + num_handles, timeout_ns); + // Ensure number of handles is valid. R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); // Get the synchronization context. auto& kernel = system.Kernel(); auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); - std::array objs; + auto objs = GetCurrentThread(kernel).GetSynchronizationObjectBuffer(); + auto handles = GetCurrentThread(kernel).GetHandleBuffer(); // Copy user handles. if (num_handles > 0) { + // Ensure we can try to get the handles. + R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange( + user_handles, static_cast(sizeof(Handle) * num_handles)), + ResultInvalidPointer); + + // Get the handles. + GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(), + sizeof(Handle) * num_handles); + // Convert the handles to objects. - R_UNLESS(handle_table.GetMultipleObjects(objs.data(), handles, - num_handles), + R_UNLESS(handle_table.GetMultipleObjects( + objs.data(), handles.data(), num_handles), ResultInvalidHandle); } @@ -80,23 +94,6 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons R_RETURN(res); } -/// Wait for the given handles to synchronize, timeout after the specified nanoseconds -Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_handles, - int32_t num_handles, int64_t timeout_ns) { - LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles, - num_handles, timeout_ns); - - // Ensure number of handles is valid. - R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); - std::array handles; - if (num_handles > 0) { - GetCurrentMemory(system.Kernel()) - .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); - } - - R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns)); -} - /// Resumes a thread waiting on WaitSynchronization Result CancelSynchronization(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); -- cgit v1.2.3