summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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/shared_memory.cpp2
-rw-r--r--src/core/hle/kernel/shared_memory.h4
-rw-r--r--src/core/hle/kernel/svc.cpp43
5 files changed, 32 insertions, 24 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/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index f8aa429dc..835fc710b 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -14,7 +14,7 @@ namespace Kernel {
14SharedMemory::SharedMemory() {} 14SharedMemory::SharedMemory() {}
15SharedMemory::~SharedMemory() {} 15SharedMemory::~SharedMemory() {}
16 16
17SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, 17SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u64 size,
18 MemoryPermission permissions, 18 MemoryPermission permissions,
19 MemoryPermission other_permissions, VAddr address, 19 MemoryPermission other_permissions, VAddr address,
20 MemoryRegion region, std::string name) { 20 MemoryRegion region, std::string name) {
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index e948819c0..86f818e90 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -39,7 +39,7 @@ public:
39 * linear heap. 39 * linear heap.
40 * @param name Optional object name, used for debugging purposes. 40 * @param name Optional object name, used for debugging purposes.
41 */ 41 */
42 static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size, 42 static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u64 size,
43 MemoryPermission permissions, 43 MemoryPermission permissions,
44 MemoryPermission other_permissions, VAddr address = 0, 44 MemoryPermission other_permissions, VAddr address = 0,
45 MemoryRegion region = MemoryRegion::BASE, 45 MemoryRegion region = MemoryRegion::BASE,
@@ -116,7 +116,7 @@ public:
116 /// Offset into the backing block for this shared memory. 116 /// Offset into the backing block for this shared memory.
117 size_t backing_block_offset; 117 size_t backing_block_offset;
118 /// Size of the memory block. Page-aligned. 118 /// Size of the memory block. Page-aligned.
119 u32 size; 119 u64 size;
120 /// Permission restrictions applied to the process which created the block. 120 /// Permission restrictions applied to the process which created the block.
121 MemoryPermission permissions; 121 MemoryPermission permissions;
122 /// Permission restrictions applied to other processes mapping the block. 122 /// Permission restrictions applied to other processes mapping the block.
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4c0276cf0..4d20ef134 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -263,6 +263,7 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
263 SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle); 263 SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle);
264 264
265 ASSERT(requesting_thread); 265 ASSERT(requesting_thread);
266 ASSERT(requesting_thread == GetCurrentThread());
266 267
267 SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); 268 SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
268 if (!mutex) { 269 if (!mutex) {
@@ -331,6 +332,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
331 case GetInfoType::TotalHeapUsage: 332 case GetInfoType::TotalHeapUsage:
332 *result = vm_manager.GetTotalHeapUsage(); 333 *result = vm_manager.GetTotalHeapUsage();
333 break; 334 break;
335 case GetInfoType::IsCurrentProcessBeingDebugged:
336 *result = 0;
337 break;
334 case GetInfoType::RandomEntropy: 338 case GetInfoType::RandomEntropy:
335 *result = 0; 339 *result = 0;
336 break; 340 break;
@@ -415,8 +419,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
415 "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X", 419 "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",
416 shared_memory_handle, addr, size, permissions); 420 shared_memory_handle, addr, size, permissions);
417 421
418 SharedPtr<SharedMemory> shared_memory = 422 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
419 Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle);
420 if (!shared_memory) { 423 if (!shared_memory) {
421 return ERR_INVALID_HANDLE; 424 return ERR_INVALID_HANDLE;
422 } 425 }
@@ -431,7 +434,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
431 case MemoryPermission::WriteExecute: 434 case MemoryPermission::WriteExecute:
432 case MemoryPermission::ReadWriteExecute: 435 case MemoryPermission::ReadWriteExecute:
433 case MemoryPermission::DontCare: 436 case MemoryPermission::DontCare:
434 return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type, 437 return shared_memory->Map(g_current_process.get(), addr, permissions_type,
435 MemoryPermission::DontCare); 438 MemoryPermission::DontCare);
436 default: 439 default:
437 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); 440 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
@@ -612,20 +615,29 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
612 mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); 615 mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
613 } 616 }
614 617
615 ASSERT(mutex->GetOwnerHandle() == thread_handle);
616
617 SharedPtr<ConditionVariable> condition_variable = 618 SharedPtr<ConditionVariable> condition_variable =
618 g_object_address_table.Get<ConditionVariable>(condition_variable_addr); 619 g_object_address_table.Get<ConditionVariable>(condition_variable_addr);
619 if (!condition_variable) { 620 if (!condition_variable) {
620 // Create a new condition_variable for the specified address if one does not already exist 621 // Create a new condition_variable for the specified address if one does not already exist
621 condition_variable = 622 condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();
622 ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap();
623 condition_variable->name = 623 condition_variable->name =
624 Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); 624 Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);
625 } 625 }
626 626
627 ASSERT(condition_variable->GetAvailableCount() == 0); 627 if (condition_variable->mutex_addr) {
628 ASSERT(condition_variable->mutex_addr == mutex_addr); 628 // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify
629 // everything is correct
630 ASSERT(condition_variable->mutex_addr == mutex_addr);
631 } else {
632 // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex
633 // associated with it
634 condition_variable->mutex_addr = mutex_addr;
635 }
636
637 if (mutex->GetOwnerHandle()) {
638 // Release the mutex if the current thread is holding it
639 mutex->Release(thread.get());
640 }
629 641
630 auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, 642 auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,
631 SharedPtr<Thread> thread, 643 SharedPtr<Thread> thread,
@@ -667,8 +679,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
667 CASCADE_CODE( 679 CASCADE_CODE(
668 WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); 680 WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback));
669 681
670 mutex->Release(thread.get());
671
672 return RESULT_SUCCESS; 682 return RESULT_SUCCESS;
673} 683}
674 684
@@ -738,13 +748,14 @@ static ResultCode SetThreadCoreMask(u64, u64, u64) {
738 return RESULT_SUCCESS; 748 return RESULT_SUCCESS;
739} 749}
740 750
741static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions, 751static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions,
742 u32 remote_permissions) { 752 u32 remote_permissions) {
743 LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz, 753 LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size,
744 local_permissions, remote_permissions); 754 local_permissions, remote_permissions);
745 auto sharedMemHandle = SharedMemory::Create( 755 auto sharedMemHandle =
746 g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz, 756 SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
747 (Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions); 757 static_cast<MemoryPermission>(local_permissions),
758 static_cast<MemoryPermission>(remote_permissions));
748 759
749 CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle)); 760 CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
750 return RESULT_SUCCESS; 761 return RESULT_SUCCESS;