SVC: Fixed WaitSynchronization with multiple handles when at least one of them is ready.
This commit is contained in:
parent
4236799832
commit
8d9250fa70
2 changed files with 29 additions and 3 deletions
|
@ -166,7 +166,8 @@ static ResultCode WaitSynchronization1(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
||||||
static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) {
|
static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count,
|
||||||
|
s64 nano_seconds) {
|
||||||
LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d",
|
LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d",
|
||||||
handles_address, handle_count, nano_seconds);
|
handles_address, handle_count, nano_seconds);
|
||||||
|
|
||||||
|
@ -177,6 +178,8 @@ static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s
|
||||||
if (handle_count < 0)
|
if (handle_count < 0)
|
||||||
return ERR_OUT_OF_RANGE;
|
return ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
auto thread = GetCurrentThread();
|
||||||
|
|
||||||
using ObjectPtr = SharedPtr<WaitObject>;
|
using ObjectPtr = SharedPtr<WaitObject>;
|
||||||
std::vector<ObjectPtr> objects(handle_count);
|
std::vector<ObjectPtr> objects(handle_count);
|
||||||
|
|
||||||
|
@ -188,6 +191,26 @@ static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s
|
||||||
objects[i] = object;
|
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
|
||||||
|
WaitObject* object = itr->get();
|
||||||
|
object->Acquire(thread);
|
||||||
|
*index = static_cast<s32>(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;
|
||||||
|
|
||||||
// Just implement for a single handle for now
|
// Just implement for a single handle for now
|
||||||
ASSERT(handle_count == 1);
|
ASSERT(handle_count == 1);
|
||||||
return WaitSynchronization1(objects[0], GetCurrentThread(), nano_seconds);
|
return WaitSynchronization1(objects[0], GetCurrentThread(), nano_seconds);
|
||||||
|
|
|
@ -80,9 +80,12 @@ void SvcWrap() {
|
||||||
FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw);
|
FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <ResultCode func(u64, u64, s64)>
|
template <ResultCode func(u32*, u64, u64, s64)>
|
||||||
void SvcWrap() {
|
void SvcWrap() {
|
||||||
FuncReturn(func(PARAM(1), PARAM(2), (s64)PARAM(3)).raw);
|
u32 param_1 = 0;
|
||||||
|
ResultCode retval = func(¶m_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3));
|
||||||
|
Core::CPU().SetReg(1, param_1);
|
||||||
|
FuncReturn(retval.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <ResultCode func(u64, u64, u32, s64)>
|
template <ResultCode func(u64, u64, u32, s64)>
|
||||||
|
|
Loading…
Reference in a new issue