diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/mutex.cpp | 120 |
1 files changed, 0 insertions, 120 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 50a9a0805..5cc0bd266 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -40,126 +40,6 @@ static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(VA return {highest_priority_thread, num_waiters}; } -void ReleaseThreadMutexes(Thread* thread) { - for (auto& mtx : thread->held_mutexes) { - mtx->SetHasWaiters(false); - mtx->SetHoldingThread(nullptr); - mtx->WakeupAllWaitingThreads(); - } - thread->held_mutexes.clear(); -} - -Mutex::Mutex() {} -Mutex::~Mutex() {} - -SharedPtr<Mutex> Mutex::Create(SharedPtr<Kernel::Thread> holding_thread, VAddr guest_addr, - std::string name) { - SharedPtr<Mutex> mutex(new Mutex); - - mutex->guest_addr = guest_addr; - mutex->name = std::move(name); - - // If mutex was initialized with a holding thread, acquire it by the holding thread - if (holding_thread) { - mutex->Acquire(holding_thread.get()); - } - - // Mutexes are referenced by guest address, so track this in the kernel - g_object_address_table.Insert(guest_addr, mutex); - - return mutex; -} - -bool Mutex::ShouldWait(Thread* thread) const { - auto holding_thread = GetHoldingThread(); - return holding_thread != nullptr && thread != holding_thread; -} - -void Mutex::Acquire(Thread* thread) { - ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); - - priority = thread->current_priority; - thread->held_mutexes.insert(this); - SetHoldingThread(thread); - thread->UpdatePriority(); - Core::System::GetInstance().PrepareReschedule(); -} - -ResultCode Mutex::Release(Thread* thread) { - auto holding_thread = GetHoldingThread(); - ASSERT(holding_thread); - - // We can only release the mutex if it's held by the calling thread. - ASSERT(thread == holding_thread); - - holding_thread->held_mutexes.erase(this); - holding_thread->UpdatePriority(); - SetHoldingThread(nullptr); - SetHasWaiters(!GetWaitingThreads().empty()); - WakeupAllWaitingThreads(); - Core::System::GetInstance().PrepareReschedule(); - - return RESULT_SUCCESS; -} - -void Mutex::AddWaitingThread(SharedPtr<Thread> thread) { - WaitObject::AddWaitingThread(thread); - thread->pending_mutexes.insert(this); - SetHasWaiters(true); - UpdatePriority(); -} - -void Mutex::RemoveWaitingThread(Thread* thread) { - WaitObject::RemoveWaitingThread(thread); - thread->pending_mutexes.erase(this); - if (!GetHasWaiters()) - SetHasWaiters(!GetWaitingThreads().empty()); - UpdatePriority(); -} - -void Mutex::UpdatePriority() { - if (!GetHoldingThread()) - return; - - u32 best_priority = THREADPRIO_LOWEST; - for (auto& waiter : GetWaitingThreads()) { - if (waiter->current_priority < best_priority) - best_priority = waiter->current_priority; - } - - if (best_priority != priority) { - priority = best_priority; - GetHoldingThread()->UpdatePriority(); - } -} - -Handle Mutex::GetOwnerHandle() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return guest_state.holding_thread_handle; -} - -SharedPtr<Thread> Mutex::GetHoldingThread() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return g_handle_table.Get<Thread>(guest_state.holding_thread_handle); -} - -void Mutex::SetHoldingThread(SharedPtr<Thread> thread) { - GuestState guest_state{Memory::Read32(guest_addr)}; - guest_state.holding_thread_handle.Assign(thread ? thread->guest_handle : 0); - Memory::Write32(guest_addr, guest_state.raw); -} - -bool Mutex::GetHasWaiters() const { - GuestState guest_state{Memory::Read32(guest_addr)}; - return guest_state.has_waiters != 0; -} - -void Mutex::SetHasWaiters(bool has_waiters) { - GuestState guest_state{Memory::Read32(guest_addr)}; - guest_state.has_waiters.Assign(has_waiters ? 1 : 0); - Memory::Write32(guest_addr, guest_state.raw); -} - ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, Handle requesting_thread_handle) { // The mutex address must be 4-byte aligned |