aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/TranslatorCache.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-02-17 22:53:18 -0300
committerGitHub <noreply@github.com>2022-02-18 02:53:18 +0100
commit92d166ecb7e5b29a27bffd77754d8e592435ee6b (patch)
tree0c3d078c1487d6d596ed45deacca29c7d2d7d300 /ARMeilleure/Translation/TranslatorCache.cs
parent72e543e946610dc80e3d52290e4bea837097a070 (diff)
Enable CPU JIT cache invalidation (#2965)1.1.44
* Enable CPU JIT cache invalidation * Invalidate cache on IC IVAU
Diffstat (limited to 'ARMeilleure/Translation/TranslatorCache.cs')
-rw-r--r--ARMeilleure/Translation/TranslatorCache.cs95
1 files changed, 95 insertions, 0 deletions
diff --git a/ARMeilleure/Translation/TranslatorCache.cs b/ARMeilleure/Translation/TranslatorCache.cs
new file mode 100644
index 00000000..11286381
--- /dev/null
+++ b/ARMeilleure/Translation/TranslatorCache.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace ARMeilleure.Translation
+{
+ internal class TranslatorCache<T>
+ {
+ private readonly IntervalTree<ulong, T> _tree;
+ private readonly ReaderWriterLock _treeLock;
+
+ public int Count => _tree.Count;
+
+ public TranslatorCache()
+ {
+ _tree = new IntervalTree<ulong, T>();
+ _treeLock = new ReaderWriterLock();
+ }
+
+ public bool TryAdd(ulong address, ulong size, T value)
+ {
+ return AddOrUpdate(address, size, value, null);
+ }
+
+ public bool AddOrUpdate(ulong address, ulong size, T value, Func<ulong, T, T> updateFactoryCallback)
+ {
+ _treeLock.AcquireWriterLock(Timeout.Infinite);
+ bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback);
+ _treeLock.ReleaseWriterLock();
+
+ return result;
+ }
+
+ public T GetOrAdd(ulong address, ulong size, T value)
+ {
+ _treeLock.AcquireWriterLock(Timeout.Infinite);
+ value = _tree.GetOrAdd(address, address + size, value);
+ _treeLock.ReleaseWriterLock();
+
+ return value;
+ }
+
+ public bool Remove(ulong address)
+ {
+ _treeLock.AcquireWriterLock(Timeout.Infinite);
+ bool removed = _tree.Remove(address) != 0;
+ _treeLock.ReleaseWriterLock();
+
+ return removed;
+ }
+
+ public void Clear()
+ {
+ _treeLock.AcquireWriterLock(Timeout.Infinite);
+ _tree.Clear();
+ _treeLock.ReleaseWriterLock();
+ }
+
+ public bool ContainsKey(ulong address)
+ {
+ _treeLock.AcquireReaderLock(Timeout.Infinite);
+ bool result = _tree.ContainsKey(address);
+ _treeLock.ReleaseReaderLock();
+
+ return result;
+ }
+
+ public bool TryGetValue(ulong address, out T value)
+ {
+ _treeLock.AcquireReaderLock(Timeout.Infinite);
+ bool result = _tree.TryGet(address, out value);
+ _treeLock.ReleaseReaderLock();
+
+ return result;
+ }
+
+ public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps)
+ {
+ _treeLock.AcquireReaderLock(Timeout.Infinite);
+ int count = _tree.Get(address, address + size, ref overlaps);
+ _treeLock.ReleaseReaderLock();
+
+ return count;
+ }
+
+ public List<T> AsList()
+ {
+ _treeLock.AcquireReaderLock(Timeout.Infinite);
+ List<T> list = _tree.AsList();
+ _treeLock.ReleaseReaderLock();
+
+ return list;
+ }
+ }
+}