示例#1
0
        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);
            }

            // 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);
            }
            return(returnBuffer);
        }
示例#2
0
        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);
            }

            if (buffer == null)
            {
                if (PinnableBufferCacheEventSource.Log.IsEnabled())
                {
                    PinnableBufferCacheEventSource.Log.FreeBufferNull(m_CacheName, m_FreeList.Count);
                }

                return;
            }

            // 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);
        }