/// <summary> /// Return a buffer back to the buffer manager. /// </summary> internal void Free(object buffer) { #if ENABLE // Check to see whether or not the cache is disabled. if (m_CacheName == null) { return; } #endif if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.FreeBuffer(m_CacheName, PinnableBufferCacheEventSource.AddressOf(buffer), buffer.GetHashCode(), m_FreeList.Count); } // After we've done 3 gen1 GCs, assume that all buffers have aged into gen2 on the free path. if ((m_gen1CountAtLastRestock + 3) > GC.CollectionCount(GC.MaxGeneration - 1)) { lock (this) { if (GC.GetGeneration(buffer) < GC.MaxGeneration) { // The buffer is not aged, so put it in the non-aged free list. m_moreThanFreeListNeeded = true; PinnableBufferCacheEventSource.Log.FreeBufferStillTooYoung(m_CacheName, m_NotGen2.Count); m_NotGen2.Add(buffer); m_gen1CountAtLastRestock = GC.CollectionCount(GC.MaxGeneration - 1); return; } } } // If we discovered that it is indeed Gen2, great, put it in the Gen2 list. m_FreeList.Push(buffer); }
internal void Free(object buffer) { if (this.m_CacheName == null) { return; } if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.FreeBuffer(this.m_CacheName, PinnableBufferCacheEventSource.AddressOf(buffer), buffer.GetHashCode(), this.m_FreeList.Count); } if (buffer == null) { if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.FreeBufferNull(this.m_CacheName, this.m_FreeList.Count); } return; } if (this.m_gen1CountAtLastRestock + 3 > GC.CollectionCount(GC.MaxGeneration - 1)) { lock (this) { if (GC.GetGeneration(buffer) < GC.MaxGeneration) { this.m_moreThanFreeListNeeded = true; PinnableBufferCacheEventSource.Log.FreeBufferStillTooYoung(this.m_CacheName, this.m_NotGen2.Count); this.m_NotGen2.Add(buffer); this.m_gen1CountAtLastRestock = GC.CollectionCount(GC.MaxGeneration - 1); return; } } } this.m_FreeList.Push(buffer); }
/// <summary> /// Get a object from the buffer manager. If no buffers exist, allocate a new one. /// </summary> internal object Allocate() { #if ENABLE // Check to see whether or not the cache is disabled. if (m_CacheName == null) { return(m_factory()); } #endif // Fast path, get it from our Gen2 aged m_FreeList. object returnBuffer; if (!m_FreeList.TryPop(out returnBuffer)) { Restock(out returnBuffer); } #if LOGGING // Computing free count is expensive enough that we don't want to compute it unless logging is on. if (PinnableBufferCacheEventSource.Log.IsEnabled()) { int numAllocCalls = Interlocked.Increment(ref m_numAllocCalls); if (numAllocCalls >= 1024) { lock (this) { int previousNumAllocCalls = Interlocked.Exchange(ref m_numAllocCalls, 0); if (previousNumAllocCalls >= 1024) { int nonGen2Count = 0; foreach (object o in m_FreeList) { if (GC.GetGeneration(o) < GC.MaxGeneration) { nonGen2Count++; } } PinnableBufferCacheEventSource.Log.WalkFreeListResult(m_CacheName, m_FreeList.Count, nonGen2Count); } } } PinnableBufferCacheEventSource.Log.AllocateBuffer(m_CacheName, PinnableBufferCacheEventSource.AddressOf(returnBuffer), returnBuffer.GetHashCode(), GC.GetGeneration(returnBuffer), m_FreeList.Count); } #endif return(returnBuffer); }
internal object Allocate() { if (this.m_CacheName == null) { return(this.m_factory()); } object obj; if (!this.m_FreeList.TryPop(out obj)) { this.Restock(out obj); } if (PinnableBufferCacheEventSource.Log.IsEnabled()) { int num = Interlocked.Increment(ref this.m_numAllocCalls); if (num >= 1024) { lock (this) { int num2 = Interlocked.Exchange(ref this.m_numAllocCalls, 0); if (num2 >= 1024) { int num3 = 0; foreach (object obj2 in this.m_FreeList) { if (GC.GetGeneration(obj2) < GC.MaxGeneration) { num3++; } } PinnableBufferCacheEventSource.Log.WalkFreeListResult(this.m_CacheName, this.m_FreeList.Count, num3); } } } PinnableBufferCacheEventSource.Log.AllocateBuffer(this.m_CacheName, PinnableBufferCacheEventSource.AddressOf(obj), obj.GetHashCode(), GC.GetGeneration(obj), this.m_FreeList.Count); } return(obj); }