| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- using ChocolArm64;
- using ChocolArm64.Memory;
- using System.Threading;
- namespace Ryujinx.OsHle
- {
- class Mutex
- {
- private const int MutexHasListenersMask = 0x40000000;
- private AMemory Memory;
- private long MutexAddress;
- private int CurrRequestingThreadHandle;
- private int HighestPriority;
- private ManualResetEvent ThreadEvent;
- private object EnterWaitLock;
- public Mutex(AMemory Memory, long MutexAddress)
- {
- this.Memory = Memory;
- this.MutexAddress = MutexAddress;
- ThreadEvent = new ManualResetEvent(false);
- EnterWaitLock = new object();
- }
- public void WaitForLock(AThread RequestingThread, int RequestingThreadHandle)
- {
- lock (EnterWaitLock)
- {
- int CurrentThreadHandle = Memory.ReadInt32(MutexAddress) & ~MutexHasListenersMask;
- if (CurrentThreadHandle == RequestingThreadHandle ||
- CurrentThreadHandle == 0)
- {
- return;
- }
- if (CurrRequestingThreadHandle == 0 || RequestingThread.Priority < HighestPriority)
- {
- CurrRequestingThreadHandle = RequestingThreadHandle;
- HighestPriority = RequestingThread.Priority;
- }
- }
- ThreadEvent.Reset();
- ThreadEvent.WaitOne();
- }
- public void GiveUpLock(int ThreadHandle)
- {
- lock (EnterWaitLock)
- {
- int CurrentThread = Memory.ReadInt32(MutexAddress) & ~MutexHasListenersMask;
- if (CurrentThread == ThreadHandle)
- {
- Unlock();
- }
- }
- }
- public void Unlock()
- {
- lock (EnterWaitLock)
- {
- if (CurrRequestingThreadHandle != 0)
- {
- Memory.WriteInt32(MutexAddress, CurrRequestingThreadHandle);
- }
- else
- {
- Memory.WriteInt32(MutexAddress, 0);
- }
- CurrRequestingThreadHandle = 0;
- ThreadEvent.Set();
- }
- }
- }
- }
|