summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-02-04 12:30:51 -0500
committerGravatar bunnei2018-02-04 12:30:51 -0500
commit0b6b147939c3abd1f98ecf639fb1ee51c5a445a1 (patch)
treef1211ba8e29d7e3eae11fc64453e3e71ee4711c1 /src
parentsvc: SharedMemory size should be 64-bits and cleanup. (diff)
downloadyuzu-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.cpp3
-rw-r--r--src/core/hle/kernel/condition_variable.h4
-rw-r--r--src/core/hle/kernel/svc.cpp23
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() {}
15ConditionVariable::~ConditionVariable() {} 15ConditionVariable::~ConditionVariable() {}
16 16
17ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, 17ResultVal<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