mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	WaitProcessWideKeyAtomic: Handle case where condition variable was already created.
This commit is contained in:
		
							parent
							
								
									647364db8f
								
							
						
					
					
						commit
						0b6b147939
					
				@ -15,13 +15,12 @@ ConditionVariable::ConditionVariable() {}
 | 
				
			|||||||
ConditionVariable::~ConditionVariable() {}
 | 
					ConditionVariable::~ConditionVariable() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
 | 
					ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr,
 | 
				
			||||||
                                                                  VAddr mutex_addr,
 | 
					 | 
				
			||||||
                                                                  std::string name) {
 | 
					                                                                  std::string name) {
 | 
				
			||||||
    SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
 | 
					    SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    condition_variable->name = std::move(name);
 | 
					    condition_variable->name = std::move(name);
 | 
				
			||||||
    condition_variable->guest_addr = guest_addr;
 | 
					    condition_variable->guest_addr = guest_addr;
 | 
				
			||||||
    condition_variable->mutex_addr = mutex_addr;
 | 
					    condition_variable->mutex_addr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Condition variables are referenced by guest address, so track this in the kernel
 | 
					    // Condition variables are referenced by guest address, so track this in the kernel
 | 
				
			||||||
    g_object_address_table.Insert(guest_addr, condition_variable);
 | 
					    g_object_address_table.Insert(guest_addr, condition_variable);
 | 
				
			||||||
 | 
				
			|||||||
@ -19,12 +19,10 @@ public:
 | 
				
			|||||||
     * Creates a condition variable.
 | 
					     * Creates a condition variable.
 | 
				
			||||||
     * @param guest_addr Address of the object tracking the condition variable in guest memory. If
 | 
					     * @param guest_addr Address of the object tracking the condition variable in guest memory. If
 | 
				
			||||||
     * specified, this condition variable will update the guest object when its state changes.
 | 
					     * specified, this condition variable will update the guest object when its state changes.
 | 
				
			||||||
     * @param mutex_addr Optional address of a guest mutex associated with this condition variable,
 | 
					 | 
				
			||||||
     * used by the OS for implementing events.
 | 
					 | 
				
			||||||
     * @param name Optional name of condition variable.
 | 
					     * @param name Optional name of condition variable.
 | 
				
			||||||
     * @return The created condition variable.
 | 
					     * @return The created condition variable.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0,
 | 
					    static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr,
 | 
				
			||||||
                                                          std::string name = "Unknown");
 | 
					                                                          std::string name = "Unknown");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string GetTypeName() const override {
 | 
					    std::string GetTypeName() const override {
 | 
				
			||||||
 | 
				
			|||||||
@ -612,20 +612,29 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
 | 
				
			|||||||
        mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
 | 
					        mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASSERT(mutex->GetOwnerHandle() == thread_handle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SharedPtr<ConditionVariable> condition_variable =
 | 
					    SharedPtr<ConditionVariable> condition_variable =
 | 
				
			||||||
        g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
 | 
					        g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
 | 
				
			||||||
    if (!condition_variable) {
 | 
					    if (!condition_variable) {
 | 
				
			||||||
        // Create a new condition_variable for the specified address if one does not already exist
 | 
					        // Create a new condition_variable for the specified address if one does not already exist
 | 
				
			||||||
        condition_variable =
 | 
					        condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();
 | 
				
			||||||
            ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap();
 | 
					 | 
				
			||||||
        condition_variable->name =
 | 
					        condition_variable->name =
 | 
				
			||||||
            Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
 | 
					            Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ASSERT(condition_variable->GetAvailableCount() == 0);
 | 
					    if (condition_variable->mutex_addr) {
 | 
				
			||||||
 | 
					        // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify
 | 
				
			||||||
 | 
					        // everything is correct
 | 
				
			||||||
        ASSERT(condition_variable->mutex_addr == mutex_addr);
 | 
					        ASSERT(condition_variable->mutex_addr == mutex_addr);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex
 | 
				
			||||||
 | 
					        // associated with it
 | 
				
			||||||
 | 
					        condition_variable->mutex_addr = mutex_addr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (mutex->GetOwnerHandle()) {
 | 
				
			||||||
 | 
					        // Release the mutex if the current thread is holding it
 | 
				
			||||||
 | 
					        mutex->Release(thread.get());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
 | 
					    auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
 | 
				
			||||||
                                                 SharedPtr<Thread> thread,
 | 
					                                                 SharedPtr<Thread> thread,
 | 
				
			||||||
@ -667,8 +676,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
 | 
				
			|||||||
    CASCADE_CODE(
 | 
					    CASCADE_CODE(
 | 
				
			||||||
        WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
 | 
					        WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mutex->Release(thread.get());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					    return RESULT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user