11using System.Collections.Concurrent;
12using System.Collections.Generic;
13using System.Runtime.InteropServices;
17 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
20 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
21 public delegate
void Deallocate(IntPtr buffer, IntPtr state);
23 public static class MemoryManager {
35 public static bool EnablePooling =
true;
44 public static uint MinPoolSize = 64;
46 private static ConcurrentDictionary<IntPtr, ActiveMemoryInfo> _activeMemory =
47 new ConcurrentDictionary<IntPtr, ActiveMemoryInfo>();
48 private static ConcurrentDictionary<PoolKey, Queue<object>> _pooledMemory =
49 new ConcurrentDictionary<PoolKey, Queue<object>>();
51 [MonoPInvokeCallback(typeof(
Allocate))]
55 PoolKey key =
new PoolKey() {
62 if (!_pooledMemory.TryGetValue(key, out pool)) {
64 pool =
new Queue<object>();
65 _pooledMemory[key] = pool;
70 if (EnablePooling && pool.Count > MinPoolSize) {
71 memory = pool.Dequeue();
77 memory =
new byte[size];
80 memory =
new float[(size +
sizeof(float) - 1) /
sizeof(float)];
86 GCHandle handle = GCHandle.Alloc(memory, GCHandleType.Pinned);
87 IntPtr ptr = handle.AddrOfPinnedObject();
91 _activeMemory.TryAdd(ptr,
new ActiveMemoryInfo() {
97 }
catch (Exception e) {
105 public static void Unpin(IntPtr ptr, IntPtr state) {
108 ActiveMemoryInfo info = _activeMemory[ptr];
112 _pooledMemory[info.key].Enqueue(info.handle.Target);
116 ActiveMemoryInfo value;
118 _activeMemory.TryRemove(ptr, out value);
122 }
catch (Exception e) {
127 public static object GetPinnedObject(IntPtr ptr) {
129 return _activeMemory[ptr].handle.Target;
130 }
catch (Exception) { }
134 private struct PoolKey : IEquatable<PoolKey> {
138 public override int GetHashCode() {
139 return (
int)type | (int)size << 4;
142 public bool Equals(PoolKey other) {
143 return type == other.type &&
147 public override bool Equals(
object obj) {
148 if (obj is PoolKey) {
149 return Equals((PoolKey)obj);
156 private struct ActiveMemoryInfo {
157 public GCHandle handle;
delegate void Deallocate(IntPtr buffer, IntPtr state)
delegate IntPtr Allocate(UInt32 size, eLeapAllocatorType typeHint, IntPtr state)