Open
Graph Drawing
Framework

 v.2012.05
 

PoolMemoryAllocator.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00044 #ifdef _MSC_VER
00045 #pragma once
00046 #endif
00047 
00048 #ifndef OGDF_POOL_MEMORY_ALLOCATOR_H
00049 #define OGDF_POOL_MEMORY_ALLOCATOR_H
00050 
00051 #ifndef OGDF_MEMORY_POOL_NTS
00052 #include <ogdf/basic/CriticalSection.h>
00053 #else
00054 #include <ogdf/basic/System.h>
00055 #endif
00056 
00057 
00058 namespace ogdf {
00059 
00060 
00062 
00079 class PoolMemoryAllocator
00080 {
00081     struct MemElem {
00082         MemElem *m_next;
00083     };
00084     struct MemElemEx {
00085         MemElemEx *m_next;
00086         MemElemEx *m_down;
00087     };
00088 
00089     typedef MemElem   *MemElemPtr;
00090     typedef MemElemEx *MemElemExPtr;
00091 
00092     struct PoolVector;
00093     struct PoolElement;
00094     struct BlockChain;
00095     typedef BlockChain *BlockChainPtr;
00096 
00097 public:
00098     enum {
00099         eMinBytes = sizeof(MemElemPtr),
00100         eTableSize = 256,
00101         eBlockSize = 8192,
00102         ePoolVectorLength = 15
00103     };
00104 
00105     PoolMemoryAllocator() { }
00106     ~PoolMemoryAllocator() { }
00107 
00109     static OGDF_EXPORT void init();
00110 
00111     static OGDF_EXPORT void initThread() {
00112 #if !defined(OGDF_MEMORY_POOL_NTS) && defined(OGDF_NO_COMPILER_TLS)
00113         pthread_setspecific(s_tpKey,calloc(eTableSize,sizeof(MemElemPtr)));
00114 #endif
00115     }
00116 
00118     static OGDF_EXPORT void cleanup();
00119 
00120     static OGDF_EXPORT bool checkSize(size_t nBytes) {
00121         return nBytes < eTableSize;
00122     }
00123 
00125     static OGDF_EXPORT void *allocate(size_t nBytes) {
00126 #if !defined(OGDF_MEMORY_POOL_NTS) && defined(OGDF_NO_COMPILER_TLS)
00127         MemElemPtr *pFreeBytes = ((MemElemPtr*)pthread_getspecific(s_tpKey))+nBytes;
00128 #else
00129         MemElemPtr *pFreeBytes = s_tp+nBytes;
00130 #endif
00131         if (OGDF_LIKELY(*pFreeBytes != 0)) {
00132             MemElemPtr p = *pFreeBytes;
00133             *pFreeBytes = p->m_next;
00134             return p;
00135         } else {
00136             return fillPool(*pFreeBytes,__uint16(nBytes));
00137         }
00138     }
00139 
00141     static OGDF_EXPORT void deallocate(size_t nBytes, void *p) {
00142 #if !defined(OGDF_MEMORY_POOL_NTS) && defined(OGDF_NO_COMPILER_TLS)
00143         MemElemPtr *pFreeBytes = ((MemElemPtr*)pthread_getspecific(s_tpKey))+nBytes;
00144 #else
00145         MemElemPtr *pFreeBytes = s_tp+nBytes;
00146 #endif
00147         MemElemPtr(p)->m_next = *pFreeBytes;
00148         *pFreeBytes = MemElemPtr(p);
00149     }
00150 
00152 
00158     static OGDF_EXPORT void deallocateList(size_t nBytes, void *pHead, void *pTail) {
00159 #if !defined(OGDF_MEMORY_POOL_NTS) && defined(OGDF_NO_COMPILER_TLS)
00160         MemElemPtr *pFreeBytes = ((MemElemPtr*)pthread_getspecific(s_tpKey))+nBytes;
00161 #else
00162         MemElemPtr *pFreeBytes = s_tp+nBytes;
00163 #endif
00164         MemElemPtr(pTail)->m_next = *pFreeBytes;
00165         *pFreeBytes = MemElemPtr(pHead);
00166     }
00167 
00168     static OGDF_EXPORT void flushPool();
00169     static OGDF_EXPORT void flushPool(__uint16 nBytes);
00170 
00172     static OGDF_EXPORT size_t memoryAllocatedInBlocks();
00173 
00175     static OGDF_EXPORT size_t memoryInGlobalFreeList();
00176 
00178     static OGDF_EXPORT size_t memoryInThreadFreeList();
00179 
00180 private:
00181     static int slicesPerBlock(__uint16 nBytes) {
00182         int nWords;
00183         return slicesPerBlock(nBytes,nWords);
00184     }
00185 
00186     static int slicesPerBlock(__uint16 nBytes, int &nWords) {
00187         nWords = (nBytes+sizeof(MemElemPtr)-1)/sizeof(MemElemPtr);
00188         return (eBlockSize-sizeof(MemElemPtr))/(nWords*sizeof(MemElemPtr));
00189     }
00190 
00191     static void incVectorSlot(PoolElement &pe);
00192 
00193     static void flushPoolSmall(__uint16 nBytes);
00194     static MemElemExPtr collectGroups(
00195         __uint16 nBytes,
00196         MemElemPtr &pRestHead,
00197         MemElemPtr &pRestTail,
00198         int &nRest);
00199 
00200     static void *fillPool(MemElemPtr &pFreeBytes, __uint16 nBytes);
00201 
00202     static MemElemPtr allocateBlock(__uint16 nBytes);
00203 
00204     static PoolElement s_pool[eTableSize];
00205     static MemElemPtr s_freeVectors;
00206     static BlockChainPtr s_blocks;
00207 
00208 #ifdef OGDF_MEMORY_POOL_NTS
00209     static MemElemPtr s_tp[eTableSize];
00210 #elif defined(OGDF_NO_COMPILER_TLS)
00211     static CriticalSection *s_criticalSection;
00212     static pthread_key_t s_tpKey;
00213 #else
00214     static CriticalSection *s_criticalSection;
00215     static OGDF_DECL_THREAD MemElemPtr s_tp[eTableSize];
00216 #endif
00217 };
00218 
00219 
00220 }
00221 
00222 #endif