diff options
| author | 2018-01-09 11:53:50 -0500 | |
|---|---|---|
| committer | 2018-01-09 11:53:50 -0500 | |
| commit | 8d9250fa70af00b5f40a58b0729588616bef94fa (patch) | |
| tree | 956a699769296b21a52f0fe0209ab0b969d0ec2c /src/core/hle/kernel/svc.cpp | |
| parent | kernel: Rename Semaphore to ConditionVariable. (diff) | |
| download | yuzu-8d9250fa70af00b5f40a58b0729588616bef94fa.tar.gz yuzu-8d9250fa70af00b5f40a58b0729588616bef94fa.tar.xz yuzu-8d9250fa70af00b5f40a58b0729588616bef94fa.zip | |
SVC: Fixed WaitSynchronization with multiple handles when at least one of them is ready.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b94503536..c3280bfa3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -166,7 +166,8 @@ static ResultCode WaitSynchronization1( | |||
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 168 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 169 | static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) { | 169 | static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, |
| 170 | s64 nano_seconds) { | ||
| 170 | LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d", | 171 | LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d", |
| 171 | handles_address, handle_count, nano_seconds); | 172 | handles_address, handle_count, nano_seconds); |
| 172 | 173 | ||
| @@ -177,6 +178,8 @@ static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s | |||
| 177 | if (handle_count < 0) | 178 | if (handle_count < 0) |
| 178 | return ERR_OUT_OF_RANGE; | 179 | return ERR_OUT_OF_RANGE; |
| 179 | 180 | ||
| 181 | auto thread = GetCurrentThread(); | ||
| 182 | |||
| 180 | using ObjectPtr = SharedPtr<WaitObject>; | 183 | using ObjectPtr = SharedPtr<WaitObject>; |
| 181 | std::vector<ObjectPtr> objects(handle_count); | 184 | std::vector<ObjectPtr> objects(handle_count); |
| 182 | 185 | ||
| @@ -188,6 +191,26 @@ static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s | |||
| 188 | objects[i] = object; | 191 | objects[i] = object; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 194 | // Find the first object that is acquirable in the provided list of objects | ||
| 195 | auto itr = std::find_if(objects.begin(), objects.end(), [thread](const ObjectPtr& object) { | ||
| 196 | return !object->ShouldWait(thread); | ||
| 197 | }); | ||
| 198 | |||
| 199 | if (itr != objects.end()) { | ||
| 200 | // We found a ready object, acquire it and set the result value | ||
| 201 | WaitObject* object = itr->get(); | ||
| 202 | object->Acquire(thread); | ||
| 203 | *index = static_cast<s32>(std::distance(objects.begin(), itr)); | ||
| 204 | return RESULT_SUCCESS; | ||
| 205 | } | ||
| 206 | |||
| 207 | // No objects were ready to be acquired, prepare to suspend the thread. | ||
| 208 | |||
| 209 | // If a timeout value of 0 was provided, just return the Timeout error code instead of | ||
| 210 | // suspending the thread. | ||
| 211 | if (nano_seconds == 0) | ||
| 212 | return RESULT_TIMEOUT; | ||
| 213 | |||
| 191 | // Just implement for a single handle for now | 214 | // Just implement for a single handle for now |
| 192 | ASSERT(handle_count == 1); | 215 | ASSERT(handle_count == 1); |
| 193 | return WaitSynchronization1(objects[0], GetCurrentThread(), nano_seconds); | 216 | return WaitSynchronization1(objects[0], GetCurrentThread(), nano_seconds); |