|
|
//========= Copyright �, Valve LLC, All rights reserved. ======================
//
// Purpose: Defines a buffer pool used to group small allocations
//
//=============================================================================
#include "stdafx.h"
#include "bufferpool.h"
using namespace GCSDK;
CUtlVector<CBufferPool *> CBufferPool::sm_vecBufferPools;
//----------------------------------------------------------------------------
// Purpose: Constructor
//----------------------------------------------------------------------------
CBufferPool::CBufferPool( const char *pchName, const GCConVar &cvMaxSizeMB, const GCConVar &cvInitBufferSize, int nFlags ) : m_nBuffersInUse( 0 ) , m_nBuffersTotal( 0 ) , m_nHighWatermark( 0 ) , m_cubFree( 0 ) , m_sName( pchName ) , m_cvMaxSizeMB( cvMaxSizeMB ) , m_cvInitBufferSize( cvInitBufferSize ) , m_nFlags( nFlags ) { sm_vecBufferPools.AddToTail( this ); }
//----------------------------------------------------------------------------
// Purpose: Destructor
//----------------------------------------------------------------------------
CBufferPool::~CBufferPool() { m_vecFreeBuffers.PurgeAndDeleteElements(); sm_vecBufferPools.FindAndRemove( this ); }
//----------------------------------------------------------------------------
// Purpose: Gives a bind param buffer to a query
//----------------------------------------------------------------------------
CUtlBuffer *CBufferPool::GetBuffer() { m_nBuffersInUse++;
if ( m_vecFreeBuffers.Count() > 0 ) { CUtlBuffer *pBuffer = m_vecFreeBuffers.Tail(); m_vecFreeBuffers.Remove( m_vecFreeBuffers.Count() - 1 ); m_cubFree -= pBuffer->Size();
return pBuffer; } else { m_nBuffersTotal++; m_nHighWatermark = max( m_nBuffersTotal, m_nHighWatermark ); return new CUtlBuffer( 0, m_cvInitBufferSize.GetInt(), m_nFlags ); } }
//----------------------------------------------------------------------------
// Purpose: Returns a bind param buffer when a query is done with it
//----------------------------------------------------------------------------
void CBufferPool::ReturnBuffer( CUtlBuffer *pBuffer ) { m_nBuffersInUse--;
if ( ( int64 )( m_cubFree + pBuffer->Size() ) <= ( m_cvMaxSizeMB.GetInt() * k_nMegabyte ) ) { pBuffer->Clear(); m_cubFree += pBuffer->Size(); m_vecFreeBuffers.AddToTail( pBuffer ); } else { m_nBuffersTotal--; delete pBuffer; } }
//----------------------------------------------------------------------------
// Purpose: Print statistics to the console
//----------------------------------------------------------------------------
void CBufferPool::DumpPools() { EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, "Reusable Buffer Pools:\n" ); EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, " Pool Buffers Free Max Buffers Total Mem (est) Free Mem\n" ); EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, " ------------------------------ ------------ ------------ ------------ ---------------- ----------------\n" );
FOR_EACH_VEC( sm_vecBufferPools, i ) { CBufferPool *pPool = sm_vecBufferPools[i];
int nTotalEst = 0; if ( pPool->m_vecFreeBuffers.Count() > 0 ) { nTotalEst = pPool->m_cubFree / pPool->m_vecFreeBuffers.Count() * pPool->m_nBuffersTotal; }
EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, " %-30s %12d %12d %12d %16s %16s\n", pPool->m_sName.Get(), pPool->m_nBuffersTotal, pPool->m_vecFreeBuffers.Count(), pPool->m_nHighWatermark, Q_pretifymem( nTotalEst, 0, true ), Q_pretifymem( pPool->m_cubFree, 0, true ) ); }
EmitInfo( SPEW_CONSOLE, SPEW_ALWAYS, LOG_ALWAYS, "\n" ); }
|