diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 43 |
1 files changed, 27 insertions, 16 deletions
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; |