Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) 1994 Microsoft Corporation All rights reserved.
Module Name:
memblock.cxx
Abstract:
Memory allocater for chunks of read only memory.
Author:
Albert Ting (AlbertT) 30-Aug-1994
Revision History:
--*/
#include "spllibp.hxx"
#pragma hdrstop
TMemBlock:: TMemBlock( UINT uGranularity, DWORD fdwFlags) : _uGranularity(uGranularity), _pIterBlock(NULL), _pIterData(NULL), _dwCount(0), _fdwFlags(fdwFlags) { DWORD dwSize = dwBlockHeaderSize() + _uGranularity;
if( _fdwFlags & kFlagGlobalNew ){
_pLast = (PBLOCK) new BYTE[dwSize];
} else {
_pLast = (PBLOCK)AllocMem( dwSize ); }
_pFirst = _pLast;
if (_pFirst) { _pFirst->pNext = NULL; _dwNextFree = dwBlockHeaderSize(); } }
TMemBlock:: ~TMemBlock() { PBLOCK pBlock; PBLOCK pBlockNext;
for (pBlock = _pFirst; pBlock; pBlock = pBlockNext) {
pBlockNext = pBlock->pNext;
if( _fdwFlags & kFlagGlobalNew ){
delete [] (PBYTE)pBlock;
} else {
//
// Our Delete must mirror the New.
//
FreeMem(pBlock); } } }
PVOID TMemBlock:: pvAlloc( DWORD dwSize ) { PDATA pData;
//
// If out of memory, fail.
//
if (!_pFirst) { goto FailOOM; }
dwSize = Align(dwSize + dwDataHeaderSize());
SPLASSERT(dwSize <= _uGranularity);
if (dwSize + _dwNextFree > _uGranularity) {
DWORD dwSize = dwBlockHeaderSize() + _uGranularity;
//
// Must allocate a new block
//
if( _fdwFlags & kFlagGlobalNew ){
_pLast->pNext = (PBLOCK) new BYTE[dwSize];
} else {
_pLast->pNext = (PBLOCK)AllocMem( dwSize ); }
if (!_pLast->pNext) { goto FailOOM; }
_pLast = _pLast->pNext; _pLast->pNext = NULL;
_dwNextFree = dwBlockHeaderSize(); }
//
// We have enough space in this link now;
// update everything.
//
pData = (PDATA)((PBYTE)_pLast + _dwNextFree); pData->dwSize = dwSize;
_dwNextFree += dwSize; _pLast->pDataLast = pData; _dwCount++;
return pvDataToUser(pData);
FailOOM: SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
PVOID TMemBlock:: pvFirst( VOID ) { if (!_dwCount) { return NULL; }
_pIterBlock = _pFirst; _pIterData = pBlockToData(_pIterBlock); _dwIterCount = 0;
return pvDataToUser(_pIterData); }
PVOID TMemBlock:: pvIter( VOID ) { _dwIterCount++;
if (_dwIterCount == _dwCount) return NULL;
//
// Go to next block. If we're at the last pData, go to next block.
//
if (_pIterData == _pIterBlock->pDataLast) {
_pIterBlock = _pIterBlock->pNext; _pIterData = pBlockToData(_pIterBlock);
} else {
_pIterData = pDataNext(_pIterData); }
return pvDataToUser(_pIterData); }
UINT TMemBlock:: uSize( PVOID pvUser ) const { return pvUserToData(pvUser)->dwSize; }
|