summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar liamwhite2023-03-08 09:16:17 -0500
committerGravatar GitHub2023-03-08 09:16:17 -0500
commitb5d61f214d4d591a3d16901fe733ec54df9b1a76 (patch)
tree249897b461effe092c0b37170206ebee08f42abb
parentMerge pull request #9896 from Kelebek1/d24s8 (diff)
parentkernel: fix WaitSynchronization (diff)
downloadyuzu-b5d61f214d4d591a3d16901fe733ec54df9b1a76.tar.gz
yuzu-b5d61f214d4d591a3d16901fe733ec54df9b1a76.tar.xz
yuzu-b5d61f214d4d591a3d16901fe733ec54df9b1a76.zip
Merge pull request #9904 from liamwhite/ws
kernel: fix WaitSynchronization
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 1a8f7e191..9e7bf9530 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -48,19 +48,15 @@ Result ResetSignal(Core::System& system, Handle handle) {
48 return ResultInvalidHandle; 48 return ResultInvalidHandle;
49} 49}
50 50
51/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 51static Result WaitSynchronization(Core::System& system, int32_t* out_index, const Handle* handles,
52Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, 52 int32_t num_handles, int64_t timeout_ns) {
53 s64 nano_seconds) {
54 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}",
55 handles_address, num_handles, nano_seconds);
56
57 // Ensure number of handles is valid. 53 // Ensure number of handles is valid.
58 R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); 54 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
59 55
56 // Get the synchronization context.
60 auto& kernel = system.Kernel(); 57 auto& kernel = system.Kernel();
58 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
61 std::vector<KSynchronizationObject*> objs(num_handles); 59 std::vector<KSynchronizationObject*> objs(num_handles);
62 const auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
63 Handle* handles = system.Memory().GetPointer<Handle>(handles_address);
64 60
65 // Copy user handles. 61 // Copy user handles.
66 if (num_handles > 0) { 62 if (num_handles > 0) {
@@ -68,21 +64,38 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre
68 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, 64 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles,
69 num_handles), 65 num_handles),
70 ResultInvalidHandle); 66 ResultInvalidHandle);
71 for (const auto& obj : objs) {
72 kernel.RegisterInUseObject(obj);
73 }
74 } 67 }
75 68
76 // Ensure handles are closed when we're done. 69 // Ensure handles are closed when we're done.
77 SCOPE_EXIT({ 70 SCOPE_EXIT({
78 for (s32 i = 0; i < num_handles; ++i) { 71 for (auto i = 0; i < num_handles; ++i) {
79 kernel.UnregisterInUseObject(objs[i]);
80 objs[i]->Close(); 72 objs[i]->Close();
81 } 73 }
82 }); 74 });
83 75
84 return KSynchronizationObject::Wait(kernel, index, objs.data(), static_cast<s32>(objs.size()), 76 // Wait on the objects.
85 nano_seconds); 77 Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(),
78 static_cast<s32>(objs.size()), timeout_ns);
79
80 R_SUCCEED_IF(res == ResultSessionClosed);
81 R_RETURN(res);
82}
83
84/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
85Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles,
86 int32_t num_handles, int64_t timeout_ns) {
87 LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles,
88 num_handles, timeout_ns);
89
90 // Ensure number of handles is valid.
91 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
92
93 std::vector<Handle> handles(num_handles);
94 if (num_handles > 0) {
95 system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
96 }
97
98 R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns));
86} 99}
87 100
88/// Resumes a thread waiting on WaitSynchronization 101/// Resumes a thread waiting on WaitSynchronization