csgo-2018-source/gcsdk/steamextra/tier1/tsmempool.h
2021-07-24 21:11:47 -07:00

167 lines
4.0 KiB
C++

//=========== (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