From ee1825219b8ccca13df7198d4e9ffb966e44c883 Mon Sep 17 00:00:00 2001 From: FICTURE7 Date: Fri, 9 Sep 2022 03:14:08 +0400 Subject: Clean up rejit queue (#2751) --- ARMeilleure/Translation/TranslatorQueue.cs | 121 +++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 ARMeilleure/Translation/TranslatorQueue.cs (limited to 'ARMeilleure/Translation/TranslatorQueue.cs') diff --git a/ARMeilleure/Translation/TranslatorQueue.cs b/ARMeilleure/Translation/TranslatorQueue.cs new file mode 100644 index 00000000..fc0aa64f --- /dev/null +++ b/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