void CMemoryStack::FreeToAllocPoint( MemoryStackMark_t mark ) { void *pAllocPoint = m_pBase + mark; Assert( pAllocPoint >= m_pBase && pAllocPoint <= m_pNextAlloc ); if ( pAllocPoint >= m_pBase && pAllocPoint < m_pNextAlloc ) { #if defined(_WIN32) unsigned char *pDecommitPoint = MemAlign( (unsigned char *)pAllocPoint, m_commitSize ); if ( pDecommitPoint < m_pBase + m_minCommit ) { pDecommitPoint = m_pBase + m_minCommit; } unsigned decommitSize = m_pCommitLimit - pDecommitPoint; if ( decommitSize > 0 ) { MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() ); VirtualFree( pDecommitPoint, decommitSize, MEM_DECOMMIT ); m_pCommitLimit = pDecommitPoint; if ( mark > 0 ) { MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); } } #endif m_pNextAlloc = (unsigned char *)pAllocPoint; } }
void *CMemoryStack::Alloc( unsigned bytes, const char *pszName ) { Assert( m_pBase ); if ( !bytes ) bytes = 1; bytes = MemAlign( bytes, m_alignment ); void *pResult = m_pNextAlloc; m_pNextAlloc += bytes; if ( m_pNextAlloc > m_pCommitLimit ) { #if defined(_WIN32) unsigned char * pNewCommitLimit = MemAlign( m_pNextAlloc, m_commitSize ); unsigned commitSize = pNewCommitLimit - m_pCommitLimit; MemAlloc_RegisterExternalDeallocation( CMemoryStack, GetBase(), GetSize() ); Assert( m_pCommitLimit + commitSize < m_pAllocLimit ); if ( !VirtualAlloc( m_pCommitLimit, commitSize, VA_COMMIT_FLAGS, PAGE_READWRITE ) ) { Assert( 0 ); return NULL; } m_pCommitLimit = pNewCommitLimit; MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); #else Assert( 0 ); return NULL; #endif } memset( pResult, 0, bytes ); return pResult; }
int lsi_ctl_init(LsiCtl* lsi_ctl) { if (!lsi_ctl || lsi_ctl->m_head.m_size <= 0) { return -1; } int sum, shmid, last_chan_size, page_size, i; char* pool, *chan; // create share memory page_size = getpagesize(); sum = MemAlign(lsi_ctl->m_head.m_size, page_size); shmid = shmget(lsi_ctl->m_head.m_shm_key, sum, 0666 | IPC_CREAT | IPC_EXCL); if (shmid < 0) { if (-1 == shmid && EEXIST == errno) { printf("LSI [%d] already exist fail\n", lsi_ctl->m_head.m_shm_key); return -1; } printf("LSI create share momory[%d] fail\n", lsi_ctl->m_head.m_shm_key); return -1; } // set init data pool = (char*)(shmat(shmid, 0, 0)); memset(pool, 0, sum); memcpy(pool, &lsi_ctl->m_head, sizeof(lsi_ctl->m_head)); chan = pool + sizeof(lsi_ctl->m_head); last_chan_size = 0; for (i = 0; i < lsi_ctl->m_head.m_chan_count; i++) { chan += last_chan_size; memcpy(chan, &lsi_ctl->m_chan[i], sizeof(LsiChanHead)); last_chan_size = lsi_ctl->m_chan[i].m_size + sizeof(LsiChanHead); } shmdt(pool); return lsi_ctl_status(lsi_ctl); }
void CSmallBlockPool::Init( unsigned nBlockSize, byte *pBase, unsigned initialCommit ) { if ( !( nBlockSize % MIN_SBH_ALIGN == 0 && nBlockSize >= MIN_SBH_BLOCK && nBlockSize >= sizeof(TSLNodeBase_t) ) ) DebuggerBreak(); m_nBlockSize = nBlockSize; m_pCommitLimit = m_pNextAlloc = m_pBase = pBase; m_pAllocLimit = m_pBase + MAX_POOL_REGION; if ( initialCommit ) { initialCommit = MemAlign( initialCommit, PAGE_SIZE ); if ( !VirtualAlloc( m_pCommitLimit, initialCommit, VA_COMMIT_FLAGS, PAGE_READWRITE ) ) { Assert( 0 ); return; } m_pCommitLimit += initialCommit; } }
bool CMemoryStack::Init( unsigned maxSize, unsigned commitSize, unsigned initialCommit, unsigned alignment ) { Assert( !m_pBase ); m_maxSize = maxSize; m_alignment = MemAlign( alignment, 4 ); Assert( m_alignment == alignment ); Assert( m_maxSize > 0 ); #if defined(_WIN32) if ( commitSize != 0 ) { m_commitSize = commitSize; } unsigned pageSize; #ifndef _XBOX SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); Assert( !( sysInfo.dwPageSize & (sysInfo.dwPageSize-1)) ); pageSize = sysInfo.dwPageSize; #else pageSize = 4096; #endif if ( m_commitSize == 0 ) { m_commitSize = pageSize; } else { m_commitSize = MemAlign( m_commitSize, pageSize ); } m_maxSize = MemAlign( m_maxSize, m_commitSize ); Assert( m_maxSize % pageSize == 0 && m_commitSize % pageSize == 0 && m_commitSize <= m_maxSize ); m_pBase = (unsigned char *)VirtualAlloc( NULL, m_maxSize, MEM_RESERVE, PAGE_NOACCESS ); Assert( m_pBase ); m_pCommitLimit = m_pNextAlloc = m_pBase; if ( initialCommit ) { initialCommit = MemAlign( initialCommit, m_commitSize ); Assert( initialCommit < m_maxSize ); if ( !VirtualAlloc( m_pCommitLimit, initialCommit, VA_COMMIT_FLAGS, PAGE_READWRITE ) ) return false; m_minCommit = initialCommit; m_pCommitLimit += initialCommit; MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); } #else m_pBase = new unsigned char[m_maxSize]; m_pNextAlloc = m_pBase; m_pCommitLimit = m_pBase + m_maxSize; #endif m_pAllocLimit = m_pBase + m_maxSize; return ( m_pBase != NULL ); }
int CSmallBlockPool::Compact() { int nBytesFreed = 0; if ( m_FreeList.Count() ) { int i; int nFree = CountFreeBlocks(); FreeBlock_t **pSortArray = (FreeBlock_t **)malloc( nFree * sizeof(FreeBlock_t *) ); // can't use new because will reenter if ( !pSortArray ) { return 0; } i = 0; while ( i < nFree ) { pSortArray[i++] = m_FreeList.Pop(); } std::sort( pSortArray, pSortArray + nFree ); byte *pOldNextAlloc = m_pNextAlloc; for ( i = nFree - 1; i >= 0; i-- ) { if ( (byte *)pSortArray[i] == m_pNextAlloc - m_nBlockSize ) { pSortArray[i] = NULL; m_pNextAlloc -= m_nBlockSize; } else { break; } } if ( pOldNextAlloc != m_pNextAlloc ) { byte *pNewCommitLimit = MemAlign( (byte *)m_pNextAlloc, PAGE_SIZE ); if ( pNewCommitLimit < m_pCommitLimit ) { nBytesFreed = m_pCommitLimit - pNewCommitLimit; VirtualFree( pNewCommitLimit, nBytesFreed, MEM_DECOMMIT ); m_pCommitLimit = pNewCommitLimit; } } if ( pSortArray[0] ) { for ( i = 0; i < nFree ; i++ ) { if ( !pSortArray[i] ) { break; } m_FreeList.Push( pSortArray[i] ); } } free( pSortArray ); } return nBytesFreed; }