NLMISC::CBlockMemory< T, __ctor_dtor__ > Class Template Reference

#include <block_memory.h>


Detailed Description

template<class T, bool __ctor_dtor__ = true>
class NLMISC::CBlockMemory< T, __ctor_dtor__ >

Block memory allocation

This memory manager is a fast memory allocator, doing same thing as new/delete. It works by block. block are always allocated, never deleted. alocation/free are in O(1).

Elements with sizeof(T)<sizeof(void*) should not be used with this allocator, because sizeEltInMemory= max(sizeof(T),sizeof(void*)).

free() check invalid ptr in debug only, for extra cost of 8 octets per element.

NB: if template parameter __ctor_dtor__ is false, then ctor and dtor are not called when an element is allocate()-ed or deallocate()-ed.

Author:
Lionel Berenguier

Nevrax France

Date:
2001

Definition at line 65 of file block_memory.h.

Public Member Functions

void __stl_alloc_changeEltSize (uint eltSize)
uint __stl_alloc_getEltSize () const
T * allocate ()
 allocate an element. ctor is called.

 CBlockMemory (const CBlockMemory< T, __ctor_dtor__ > &other)
 CBlockMemory (uint blockSize=16)
 Constructor.

void free (T *ptr)
 delete an element allocated with this manager. dtor is called. NULL is tested.

void purge ()
 ~CBlockMemory ()

Private Types

enum  TCheckIdent { CheckAllocatedIdent = 0x01234567, CheckDeletedIdent = 0x89ABCDEF }
 For debug only, check ident. More...


Private Member Functions

void buildBlock (CBlock &block)
void releaseBlock (CBlock &block)

Private Attributes

std::list< CBlock_Blocks
 list of blocks.

uint _BlockSize
 size of a block.

uint _EltSize
 size of an element in the block.

CFastMutex _Mutex
 Must be ThreadSafe (eg: important for 3D PointLight and list of transform).

sint _NAllocatedElts
 number of elements allocated.

void * _NextFreeElt
 next free element.


Member Enumeration Documentation

template<class T, bool __ctor_dtor__ = true>
enum NLMISC::CBlockMemory::TCheckIdent [private]
 

For debug only, check ident.

Enumeration values:
CheckAllocatedIdent 
CheckDeletedIdent 

Definition at line 260 of file block_memory.h.

00260 { CheckAllocatedIdent= 0x01234567, CheckDeletedIdent= 0x89ABCDEF };


Constructor & Destructor Documentation

template<class T, bool __ctor_dtor__ = true>
NLMISC::CBlockMemory< T, __ctor_dtor__ >::CBlockMemory uint  blockSize = 16  )  [inline]
 

Constructor.

Definition at line 70 of file block_memory.h.

00071         {
00072                 nlassert(blockSize);
00073                 _BlockSize= blockSize;
00074                 _EltSize= std::max(sizeof(T), sizeof(void*));
00075                 _NextFreeElt= NULL;
00076                 _NAllocatedElts= 0;
00077         }

template<class T, bool __ctor_dtor__ = true>
NLMISC::CBlockMemory< T, __ctor_dtor__ >::CBlockMemory const CBlockMemory< T, __ctor_dtor__ > &  other  )  [inline]
 

Definition at line 79 of file block_memory.h.

00080         {
00081                 _BlockSize= other._BlockSize;
00082                 // if other block is rebinded, don't copy its rebinded size.
00083                 _EltSize= std::max(sizeof(T), sizeof(void*));
00084                 // No elts allocated
00085                 _NextFreeElt= NULL;
00086                 _NAllocatedElts= 0;
00087         }

template<class T, bool __ctor_dtor__ = true>
NLMISC::CBlockMemory< T, __ctor_dtor__ >::~CBlockMemory  )  [inline]
 

purge()

Definition at line 90 of file block_memory.h.

00091         {
00092                 purge();
00093         }


Member Function Documentation

template<class T, bool __ctor_dtor__ = true>
void NLMISC::CBlockMemory< T, __ctor_dtor__ >::__stl_alloc_changeEltSize uint  eltSize  )  [inline]
 

Definition at line 209 of file block_memory.h.

00210         {
00211                 _Mutex.enter();
00212 
00213                 // must not be used with object ctor/dtor behavior.
00214                 nlassert(__ctor_dtor__ == false);
00215                 // format size.
00216                 eltSize= std::max(eltSize, sizeof(void*));
00217                 // if not the same size as before
00218                 if(_EltSize!= eltSize)
00219                 {
00220                         // verify that rebind is made before any allocation!!
00221                         nlassert(_Blocks.empty());
00222                         // change the size.
00223                         _EltSize= eltSize;
00224                 }
00225 
00226                 _Mutex.leave();
00227         };

template<class T, bool __ctor_dtor__ = true>
uint NLMISC::CBlockMemory< T, __ctor_dtor__ >::__stl_alloc_getEltSize  )  const [inline]
 

Definition at line 229 of file block_memory.h.

00230         {
00231                 return _EltSize;
00232         }

template<class T, bool __ctor_dtor__ = true>
T* NLMISC::CBlockMemory< T, __ctor_dtor__ >::allocate  )  [inline]
 

allocate an element. ctor is called.

Definition at line 97 of file block_memory.h.

00098         {
00099                 _Mutex.enter();
00100 
00101                 // if not enough memory, aloc a block.
00102                 if(!_NextFreeElt)
00103                 {
00104                         _Blocks.push_front(CBlock());
00105                         buildBlock(*_Blocks.begin());
00106                         // new free elt points to the beginning of this block.
00107                         _NextFreeElt= (*_Blocks.begin()).Data;
00108 #ifdef NL_DEBUG
00109                         // if debug, must decal for begin check.
00110                         _NextFreeElt= (uint32*)_NextFreeElt + 1;
00111 #endif
00112                 }
00113 
00114                 // choose next free elt.
00115                 nlassert(_NextFreeElt);
00116                 T*              ret= (T*)_NextFreeElt;
00117 
00118                 // update _NextFreeElt, so it points to the next free element.
00119                 _NextFreeElt= *(void**)_NextFreeElt;
00120                 
00121                 // construct the allocated element.
00122                 if( __ctor_dtor__ )
00123 #undef new
00124                         new (ret) T;
00125 #define new NL_NEW
00126 
00127 
00128                 // some simple Check.
00129 #ifdef NL_DEBUG
00130                 uint32  *checkStart= (uint32*)(void*)ret-1;
00131                 uint32  *checkEnd  = (uint32*)((uint8*)(void*)ret+_EltSize);
00132                 nlassert( *checkStart == CheckDeletedIdent);
00133                 nlassert( *checkEnd   == CheckDeletedIdent);
00134                 // if ok, mark this element as allocated.
00135                 *checkStart= CheckAllocatedIdent;
00136                 *checkEnd  = CheckAllocatedIdent;
00137 #endif
00138 
00139                 _NAllocatedElts++;
00140 
00141                 _Mutex.leave();
00142 
00143                 return ret;
00144         }

template<class T, bool __ctor_dtor__ = true>
void NLMISC::CBlockMemory< T, __ctor_dtor__ >::buildBlock CBlock block  )  [inline, private]
 

Definition at line 264 of file block_memory.h.

Referenced by NLMISC::CBlockMemory< CNode >::allocate().

00265         {
00266                 uint    i;
00267                 uint32  nodeSize= _EltSize;
00268 #ifdef NL_DEBUG
00269                 // must allocate more size for mem checks in debug.
00270                 nodeSize+= 2*sizeof(uint32);
00271 #endif
00272 
00273                 // allocate.
00274                 block.Data = (void*)new uint8 [_BlockSize * nodeSize];
00275 
00276                 // by default, all elements are not allocated, build the list of free elements.
00277                 void    *ptr= block.Data;
00278 #ifdef NL_DEBUG
00279                 // if debug, must decal for begin check.
00280                 ptr= (uint32*)ptr + 1;
00281 #endif
00282                 for(i=0; i<_BlockSize-1; i++)
00283                 {
00284                         // next elt.
00285                         void    *next= (uint8*)ptr + nodeSize;
00286                         // points to the next element in this array.
00287                         *(void**)ptr= next;
00288                         // next.
00289                         ptr= next;
00290                 }
00291                 // last element points to NULL.
00292                 *(void**)ptr= NULL;
00293 
00294 
00295                 // If debug, must init all check values to CheckDeletedIdent.
00296 #ifdef NL_DEBUG
00297                 ptr= block.Data;
00298                 // must decal for begin check.
00299                 ptr= (uint32*)ptr + 1;
00300                 // fill all nodes.
00301                 for(i=0; i<_BlockSize; i++)
00302                 {
00303                         uint32  *checkStart= (uint32*)ptr-1;
00304                         uint32  *checkEnd  = (uint32*)((uint8*)ptr+_EltSize);
00305                         // mark this element as deleted.
00306                         *checkStart= CheckDeletedIdent;
00307                         *checkEnd  = CheckDeletedIdent;
00308 
00309                         // next elt.
00310                         ptr= (uint8*)ptr + nodeSize;
00311                 }
00312 #endif
00313 
00314         }

template<class T, bool __ctor_dtor__ = true>
void NLMISC::CBlockMemory< T, __ctor_dtor__ >::free T *  ptr  )  [inline]
 

delete an element allocated with this manager. dtor is called. NULL is tested.

Definition at line 147 of file block_memory.h.

00148         {
00149                 if(!ptr)
00150                         return;
00151 
00152                 _Mutex.enter();
00153 
00154                 // some simple Check.
00155                 nlassert(_NAllocatedElts>0);
00156 #ifdef NL_DEBUG
00157                 uint32  *checkStart= (uint32*)(void*)ptr-1;
00158                 uint32  *checkEnd  = (uint32*)((uint8*)(void*)ptr+_EltSize);
00159                 nlassert( *checkStart == CheckAllocatedIdent);
00160                 nlassert( *checkEnd   == CheckAllocatedIdent);
00161                 // if ok, mark this element as deleted.
00162                 *checkStart= CheckDeletedIdent;
00163                 *checkEnd  = CheckDeletedIdent;
00164 #endif
00165                 
00166                 // destruct the element.
00167                 if( __ctor_dtor__ )
00168                         ptr->~T();
00169 
00170                 // just append this freed element to the list.
00171                 *(void**)ptr= _NextFreeElt;
00172                 _NextFreeElt= (void*) ptr;
00173 
00174                 _NAllocatedElts--;
00175 
00176                 _Mutex.leave();
00177         }

template<class T, bool __ctor_dtor__ = true>
void NLMISC::CBlockMemory< T, __ctor_dtor__ >::purge  )  [inline]
 

delete all blocks, freeing all memory. It is an error to purge() or delete a CBlockMemory, while elements still remains!! You must free your elements with free(). NB: you can disable this assert if you set NL3D_BlockMemoryAssertOnPurge to false (good to quit a program quickly without uninitialize).

Definition at line 185 of file block_memory.h.

Referenced by NLMISC::CBlockMemory< CNode >::~CBlockMemory().

00186         {
00187                 _Mutex.enter();
00188 
00189                 if(NL3D_BlockMemoryAssertOnPurge)
00190                         nlassert(_NAllocatedElts==0);
00191 
00192                 while(_Blocks.begin()!=_Blocks.end())
00193                 {
00194                         releaseBlock(*_Blocks.begin());
00195                         _Blocks.erase(_Blocks.begin());
00196                 }
00197 
00198                 _NextFreeElt= NULL;
00199                 _NAllocatedElts= 0;
00200 
00201                 _Mutex.leave();
00202         }

template<class T, bool __ctor_dtor__ = true>
void NLMISC::CBlockMemory< T, __ctor_dtor__ >::releaseBlock CBlock block  )  [inline, private]
 

Definition at line 315 of file block_memory.h.

Referenced by NLMISC::CBlockMemory< CNode >::purge().

00316         {
00317                 delete [] ((uint8*)block.Data);
00318         }


Field Documentation

template<class T, bool __ctor_dtor__ = true>
std::list<CBlock> NLMISC::CBlockMemory< T, __ctor_dtor__ >::_Blocks [private]
 

list of blocks.

Definition at line 256 of file block_memory.h.

template<class T, bool __ctor_dtor__ = true>
uint NLMISC::CBlockMemory< T, __ctor_dtor__ >::_BlockSize [private]
 

size of a block.

Definition at line 237 of file block_memory.h.

Referenced by NLMISC::CBlockMemory< CNode >::CBlockMemory().

template<class T, bool __ctor_dtor__ = true>
uint NLMISC::CBlockMemory< T, __ctor_dtor__ >::_EltSize [private]
 

size of an element in the block.

Definition at line 239 of file block_memory.h.

template<class T, bool __ctor_dtor__ = true>
CFastMutex NLMISC::CBlockMemory< T, __ctor_dtor__ >::_Mutex [private]
 

Must be ThreadSafe (eg: important for 3D PointLight and list of transform).

Definition at line 245 of file block_memory.h.

template<class T, bool __ctor_dtor__ = true>
sint NLMISC::CBlockMemory< T, __ctor_dtor__ >::_NAllocatedElts [private]
 

number of elements allocated.

Definition at line 241 of file block_memory.h.

template<class T, bool __ctor_dtor__ = true>
void* NLMISC::CBlockMemory< T, __ctor_dtor__ >::_NextFreeElt [private]
 

next free element.

Definition at line 243 of file block_memory.h.


The documentation for this class was generated from the following file:
Generated on Tue Mar 16 13:05:13 2004 for NeL by doxygen 1.3.6