Source: classlib/include/classlib/memmgr.h
|
|
|
|
/***************************************************************************
memmgr.h - manager della memoria allocata
-------------------
begin : ven dic 7 17:40:01 CET 2001
copyright : (C) 2001 by Nicola De Nisco
email : nicola@winada.it
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#if !defined( __CLASSLIB_MEMMGR_H )
#define __CLASSLIB_MEMMGR_H
#if !defined( __STDLIB_H )
#include
#endif // __STDLIB_H
#if !defined( __CHECKS_H )
#include
#endif // __CHECKS_H
#if !defined( __CLASSLIB_DEFS_H )
#include "classlib/defs.h"
#endif // __CLASSLIB_DEFS_H
#if !defined( __CLASSLIB_STDTEMPL_H )
#include "classlib/stdtempl.h"
#endif // __CLASSLIB_STDTEMPL_H
#if !defined( __CLASSLIB_ALLOCTR_H )
#include "classlib/alloctr.h"
#endif // __CLASSLIB_ALLOCTR_H
/**
class TMBlockList
Used internally.
*/
class TMBaseMemBlocks;
class TMBlockList
{
public:
TMBlockList( TMBlockList *nxt ) { Next=nxt; }
private:
TMBlockList *Next;
friend class TMBaseMemBlocks;
};
/**
class TBlockList
Used internally.
*/
class TBlockList : public TMBlockList
{
public:
TBlockList( TBlockList *blk ) :
TMBlockList( blk ) {}
};
/**
class TMBaseMemBlocks
Used internally.
*/
class TMBaseMemBlocks
{
public:
TMBaseMemBlocks( size_t sz = 8192 ) :
CurBlock(0),
BlockCount(0),
BlockSize(sz)
{
CHECK( sz != 0 );
}
~TMBaseMemBlocks()
{
#if !defined( BI_WINDOWS_WEP_BUG )
FreeTo( 0 );
#endif
}
char *Block() const { return (char*)CurBlock; }
unsigned Count() const { return BlockCount; }
size_t GetBlockSize() const { return BlockSize; }
int AllocBlock( size_t sz )
{
TMBlockList *temp = new TMBlockList( CurBlock-1 );
if( temp == 0 )
return 0;
CurBlock = temp+1;
BlockCount++;
return 1;
}
void FreeTo( unsigned term )
{
PRECONDITION( BlockCount >= term );
while( BlockCount > term )
{
TMBlockList *temp = CurBlock-1;
CurBlock = (temp->Next)+1;
delete temp;
BlockCount--;
}
}
private:
TMBlockList *CurBlock;
unsigned BlockCount;
const size_t BlockSize;
};
/**
class TBaseMemBlocks
Used internally.
*/
class TBaseMemBlocks : public TMBaseMemBlocks
{
typedef TMBaseMemBlocks parent;
public:
TBaseMemBlocks( size_t sz = 8192 ) :
parent(sz) {}
};
/**
class TMMemStack
Managed memory stack. Implements mark and release style memory
management, using the allocator Alloc.
*/
class TMMarker;
class TMMemStack
{
public:
friend class TMMarker;
TMMemStack( size_t sz = 8192 ) :
Data( sz ),
CurLoc(sz)
{
CHECK( sz != 0 );
}
void *Allocate( size_t sz )
{
sz = tmax( 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;
}
private:
TMBaseMemBlocks Data;
size_t CurLoc;
};
inline void *operator new( size_t sz, TMMemStack& m )
{
return m.Allocate( sz );
}
/**
class TMMarker
Provides the mark for TMMemStack.
*/
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;
};
/**
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) {}
};
/**
class TMarker
Provides the mark for TMemStack.
*/
class TMarker : public TMMarker
{
public:
TMarker( TMMemStack& ms ) :
TMMarker(ms) {}
};
/**
class TMMemBlocks
Managed single-size block allocator. Allocates blocks
of the size specified in the constructor, using the memory
manager specified by Alloc.
*/
class TMMemBlocks
{
public:
TMMemBlocks( size_t sz, unsigned count = 100 ) :
Mem( sz*count ),
FreeList(0),
Size( tmax(sz,sizeof(void *)) )
{
CHECK( sz != 0 && count != 0 );
}
void *Allocate( size_t sz )
{
PRECONDITION( Size == tmax(sz,sizeof(void *)) );
if( FreeList == 0 )
return Mem.Allocate( Size );
else
{
void *temp = FreeList;
FreeList = *(void **)temp;
return temp;
}
}
void Free( void* block )
{
*(void **)block = FreeList;
FreeList = block;
}
private:
TMMemStack Mem;
void *FreeList;
size_t Size;
};
/**
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 ) {}
};
typedef TMMemBlocks TStandardBlocks;
typedef TMMemBlocks TSharedBlocks;
#endif // __CLASSLIB_MEMMGR_H
Generated by: nicola on gulliver.wadahome.it on Sun May 25 13:54:34 2003, using kdoc 2.0a53. |