/*------------------------------------------------------------------------*/ /* */ /* MEMMGR.H */ /* */ /* Copyright Borland International 1991 */ /* All Rights Reserved */ /* */ /*------------------------------------------------------------------------*/ #if !defined( __MEMMGR_H ) #define __MEMMGR_H #if !defined( __STDTEMPL_H ) #include #endif // __STDTEMPL_H #if !defined( __RESOURCE_H ) #include #endif // __RESOURCE_H #if !defined( __STDLIB_H ) #include #endif // __STDLIB_H #if !defined( __CHECKS_H ) #include #endif // __CHECKS_H _CLASSDEF(HeaderBlock) _CLASSDEF(BlockList) _CLASSDEF(BaseMemBlocks) _CLASSDEF(MemStack) _CLASSDEF(Marker) _CLASSDEF(BMarker) class _CLASSTYPE HeaderBlock { public: void _FAR *operator new( size_t, size_t ); void _FAR *operator new( size_t ); }; inline void _FAR *HeaderBlock::operator new( size_t sz, size_t extra ) { return ::operator new( sz + extra ); } inline void _FAR *HeaderBlock::operator new( size_t ) { CHECK(0); return 0; } class _CLASSTYPE BlockList : public HeaderBlock { public: BlockList( BlockList _FAR * ); private: BlockList _FAR *next; friend class BaseMemBlocks; }; inline BlockList::BlockList( BlockList _FAR *nxt ) : next( nxt ) { } class _CLASSTYPE BaseMemBlocks { public: BaseMemBlocks( size_t = 8192 ); ~BaseMemBlocks(); char _FAR *block() const { return (char _FAR *)curBlock; } unsigned count() const { return blockCount; } allocBlock( size_t ); void freeTo( unsigned ); protected: const size_t blockSize; private: BlockList _FAR *curBlock; unsigned blockCount; }; inline BaseMemBlocks::BaseMemBlocks( size_t sz ) : curBlock(0), blockCount(0), blockSize(sz) { CHECK( sz != 0 ); } inline BaseMemBlocks::~BaseMemBlocks() { #if !defined( WINDOWS_WEP_BUG ) freeTo( 0 ); #endif } class _CLASSTYPE MemStack : public BaseMemBlocks { public: friend class Marker; MemStack( size_t = 8192 ); void *allocate( size_t ); private: size_t curLoc; }; inline void _FAR *operator new( size_t sz, MemStack& m ) { return m.allocate( sz ); } inline MemStack::MemStack( size_t sz ) : BaseMemBlocks( sz ), curLoc(sz) { CHECK( sz != 0 ); } class _CLASSTYPE Marker { public: Marker( MemStack _FAR & ms ) : memstk(ms), blk(ms.count()), curLoc(ms.curLoc) { } ~Marker() { PRECONDITION( blk < memstk.count() || (blk == memstk.count() && curLoc <= memstk.curLoc ) ); memstk.freeTo( blk ); memstk.curLoc = curLoc; } private: const unsigned blk; const size_t curLoc; MemStack& memstk; }; class _CLASSTYPE MemBlocks { public: MemBlocks( size_t, unsigned = 100 ); void _FAR *allocate( size_t ); void free( void _FAR * ); private: void _FAR *freeList; MemStack mem; size_t size; friend class BMarker; }; inline MemBlocks::MemBlocks( size_t sz, unsigned count ) : mem( sz*count ), freeList(0), size( max(sz, sizeof(void _FAR *)) ) { CHECK( sz != 0 && count != 0 ); } #pragma argsused inline void _FAR *MemBlocks::allocate( size_t sz ) { PRECONDITION( size == max(sz, sizeof(void _FAR *)) ); if( freeList == 0 ) return mem.allocate( size ); else { void _FAR *temp = freeList; freeList = *(void _FAR * _FAR *)temp; return temp; } } inline void MemBlocks::free( void _FAR * block ) { *(void _FAR * _FAR *)block = freeList; freeList = block; } class _CLASSTYPE BMarker { public: BMarker( MemBlocks _FAR & mb ) : memstk(mb.mem), blk(mb.mem.count()) {} ~BMarker() { PRECONDITION( blk <= memstk.count() ); memstk.freeTo( blk ); } private: const unsigned blk; MemStack _FAR & memstk; }; #endif // __MEMMGR_H