Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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