internal object Allocate()
{
// Fast path, get it from our Gen2 aged _freeList.
object returnBuffer;
if (!_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 _numAllocCalls);
if (numAllocCalls >= 1024)
{
lock (this)
{
int previousNumAllocCalls = Interlocked.Exchange(ref _numAllocCalls, 0);
if (previousNumAllocCalls >= 1024)
{
int nonGen2Count = 0;
foreach (object o in _freeList)
{
if (GC.GetGeneration(o) < GC.MaxGeneration)
{
nonGen2Count++;
}
}
PinnableBufferCacheEventSource.Log.WalkFreeListResult(_cacheName, _freeList.Count, nonGen2Count);
}
}
}
PinnableBufferCacheEventSource.Log.AllocateBuffer(_cacheName, PinnableBufferCacheEventSource.AddressOf(returnBuffer), returnBuffer.GetHashCode(), GC.GetGeneration(returnBuffer), _freeList.Count);
}
return(returnBuffer);
}