/*------------------------------------------------------------------------*/ /* */ /* MEMMGR.H */ /* */ /* Copyright (c) 1991, 1994 Borland International */ /* All Rights Reserved */ /* */ /*------------------------------------------------------------------------*/ #if !defined( CLASSLIB_MEMMGR_H ) #define CLASSLIB_MEMMGR_H #if !defined( __STDLIB_H ) #include #endif #if !defined( __DOS_H ) #include #endif #if !defined( __CHECKS_H ) #include #endif #if !defined( CLASSLIB_DEFS_H ) #include #endif #if !defined( CLASSLIB_STDTEMPL_H ) #include #endif #if !defined( CLASSLIB_ALLOCTR_H ) #include #endif #pragma option -Vo- #if defined( BI_CLASSLIB_NO_po ) #pragma option -po- #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMBlockList */ /* */ /* Used internally. */ /* */ /*------------------------------------------------------------------------*/ template class TMBaseMemBlocks; template class TMBlockList { public: TMBlockList( TMBlockList * ); private: void *operator new( size_t, size_t, const Alloc& ); void *operator new [] ( size_t, size_t, const Alloc& ); void operator delete( void * ); void operator delete [] ( void * ); TMBlockList *Next; friend TMBaseMemBlocks; }; template inline TMBlockList::TMBlockList( TMBlockList *nxt ) : Next( nxt ) { } template inline void *TMBlockList::operator new ( size_t sz, size_t extra, const Alloc& a ) { return new(a)char[sz+extra]; } template inline void TMBlockList::operator delete ( void *ptr ) { Alloc::operator delete(ptr); } template inline void TMBlockList::operator delete [] ( void _BIDSFAR * ptr ) { Alloc::operator delete [] (ptr); } #if defined( BI_OLDNAMES ) #define MBlockList TMBlockList #endif /*------------------------------------------------------------------------*/ /* */ /* class TBlockList */ /* */ /* Used internally. */ /* */ /*------------------------------------------------------------------------*/ class TBlockList : public TMBlockList { public: TBlockList( TBlockList *blk ) : TMBlockList( blk ) {} }; #if defined( BI_OLDNAMES ) #define BlockList TBlockList #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMBaseMemBlocks */ /* */ /* Used internally. */ /* */ /*------------------------------------------------------------------------*/ template class TMBaseMemBlocks : public Alloc { public: TMBaseMemBlocks( size_t = 8192 ); ~TMBaseMemBlocks(); char *Block() const { return REINTERPRET_CAST(char *,CurBlock); } unsigned Count() const { return BlockCount; } AllocBlock( size_t ); void FreeTo( unsigned ); size_t GetBlockSize() const { return BlockSize; } private: TMBlockList *CurBlock; const size_t BlockSize; unsigned BlockCount; }; template inline TMBaseMemBlocks::TMBaseMemBlocks( size_t sz ) : CurBlock(0), BlockCount(0), BlockSize(sz) { CHECK( sz != 0 ); } template inline TMBaseMemBlocks::~TMBaseMemBlocks() { #if !defined( BI_WINDOWS_WEP_BUG ) FreeTo( 0 ); #endif } template int TMBaseMemBlocks::AllocBlock( size_t sz ) { TMBlockList *temp = new( max(sz,BlockSize), *this ) TMBlockList( CurBlock-1 ); if( temp == 0 ) return 0; CurBlock = temp+1; BlockCount++; return 1; } template void TMBaseMemBlocks::FreeTo( unsigned term ) { PRECONDITION( BlockCount >= term ); while( BlockCount > term ) { TMBlockList *temp = CurBlock-1; CurBlock = (temp->Next)+1; delete temp; BlockCount--; } } #if defined( BI_OLDNAMES ) #define MBaseMemBlocks TMBaseMemBlocks #endif /*------------------------------------------------------------------------*/ /* */ /* class TBaseMemBlocks */ /* */ /* Used internally. */ /* */ /*------------------------------------------------------------------------*/ class TBaseMemBlocks : public TMBaseMemBlocks { public: TBaseMemBlocks( size_t sz = 8192 ) : TMBaseMemBlocks(sz) {} }; #if defined( BI_OLDNAMES ) #define BaseMemBlocks TBaseMemBlocks #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMMemStack */ /* */ /* Managed memory stack. Implements mark and release style memory */ /* management, using the allocator Alloc. */ /* */ /*------------------------------------------------------------------------*/ template class TMMarker; template class TMMemStack { public: friend TMMarker; TMMemStack( size_t = 8192 ); void *Allocate( size_t ); #if defined( BI_OLDNAMES ) void *allocate( size_t sz ) { return Allocate( sz ); } #endif // BI_OLDNAMES private: TMBaseMemBlocks Data; size_t CurLoc; }; #if defined( BI_OLDNAMES ) #define MMemStack TMMemStack #endif template inline void *operator new( size_t sz, TMMemStack& m ) { return m.Allocate( sz ); } template inline void *operator new [] ( size_t sz, TMMemStack& m ) { return m.Allocate( sz ); } template inline TMMemStack::TMMemStack( size_t sz ) : Data( sz ), CurLoc(sz) { CHECK( sz != 0 ); } template void *TMMemStack::Allocate( size_t sz ) { sz = max( 1U, sz ); if( sz > Data.GetBlockSize() - CurLoc ) if( Data.AllocBlock( sz ) == 0 ) return 0; else CurLoc = 0; void *temp = Data.Block() + CurLoc; CurLoc += sz; return temp; } /*------------------------------------------------------------------------*/ /* */ /* template class TMMarker */ /* */ /* Provides the mark for TMMemStack. */ /* */ /*------------------------------------------------------------------------*/ template class TMMarker { public: TMMarker( TMMemStack& ms ) : Memstk(ms), Blk(ms.Data.Count()), CurLoc(ms.CurLoc) { } ~TMMarker() { PRECONDITION( Blk < Memstk.Data.Count() || (Blk == Memstk.Data.Count() && CurLoc <= Memstk.CurLoc ) ); Memstk.Data.FreeTo( Blk ); Memstk.CurLoc = CurLoc; } private: TMMemStack& Memstk; const unsigned Blk; const size_t CurLoc; }; #if defined( BI_OLDNAMES ) #define MMarker TMMarker #endif /*------------------------------------------------------------------------*/ /* */ /* class TMemStack */ /* */ /* Implements mark and release style memory management using the */ /* standard allocator. */ /* */ /*------------------------------------------------------------------------*/ class TMemStack : public TMMemStack { public: TMemStack( size_t sz = 8192 ) : TMMemStack(sz) {} }; #if defined( BI_OLDNAMES ) #define MemStack TMemStack #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMarker */ /* */ /* Provides the mark for TMemStack. */ /* */ /*------------------------------------------------------------------------*/ class TMarker : public TMMarker { public: TMarker( TMMemStack& ms ) : TMMarker(ms) {} }; /*------------------------------------------------------------------------*/ /* */ /* template class TMMemBlocks */ /* */ /* Managed single-size block allocator. Allocates blocks */ /* of the size specified in the constructor, using the memory */ /* manager specified by Alloc. */ /* */ /*------------------------------------------------------------------------*/ template class TMMemBlocks { public: TMMemBlocks( size_t, unsigned = 100 ); void *Allocate( size_t ); void Free( void * ); #if defined( BI_OLDNAMES ) void *allocate( size_t sz ) { return Allocate(sz); } void free( void *ptr ) { Free(ptr); } #endif // BI_OLDNAMES private: void *FreeList; TMMemStack Mem; size_t Size; }; #if defined( BI_OLDNAMES ) #define MMemBlocks TMemBlocks #endif template inline TMMemBlocks::TMMemBlocks( size_t sz, unsigned count ) : Mem( sz*count ), FreeList(0), Size( max(sz,sizeof(void *)) ) { CHECK( sz != 0 && count != 0 ); } #pragma argsused template inline void *TMMemBlocks::Allocate( size_t sz ) { PRECONDITION( Size == max(sz,sizeof(void *)) ); if( FreeList == 0 ) return Mem.Allocate( Size ); else { void *temp = FreeList; FreeList = *(void **)temp; return temp; } } template inline void TMMemBlocks::Free( void *block ) { *(void **)block = FreeList; FreeList = block; } /*------------------------------------------------------------------------*/ /* */ /* class TMemBlocks */ /* */ /* Single-size block allocator. Allocates blocks of the size */ /* specified in the constructor, using the global operator new */ /* and operator delete. */ /* */ /*------------------------------------------------------------------------*/ class TMemBlocks : public TMMemBlocks { public: TMemBlocks( size_t sz, unsigned n = 100 ) : TMMemBlocks( sz, n ) {} }; #if defined( BI_OLDNAMES ) #define MemBlocks TMemBlocks #endif typedef TMMemBlocks TStandardBlocks; #if defined( BI_PLAT_WIN16 ) && defined( BI_DATA_FAR ) typedef TMMemBlocks TSharedBlocks; #endif #if defined( BI_CLASSLIB_NO_po ) #pragma option -po. #endif #pragma option -Vo. #endif // CLASSLIB_MEMMGR_H