diff options
| author | 2018-02-04 12:30:51 -0500 | |
|---|---|---|
| committer | 2018-02-04 12:30:51 -0500 | |
| commit | 0b6b147939c3abd1f98ecf639fb1ee51c5a445a1 (patch) | |
| tree | f1211ba8e29d7e3eae11fc64453e3e71ee4711c1 /src | |
| parent | svc: SharedMemory size should be 64-bits and cleanup. (diff) | |
| download | yuzu-0b6b147939c3abd1f98ecf639fb1ee51c5a445a1.tar.gz yuzu-0b6b147939c3abd1f98ecf639fb1ee51c5a445a1.tar.xz yuzu-0b6b147939c3abd1f98ecf639fb1ee51c5a445a1.zip | |
WaitProcessWideKeyAtomic: Handle case where condition variable was already created.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/condition_variable.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/condition_variable.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 23 |
3 files changed, 17 insertions, 13 deletions
diff --git a/src/core/hle/kernel/condition_variable.cpp b/src/core/hle/kernel/condition_variable.cpp index 561666384..a786d7f74 100644 --- a/src/core/hle/kernel/condition_variable.cpp +++ b/src/core/hle/kernel/condition_variable.cpp | |||
| @@ -15,13 +15,12 @@ ConditionVariable::ConditionVariable() {} | |||
| 15 | ConditionVariable::~ConditionVariable() {} | 15 | ConditionVariable::~ConditionVariable() {} |
| 16 | 16 | ||
| 17 | ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, | 17 | ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, |
| 18 | VAddr mutex_addr, | ||
| 19 | std::string name) { | 18 | std::string name) { |
| 20 | SharedPtr<ConditionVariable> condition_variable(new ConditionVariable); | 19 | SharedPtr<ConditionVariable> condition_variable(new ConditionVariable); |
| 21 | 20 | ||
| 22 | condition_variable->name = std::move(name); | 21 | condition_variable->name = std::move(name); |
| 23 | condition_variable->guest_addr = guest_addr; | 22 | condition_variable->guest_addr = guest_addr; |
| 24 | condition_variable->mutex_addr = mutex_addr; | 23 | condition_variable->mutex_addr = 0; |
| 25 | 24 | ||
| 26 | // Condition variables are referenced by guest address, so track this in the kernel | 25 | // Condition variables are referenced by guest address, so track this in the kernel |
| 27 | g_object_address_table.Insert(guest_addr, condition_variable); | 26 | g_object_address_table.Insert(guest_addr, condition_variable); |
diff --git a/src/core/hle/kernel/condition_variable.h b/src/core/hle/kernel/condition_variable.h index 0d54031cb..1c9f06769 100644 --- a/src/core/hle/kernel/condition_variable.h +++ b/src/core/hle/kernel/condition_variable.h | |||
| @@ -19,12 +19,10 @@ public: | |||
| 19 | * Creates a condition variable. | 19 | * Creates a condition variable. |
| 20 | * @param guest_addr Address of the object tracking the condition variable in guest memory. If | 20 | * @param guest_addr Address of the object tracking the condition variable in guest memory. If |
| 21 | * specified, this condition variable will update the guest object when its state changes. | 21 | * specified, this condition variable will update the guest object when its state changes. |
| 22 | * @param mutex_addr Optional address of a guest mutex associated with this condition variable, | ||
| 23 | * used by the OS for implementing events. | ||
| 24 | * @param name Optional name of condition variable. | 22 | * @param name Optional name of condition variable. |
| 25 | * @return The created condition variable. | 23 | * @return The created condition variable. |
| 26 | */ | 24 | */ |
| 27 | static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0, | 25 | static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, |
| 28 | std::string name = "Unknown"); | 26 | std::string name = "Unknown"); |
| 29 | 27 | ||
| 30 | std::string GetTypeName() const override { | 28 | std::string GetTypeName() const override { |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4e395ed31..0705b264d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -612,20 +612,29 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | |||
| 612 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); | 612 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); |
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | ASSERT(mutex->GetOwnerHandle() == thread_handle); | ||
| 616 | |||
| 617 | SharedPtr<ConditionVariable> condition_variable = | 615 | SharedPtr<ConditionVariable> condition_variable = |
| 618 | g_object_address_table.Get<ConditionVariable>(condition_variable_addr); | 616 | g_object_address_table.Get<ConditionVariable>(condition_variable_addr); |
| 619 | if (!condition_variable) { | 617 | if (!condition_variable) { |
| 620 | // Create a new condition_variable for the specified address if one does not already exist | 618 | // Create a new condition_variable for the specified address if one does not already exist |
| 621 | condition_variable = | 619 | condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); |
| 622 | ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap(); | ||
| 623 | condition_variable->name = | 620 | condition_variable->name = |
| 624 | Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); | 621 | Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); |
| 625 | } | 622 | } |
| 626 | 623 | ||
| 627 | ASSERT(condition_variable->GetAvailableCount() == 0); | 624 | if (condition_variable->mutex_addr) { |
| 628 | ASSERT(condition_variable->mutex_addr == mutex_addr); | 625 | // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify |
| 626 | // everything is correct | ||
| 627 | ASSERT(condition_variable->mutex_addr == mutex_addr); | ||
| 628 | } else { | ||
| 629 | // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex | ||
| 630 | // associated with it | ||
| 631 | condition_variable->mutex_addr = mutex_addr; | ||
| 632 | } | ||
| 633 | |||
| 634 | if (mutex->GetOwnerHandle()) { | ||
| 635 | // Release the mutex if the current thread is holding it | ||
| 636 | mutex->Release(thread.get()); | ||
| 637 | } | ||
| 629 | 638 | ||
| 630 | auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, | 639 | auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, |
| 631 | SharedPtr<Thread> thread, | 640 | SharedPtr<Thread> thread, |
| @@ -667,8 +676,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | |||
| 667 | CASCADE_CODE( | 676 | CASCADE_CODE( |
| 668 | WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); | 677 | WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); |
| 669 | 678 | ||
| 670 | mutex->Release(thread.get()); | ||
| 671 | |||
| 672 | return RESULT_SUCCESS; | 679 | return RESULT_SUCCESS; |
| 673 | } | 680 | } |
| 674 | 681 | ||