public object Allocate() { Interlocked.Increment(ref AllocCount); #if (NET_2_0) Core.Utils.SpinWait spin = new Core.Utils.SpinWait(); #else System.Threading.SpinWait spin = new System.Threading.SpinWait(); #endif while (Interlocked.Increment(ref _allocatorNumber) != 1) { Interlocked.Decrement(ref _allocatorNumber); spin.SpinOnce(); } object obj; var succ = _pool.TryDequeue(out obj); Interlocked.Decrement(ref _allocatorNumber); if (!succ || obj == null) { Interlocked.Increment(ref NewCount); obj = _factory.MakeObject(); } _factory.ActivateObject(obj); return(obj); }
// there may be some leak while increasing cap // but it's ok... public void Free(object t) { if (t == null) { return; } _factory.DestroyObject(t); Interlocked.Increment(ref FreeCount); #if (NET_4_6 && UNITY_2017) System.Threading.SpinWait spin = new System.Threading.SpinWait(); #else Core.Utils.SpinWait spin = new Core.Utils.SpinWait(); #endif while (Interlocked.Increment(ref _freeNumber) != 1) { Interlocked.Decrement(ref _freeNumber); spin.SpinOnce(); } if (_pool.Count > _pool.Capacity - 5) { _old = _pool; _pool = new RingBuffer <object>(_old.Capacity * 2); _logger.InfoFormat("ring buffer not big enough for object pool of type {0}", _factory.MakeObject().GetType()); if (_old.Count > 0) { object obj; var succ = _old.TryDequeue(out obj); while (succ && obj != null) { _pool.Enqueue(obj); succ = _old.TryDequeue(out obj); } } _old = null; } { _pool.Enqueue(t); Interlocked.Decrement(ref _freeNumber); } }