diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/ThreadQueue.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/ThreadQueue.cs | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/ThreadQueue.cs b/Ryujinx.HLE/HOS/Kernel/ThreadQueue.cs new file mode 100644 index 00000000..815e86ad --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/ThreadQueue.cs @@ -0,0 +1,158 @@ +namespace Ryujinx.HLE.HOS.Kernel +{ + class ThreadQueue + { + private const int LowestPriority = 0x3f; + + private SchedulerThread Head; + + private object ListLock; + + public ThreadQueue() + { + ListLock = new object(); + } + + public void Push(SchedulerThread Wait) + { + lock (ListLock) + { + //Ensure that we're not creating circular references + //by adding a thread that is already on the list. + if (HasThread(Wait)) + { + return; + } + + if (Head == null || Head.Thread.ActualPriority >= Wait.Thread.ActualPriority) + { + Wait.Next = Head; + + Head = Wait; + + return; + } + + SchedulerThread Curr = Head; + + while (Curr.Next != null) + { + if (Curr.Next.Thread.ActualPriority >= Wait.Thread.ActualPriority) + { + break; + } + + Curr = Curr.Next; + } + + Wait.Next = Curr.Next; + Curr.Next = Wait; + } + } + + public SchedulerThread Pop(int Core, int MinPriority = LowestPriority) + { + lock (ListLock) + { + int CoreMask = 1 << Core; + + SchedulerThread Prev = null; + SchedulerThread Curr = Head; + + while (Curr != null) + { + KThread Thread = Curr.Thread; + + if (Thread.ActualPriority <= MinPriority && (Thread.CoreMask & CoreMask) != 0) + { + if (Prev != null) + { + Prev.Next = Curr.Next; + } + else + { + Head = Head.Next; + } + + break; + } + + Prev = Curr; + Curr = Curr.Next; + } + + return Curr; + } + } + + public bool Remove(SchedulerThread Thread) + { + lock (ListLock) + { + if (Head == null) + { + return false; + } + else if (Head == Thread) + { + Head = Head.Next; + + return true; + } + + SchedulerThread Prev = Head; + SchedulerThread Curr = Head.Next; + + while (Curr != null) + { + if (Curr == Thread) + { + Prev.Next = Curr.Next; + + return true; + } + + Prev = Curr; + Curr = Curr.Next; + } + + return false; + } + } + + public bool Resort(SchedulerThread Thread) + { + lock (ListLock) + { + if (Remove(Thread)) + { + Push(Thread); + + return true; + } + + return false; + } + } + + public bool HasThread(SchedulerThread Thread) + { + lock (ListLock) + { + SchedulerThread Curr = Head; + + while (Curr != null) + { + if (Curr == Thread) + { + return true; + } + + Curr = Curr.Next; + } + + return false; + } + } + } +}
\ No newline at end of file |