|
|
//=========== (C) Copyright 2000 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#ifndef TSMEMPOOL_H
#define TSMEMPOOL_H
#ifdef _WIN32
#pragma once
#endif
#undef new
//-----------------------------------------------------------------------------
// Purpose: Optimized pool memory allocator
//-----------------------------------------------------------------------------
class CThreadSafeMemoryPool { public: enum { GROW_NONE=0, // Don't allow new blobs.
GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates get larger and larger each time it allocates one).
GROW_SLOW=2, // New blob size is numElements.
GROW_TIL_YOU_CANT=3 // GROW_SLOW til alloc fails - then STOP and dont assert!
};
CThreadSafeMemoryPool( int blockSize, int numElements, int growMode = GROW_FAST ); ~CThreadSafeMemoryPool();
void *Alloc(); // Allocate the element size you specified in the constructor.
void *Alloc( unsigned int cubAlloc ); void Free( void *pMem ); void Free( void *pMem, int cubAlloc ); // Frees everything
void Clear();
// display
void PrintStats(); size_t CubTotalSize(); size_t CubSizeInUse(); int Count();
static void * operator new( size_t size ) { CThreadSafeMemoryPool *pNode = (CThreadSafeMemoryPool *)MemAlloc_AllocAlignedFileLine( size, 8, __FILE__, __LINE__ #ifdef STEAM
, true // new operator
#endif
); return pNode; } static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { CThreadSafeMemoryPool *pNode = (CThreadSafeMemoryPool *)MemAlloc_AllocAlignedFileLine( size, 8, pFileName, nLine #ifdef STEAM
, true // new operator
#endif
); return pNode; } static void operator delete( void *p) { MemAlloc_FreeAligned( p #ifdef STEAM
, true // new operator
#endif
); } static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine ) { MemAlloc_FreeAligned( p #ifdef STEAM
, true // new operator
#endif
); } private: // These ain't gonna work
static void * operator new[] ( size_t size ); static void operator delete [] ( void *p);
// CThreadSpinRWLock needs 8 byte alignment to work but we new() CThreadSafeMemoryPool
// so simply place it at the start of the class to make sure it fits on the 8-byte boundary
CThreadSpinRWLock m_threadRWLock;
int m_nGrowMode; int m_cubBlockSize; int m_nGrowSize;
void ClearNoLock();
CInterlockedInt m_cBlocksInUse; size_t m_cubAllocated;
struct BlockSet_t { byte *m_pubBlockSet; size_t m_cubAllocated; }; CUtlVector<BlockSet_t> m_vecBlockSets;
class CTSListBase *m_ptslistFreeBlocks; };
//-----------------------------------------------------------------------------
// Wrapper macro to make an allocator that returns particular typed allocations
// and construction and destruction of objects.
//-----------------------------------------------------------------------------
template< class T > class CThreadSafeClassMemoryPool : public CThreadSafeMemoryPool { public: CThreadSafeClassMemoryPool(int numElements, int growMode = GROW_FAST) : CThreadSafeMemoryPool( sizeof(T), numElements, growMode ) {}
T* Alloc(); void Free( T *pMem ); };
template< class T > T* CThreadSafeClassMemoryPool<T>::Alloc() { T *pRet = (T*)CThreadSafeMemoryPool::Alloc(); if ( pRet ) { Construct( pRet ); } return pRet; }
template< class T > void CThreadSafeClassMemoryPool<T>::Free(T *pMem) { if ( pMem ) { Destruct( pMem ); }
CThreadSafeMemoryPool::Free( pMem ); }
#endif // TSMEMPOOL_H
|