From cee712105850ac3385cd0091a923438167433f9f Mon Sep 17 00:00:00 2001
From: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Date: Sat, 8 Apr 2023 01:22:00 +0200
Subject: Move solution and projects to src
---
src/ARMeilleure/Translation/TranslatorQueue.cs | 121 +++++++++++++++++++++++++
1 file changed, 121 insertions(+)
create mode 100644 src/ARMeilleure/Translation/TranslatorQueue.cs
(limited to 'src/ARMeilleure/Translation/TranslatorQueue.cs')
diff --git a/src/ARMeilleure/Translation/TranslatorQueue.cs b/src/ARMeilleure/Translation/TranslatorQueue.cs
new file mode 100644
index 00000000..fc0aa64f
--- /dev/null
+++ b/src/ARMeilleure/Translation/TranslatorQueue.cs
@@ -0,0 +1,121 @@
+using ARMeilleure.Diagnostics;
+using ARMeilleure.State;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace ARMeilleure.Translation
+{
+ ///
+ /// Represents a queue of .
+ ///
+ ///
+ /// This does not necessarily behave like a queue, i.e: a FIFO collection.
+ ///
+ sealed class TranslatorQueue : IDisposable
+ {
+ private bool _disposed;
+ private readonly Stack _requests;
+ private readonly HashSet _requestAddresses;
+
+ ///
+ /// Gets the object used to synchronize access to the .
+ ///
+ public object Sync { get; }
+
+ ///
+ /// Gets the number of requests in the .
+ ///
+ public int Count => _requests.Count;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TranslatorQueue()
+ {
+ Sync = new object();
+
+ _requests = new Stack();
+ _requestAddresses = new HashSet();
+ }
+
+ ///
+ /// Enqueues a request with the specified and .
+ ///
+ /// Address of request
+ /// of request
+ public void Enqueue(ulong address, ExecutionMode mode)
+ {
+ lock (Sync)
+ {
+ if (_requestAddresses.Add(address))
+ {
+ _requests.Push(new RejitRequest(address, mode));
+
+ TranslatorEventSource.Log.RejitQueueAdd(1);
+
+ Monitor.Pulse(Sync);
+ }
+ }
+ }
+
+ ///
+ /// Tries to dequeue a . This will block the thread until a
+ /// is enqueued or the is disposed.
+ ///
+ /// dequeued
+ /// on success; otherwise
+ public bool TryDequeue(out RejitRequest result)
+ {
+ while (!_disposed)
+ {
+ lock (Sync)
+ {
+ if (_requests.TryPop(out result))
+ {
+ _requestAddresses.Remove(result.Address);
+
+ TranslatorEventSource.Log.RejitQueueAdd(-1);
+
+ return true;
+ }
+
+ Monitor.Wait(Sync);
+ }
+ }
+
+ result = default;
+
+ return false;
+ }
+
+ ///
+ /// Clears the .
+ ///
+ public void Clear()
+ {
+ lock (Sync)
+ {
+ TranslatorEventSource.Log.RejitQueueAdd(-_requests.Count);
+
+ _requests.Clear();
+ _requestAddresses.Clear();
+
+ Monitor.PulseAll(Sync);
+ }
+ }
+
+ ///
+ /// Releases all resources used by the instance.
+ ///
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ _disposed = true;
+
+ Clear();
+ }
+ }
+ }
+}
--
cgit v1.2.3