diff options
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/shared_memory.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 43 |
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() {} | |||
| 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/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 { | |||
| 14 | SharedMemory::SharedMemory() {} | 14 | SharedMemory::SharedMemory() {} |
| 15 | SharedMemory::~SharedMemory() {} | 15 | SharedMemory::~SharedMemory() {} |
| 16 | 16 | ||
| 17 | SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, | 17 | SharedPtr<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 | ||
| 741 | static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions, | 751 | static 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; |