|
|
|
@ -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<KSynchronizationObject*, Svc::ArgumentHandleCountMax> 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<u64>(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<KSynchronizationObject>(objs.data(), handles, |
|
|
|
num_handles), |
|
|
|
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>( |
|
|
|
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<Handle, Svc::ArgumentHandleCountMax> 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); |
|
|
|
|