diff options
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 7 | 
2 files changed, 29 insertions, 3 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(  }  /// 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",                handles_address, handle_count, nano_seconds); @@ -177,6 +178,8 @@ static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s      if (handle_count < 0)          return ERR_OUT_OF_RANGE; +    auto thread = GetCurrentThread(); +      using ObjectPtr = SharedPtr<WaitObject>;      std::vector<ObjectPtr> objects(handle_count); @@ -188,6 +191,26 @@ static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s          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      ASSERT(handle_count == 1);      return WaitSynchronization1(objects[0], GetCurrentThread(), nano_seconds); diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index bffa2f7f8..16c834cf3 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -80,9 +80,12 @@ void SvcWrap() {      FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw);  } -template <ResultCode func(u64, u64, s64)> +template <ResultCode func(u32*, u64, u64, s64)>  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)>  | 
