| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- using ChocolArm64.Memory;
- using System.Collections.Concurrent;
- using System.Threading;
- namespace Ryujinx.OsHle
- {
- class CondVar
- {
- private AMemory Memory;
- private long CondVarAddress;
- private long Timeout;
- private class WaitingThread
- {
- public int Handle;
- public ManualResetEvent Event;
- public WaitingThread(int Handle, ManualResetEvent Event)
- {
- this.Handle = Handle;
- this.Event = Event;
- }
- }
- private ConcurrentQueue<WaitingThread> WaitingThreads;
- public CondVar(AMemory Memory, long CondVarAddress, long Timeout)
- {
- this.Memory = Memory;
- this.CondVarAddress = CondVarAddress;
- this.Timeout = Timeout;
- WaitingThreads = new ConcurrentQueue<WaitingThread>();
- }
- public void WaitForSignal(int ThreadHandle)
- {
- int Count = Memory.ReadInt32(CondVarAddress);
- if (Count <= 0)
- {
- return;
- }
- Memory.WriteInt32(CondVarAddress, Count - 1);
- ManualResetEvent Event = new ManualResetEvent(false);
- WaitingThreads.Enqueue(new WaitingThread(ThreadHandle, Event));
- if (Timeout != -1)
- {
- Event.WaitOne((int)(Timeout / 1000000));
- }
- else
- {
- Event.WaitOne();
- }
- }
- public void SetSignal(int Count)
- {
- if (Count == -1)
- {
- while (WaitingThreads.TryDequeue(out WaitingThread Thread))
- {
- Thread.Event.Set();
- }
- Memory.WriteInt32(CondVarAddress, WaitingThreads.Count);
- }
- else
- {
- //TODO: Threads with the highest priority needs to be signaled first.
- if (WaitingThreads.TryDequeue(out WaitingThread Thread))
- {
- Thread.Event.Set();
- }
- Memory.WriteInt32(CondVarAddress, Count);
- }
- }
- }
- }
|