private void InsertWaitingMutexThreadUnsafe(KThread OwnerThread, KThread WaitThread) { WaitThread.MutexOwner = OwnerThread; if (!OwnerThread.MutexWaiters.Contains(WaitThread)) { OwnerThread.MutexWaiters.Add(WaitThread); OwnerThread.UpdatePriority(); } }
private void MutexUnlock(KThread CurrThread, long MutexAddress) { lock (Process.ThreadSyncLock) { //This is the new thread that will now own the mutex. //If no threads are waiting for the lock, then it should be null. (KThread OwnerThread, int Count) = PopMutexThreadUnsafe(CurrThread, MutexAddress); if (OwnerThread == CurrThread) { throw new InvalidOperationException(); } if (OwnerThread != null) { //Remove all waiting mutex from the old owner, //and insert then on the new owner. UpdateMutexOwnerUnsafe(CurrThread, OwnerThread, MutexAddress); CurrThread.UpdatePriority(); int HasListeners = Count >= 2 ? MutexHasListenersMask : 0; Memory.WriteInt32ToSharedAddr(MutexAddress, HasListeners | OwnerThread.WaitHandle); OwnerThread.WaitHandle = 0; OwnerThread.MutexAddress = 0; OwnerThread.CondVarAddress = 0; OwnerThread.MutexOwner = null; OwnerThread.UpdatePriority(); Process.Scheduler.WakeUp(OwnerThread); Device.Log.PrintDebug(LogClass.KernelSvc, "Gave mutex to thread id " + OwnerThread.ThreadId + "!"); } else { Memory.WriteInt32ToSharedAddr(MutexAddress, 0); Device.Log.PrintDebug(LogClass.KernelSvc, "No threads waiting mutex!"); } } }