void PoolMemoryAllocator::incVectorSlot(PoolElement &pe) { if(pe.m_currentVector == 0 || ++pe.m_index == ePoolVectorLength) { if(s_freeVectors == 0) s_freeVectors = allocateBlock(sizeof(PoolVector)); PoolVector *pv = (PoolVector *)s_freeVectors; s_freeVectors = MemElemPtr(pv)->m_next; pe.m_currentVector = pv; pe.m_index = 0; } }
PoolMemoryAllocator::MemElemPtr PoolMemoryAllocator::allocateBlock(__uint16 nBytes) { if(nBytes < eMinBytes) nBytes = eMinBytes; MemElemPtr pBlock = (MemElemPtr) malloc(eBlockSize); // we altogether create nSlices slices int nWords; int nSlices = slicesPerBlock(nBytes,nWords); MemElemPtr pHead = MemElemPtr(pBlock); BlockChainPtr(pBlock)->m_next = s_blocks; s_blocks = BlockChainPtr(pBlock); do { pBlock = pBlock->m_next = pBlock+nWords; } while(--nSlices > 1); MemElemPtr(pBlock)->m_next = 0; return pHead; }
void PoolMemoryAllocator::flushPool(__uint16 nBytes) { #ifndef OGDF_MEMORY_POOL_NTS if(nBytes >= sizeof(MemElemEx)) { MemElemPtr pRestHead, pRestTail; int nRest; MemElemExPtr pStart = collectGroups(nBytes, pRestHead, pRestTail, nRest); s_criticalSection->enter(); PoolElement &pe = s_pool[nBytes]; while(pStart != 0) { incVectorSlot(pe); pe.m_currentVector->m_pool[pe.m_index] = MemElemPtr(pStart); pStart = pStart->m_down; } if(pRestHead != 0) { int n = slicesPerBlock(nBytes); pRestTail->m_next = pe.m_restTail; int nTotal = nRest + pe.m_restCount; if(nTotal >= n) { MemElemPtr p = pe.m_restHead; int i = n-nRest; while(--i > 0) p = p->m_next; pe.m_restHead = p->m_next; pe.m_restCount = nTotal-n; incVectorSlot(pe); pe.m_currentVector->m_pool[pe.m_index] = pRestHead; } else { pe.m_restHead = pRestHead; pe.m_restCount = nTotal; } } s_criticalSection->leave(); } else { s_criticalSection->enter(); flushPoolSmall(nBytes); s_criticalSection->leave(); } #endif }