mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	SVC: Fixed WaitSynchronization with multiple handles when at least one of them is ready.
This commit is contained in:
		
							parent
							
								
									4236799832
								
							
						
					
					
						commit
						8d9250fa70
					
				@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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)>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user