diff options
| -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() {}  ConditionVariable::~ConditionVariable() {}  ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, -                                                                  VAddr mutex_addr,                                                                    std::string name) {      SharedPtr<ConditionVariable> condition_variable(new ConditionVariable);      condition_variable->name = std::move(name);      condition_variable->guest_addr = guest_addr; -    condition_variable->mutex_addr = mutex_addr; +    condition_variable->mutex_addr = 0;      // Condition variables are referenced by guest address, so track this in the kernel      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:       * Creates a condition variable.       * @param guest_addr Address of the object tracking the condition variable in guest memory. If       * specified, this condition variable will update the guest object when its state changes. -     * @param mutex_addr Optional address of a guest mutex associated with this condition variable, -     * used by the OS for implementing events.       * @param name Optional name of condition variable.       * @return The created condition variable.       */ -    static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0, +    static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr,                                                            std::string name = "Unknown");      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 {  SharedMemory::SharedMemory() {}  SharedMemory::~SharedMemory() {} -SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, +SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u64 size,                                               MemoryPermission permissions,                                               MemoryPermission other_permissions, VAddr address,                                               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:       * linear heap.       * @param name Optional object name, used for debugging purposes.       */ -    static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size, +    static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u64 size,                                            MemoryPermission permissions,                                            MemoryPermission other_permissions, VAddr address = 0,                                            MemoryRegion region = MemoryRegion::BASE, @@ -116,7 +116,7 @@ public:      /// Offset into the backing block for this shared memory.      size_t backing_block_offset;      /// Size of the memory block. Page-aligned. -    u32 size; +    u64 size;      /// Permission restrictions applied to the process which created the block.      MemoryPermission permissions;      /// 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,      SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle);      ASSERT(requesting_thread); +    ASSERT(requesting_thread == GetCurrentThread());      SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);      if (!mutex) { @@ -331,6 +332,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)      case GetInfoType::TotalHeapUsage:          *result = vm_manager.GetTotalHeapUsage();          break; +    case GetInfoType::IsCurrentProcessBeingDebugged: +        *result = 0; +        break;      case GetInfoType::RandomEntropy:          *result = 0;          break; @@ -415,8 +419,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s                "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",                shared_memory_handle, addr, size, permissions); -    SharedPtr<SharedMemory> shared_memory = -        Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle); +    SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);      if (!shared_memory) {          return ERR_INVALID_HANDLE;      } @@ -431,7 +434,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s      case MemoryPermission::WriteExecute:      case MemoryPermission::ReadWriteExecute:      case MemoryPermission::DontCare: -        return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type, +        return shared_memory->Map(g_current_process.get(), addr, permissions_type,                                    MemoryPermission::DontCare);      default:          LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); @@ -612,20 +615,29 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var          mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);      } -    ASSERT(mutex->GetOwnerHandle() == thread_handle); -      SharedPtr<ConditionVariable> condition_variable =          g_object_address_table.Get<ConditionVariable>(condition_variable_addr);      if (!condition_variable) {          // Create a new condition_variable for the specified address if one does not already exist -        condition_variable = -            ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap(); +        condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap();          condition_variable->name =              Common::StringFromFormat("condition-variable-%llx", condition_variable_addr);      } -    ASSERT(condition_variable->GetAvailableCount() == 0); -    ASSERT(condition_variable->mutex_addr == mutex_addr); +    if (condition_variable->mutex_addr) { +        // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify +        // everything is correct +        ASSERT(condition_variable->mutex_addr == mutex_addr); +    } else { +        // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex +        // associated with it +        condition_variable->mutex_addr = mutex_addr; +    } + +    if (mutex->GetOwnerHandle()) { +        // Release the mutex if the current thread is holding it +        mutex->Release(thread.get()); +    }      auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason,                                                   SharedPtr<Thread> thread, @@ -667,8 +679,6 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var      CASCADE_CODE(          WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); -    mutex->Release(thread.get()); -      return RESULT_SUCCESS;  } @@ -738,13 +748,14 @@ static ResultCode SetThreadCoreMask(u64, u64, u64) {      return RESULT_SUCCESS;  } -static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions, +static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions,                                       u32 remote_permissions) { -    LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz, +    LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size,                local_permissions, remote_permissions); -    auto sharedMemHandle = SharedMemory::Create( -        g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz, -        (Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions); +    auto sharedMemHandle = +        SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, +                             static_cast<MemoryPermission>(local_permissions), +                             static_cast<MemoryPermission>(remote_permissions));      CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));      return RESULT_SUCCESS; | 
