Added SmallValueObject, SmallObjectBase, and AllocatorSingleton classes.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@166 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
dea82286fa
commit
b436c6aaee
1 changed files with 175 additions and 73 deletions
|
@ -13,7 +13,8 @@
|
||||||
// without express or implied warranty.
|
// without express or implied warranty.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Last update: Nov 26, 2004
|
// $Header$
|
||||||
|
|
||||||
|
|
||||||
#ifndef SMALLOBJ_INC_
|
#ifndef SMALLOBJ_INC_
|
||||||
#define SMALLOBJ_INC_
|
#define SMALLOBJ_INC_
|
||||||
|
@ -40,14 +41,20 @@ namespace Loki
|
||||||
{
|
{
|
||||||
class FixedAllocator;
|
class FixedAllocator;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class SmallObjAllocator
|
||||||
|
// Manages pool of fixed-size allocators.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class SmallObjAllocator
|
class SmallObjAllocator
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
SmallObjAllocator( std::size_t pageSize, std::size_t maxObjectSize,
|
SmallObjAllocator( std::size_t pageSize, std::size_t maxObjectSize,
|
||||||
std::size_t objectAlignSize );
|
std::size_t objectAlignSize );
|
||||||
|
|
||||||
~SmallObjAllocator( void );
|
~SmallObjAllocator( void );
|
||||||
|
|
||||||
|
public:
|
||||||
void * Allocate( std::size_t size, bool doThrow );
|
void * Allocate( std::size_t size, bool doThrow );
|
||||||
|
|
||||||
void Deallocate( void * p, std::size_t size );
|
void Deallocate( void * p, std::size_t size );
|
||||||
|
@ -57,6 +64,11 @@ namespace Loki
|
||||||
inline std::size_t GetAlignment() const { return objectAlignSize_; }
|
inline std::size_t GetAlignment() const { return objectAlignSize_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Copy-constructor is not implemented.
|
||||||
|
SmallObjAllocator( const SmallObjAllocator & );
|
||||||
|
/// Copy-assignment operator is not implemented.
|
||||||
|
SmallObjAllocator & operator = ( const SmallObjAllocator & );
|
||||||
|
|
||||||
Loki::FixedAllocator * pool_;
|
Loki::FixedAllocator * pool_;
|
||||||
|
|
||||||
std::size_t maxSmallObjectSize_;
|
std::size_t maxSmallObjectSize_;
|
||||||
|
@ -64,6 +76,126 @@ namespace Loki
|
||||||
std::size_t objectAlignSize_;
|
std::size_t objectAlignSize_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class AllocatorSingleton
|
||||||
|
// This template class is derived from SmallObjAllocator in order to pass template
|
||||||
|
// arguments into SmallObjAllocator, and still have a default constructor for the
|
||||||
|
// singleton.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
template <class> class ThreadingModel,
|
||||||
|
std::size_t chunkSize,
|
||||||
|
std::size_t maxSmallObjectSize,
|
||||||
|
std::size_t objectAlignSize
|
||||||
|
>
|
||||||
|
class AllocatorSingleton : public SmallObjAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline AllocatorSingleton() :
|
||||||
|
SmallObjAllocator( chunkSize, maxSmallObjectSize, objectAlignSize )
|
||||||
|
{}
|
||||||
|
inline ~AllocatorSingleton( void ) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Copy-constructor is not implemented.
|
||||||
|
AllocatorSingleton( const AllocatorSingleton & );
|
||||||
|
/// Copy-assignment operator is not implemented.
|
||||||
|
AllocatorSingleton & operator = ( const AllocatorSingleton & );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class SmallObjectBase
|
||||||
|
// Base class for small object allocation classes.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
template <class> class ThreadingModel,
|
||||||
|
std::size_t chunkSize,
|
||||||
|
std::size_t maxSmallObjectSize,
|
||||||
|
std::size_t objectAlignSize,
|
||||||
|
template <class> class LifetimePolicy
|
||||||
|
>
|
||||||
|
class SmallObjectBase
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) && (LOKI_DEFAULT_OBJECT_ALIGNMENT != 0)
|
||||||
|
|
||||||
|
/// Defines type of allocator.
|
||||||
|
typedef AllocatorSingleton< ThreadingModel, chunkSize,
|
||||||
|
maxSmallObjectSize, objectAlignSize > MyAllocator;
|
||||||
|
|
||||||
|
/// Defines type for thread-safety locking mechanism.
|
||||||
|
typedef ThreadingModel< MyAllocator > MyThreadingModel;
|
||||||
|
|
||||||
|
/// Defines singleton made from allocator.
|
||||||
|
typedef Loki::SingletonHolder< MyAllocator, Loki::CreateStatic,
|
||||||
|
LifetimePolicy, ThreadingModel > MyAllocatorSingleton;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Throwing single-object new.
|
||||||
|
@note The exception specification is commented to prevent warning
|
||||||
|
from MS compiler.
|
||||||
|
*/
|
||||||
|
static void * operator new ( std::size_t size ) // throw ( std::bad_alloc )
|
||||||
|
{
|
||||||
|
typename MyThreadingModel::Lock lock;
|
||||||
|
(void)lock; // get rid of warning
|
||||||
|
return MyAllocatorSingleton::Instance().Allocate( size, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Non-throwing single-object new.
|
||||||
|
static void * operator new ( std::size_t size, const std::nothrow_t & ) throw ()
|
||||||
|
{
|
||||||
|
typename MyThreadingModel::Lock lock;
|
||||||
|
(void)lock; // get rid of warning
|
||||||
|
return MyAllocatorSingleton::Instance().Allocate( size, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Placement single-object new.
|
||||||
|
inline static void * operator new ( std::size_t size, void * place )
|
||||||
|
{
|
||||||
|
return ::operator new( size, place );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Single-object delete.
|
||||||
|
static void operator delete ( void * p, std::size_t size ) throw ()
|
||||||
|
{
|
||||||
|
typename MyThreadingModel::Lock lock;
|
||||||
|
(void)lock; // get rid of warning
|
||||||
|
MyAllocatorSingleton::Instance().Deallocate( p, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Non-throwing single-object delete.
|
||||||
|
static void operator delete ( void * p, std::size_t size,
|
||||||
|
const std::nothrow_t & ) throw()
|
||||||
|
{
|
||||||
|
typename MyThreadingModel::Lock lock;
|
||||||
|
(void)lock; // get rid of warning
|
||||||
|
MyAllocatorSingleton::Instance().Deallocate( p, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Placement single-object delete.
|
||||||
|
inline static void operator delete ( void * p, void * place )
|
||||||
|
{
|
||||||
|
::operator delete ( p, place );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #if default template parameters are not zero
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline SmallObjectBase( void ) {}
|
||||||
|
inline SmallObjectBase( const SmallObjectBase & ) {}
|
||||||
|
inline SmallObjectBase & operator = ( const SmallObjectBase & ) {}
|
||||||
|
inline ~SmallObjectBase() {}
|
||||||
|
}; // end class SmallObjectBase
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// class SmallObject
|
// class SmallObject
|
||||||
// Base class for polymorphic small objects, offers fast allocations &
|
// Base class for polymorphic small objects, offers fast allocations &
|
||||||
|
@ -75,84 +207,50 @@ namespace Loki
|
||||||
template <class> class ThreadingModel = DEFAULT_THREADING,
|
template <class> class ThreadingModel = DEFAULT_THREADING,
|
||||||
std::size_t chunkSize = DEFAULT_CHUNK_SIZE,
|
std::size_t chunkSize = DEFAULT_CHUNK_SIZE,
|
||||||
std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE,
|
std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE,
|
||||||
std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT
|
std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
||||||
|
template <class> class LifetimePolicy = Loki::NoDestroy
|
||||||
>
|
>
|
||||||
class SmallObject : public ThreadingModel<
|
class SmallObject : public SmallObjectBase< ThreadingModel, chunkSize,
|
||||||
SmallObject< ThreadingModel, chunkSize, maxSmallObjectSize, objectAlignSize > >
|
maxSmallObjectSize, objectAlignSize, LifetimePolicy >
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef ThreadingModel< SmallObject<ThreadingModel,
|
|
||||||
chunkSize, maxSmallObjectSize, objectAlignSize > > MyThreadingModel;
|
|
||||||
|
|
||||||
struct MySmallObjAllocator : public SmallObjAllocator
|
|
||||||
{
|
|
||||||
MySmallObjAllocator()
|
|
||||||
: SmallObjAllocator( chunkSize, maxSmallObjectSize, objectAlignSize )
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
// The typedef below would make things much simpler,
|
|
||||||
// but MWCW won't like it
|
|
||||||
// typedef SingletonHolder<MySmallObjAllocator/*, CreateStatic,
|
|
||||||
// NoDestroy, ThreadingModel*/> MyAllocator;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) && (LOKI_DEFAULT_OBJECT_ALIGNMENT != 0)
|
|
||||||
|
|
||||||
/// Throwing single-object new.
|
|
||||||
static void * operator new ( std::size_t size ) throw ( std::bad_alloc )
|
|
||||||
{
|
|
||||||
typename MyThreadingModel::Lock lock;
|
|
||||||
(void)lock; // get rid of warning
|
|
||||||
return SingletonHolder< MySmallObjAllocator, CreateStatic,
|
|
||||||
NoDestroy >::Instance().Allocate( size, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Non-throwing single-object new.
|
|
||||||
static void * operator new ( std::size_t size, const std::nothrow_t & ) throw ()
|
|
||||||
{
|
|
||||||
typename MyThreadingModel::Lock lock;
|
|
||||||
(void)lock; // get rid of warning
|
|
||||||
return SingletonHolder< MySmallObjAllocator, CreateStatic,
|
|
||||||
NoDestroy >::Instance().Allocate( size, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Placement single-object new.
|
|
||||||
static void * operator new ( std::size_t size, void * place )
|
|
||||||
{
|
|
||||||
return ::operator new( size, place );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Single-object delete.
|
|
||||||
static void operator delete ( void * p, std::size_t size ) throw ()
|
|
||||||
{
|
|
||||||
typename MyThreadingModel::Lock lock;
|
|
||||||
(void)lock; // get rid of warning
|
|
||||||
SingletonHolder< MySmallObjAllocator, CreateStatic,
|
|
||||||
NoDestroy >::Instance().Deallocate( p, size );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Non-throwing single-object delete.
|
|
||||||
static void operator delete ( void * p, std::size_t size,
|
|
||||||
const std::nothrow_t & ) throw()
|
|
||||||
{
|
|
||||||
typename MyThreadingModel::Lock lock;
|
|
||||||
(void)lock; // get rid of warning
|
|
||||||
SingletonHolder< MySmallObjAllocator, CreateStatic,
|
|
||||||
NoDestroy >::Instance().Deallocate( p, size );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Placement single-object delete.
|
|
||||||
static void operator delete ( void * p, void * place )
|
|
||||||
{
|
|
||||||
::operator delete ( p, place );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // #if default template parameters are not zero
|
|
||||||
|
|
||||||
virtual ~SmallObject() {}
|
virtual ~SmallObject() {}
|
||||||
|
protected:
|
||||||
|
inline SmallObject( void ) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Copy-constructor is not implemented.
|
||||||
|
SmallObject( const SmallObject & );
|
||||||
|
/// Copy-assignment operator is not implemented.
|
||||||
|
SmallObject & operator = ( const SmallObject & );
|
||||||
}; // end class SmallObject
|
}; // end class SmallObject
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class SmallValueObject
|
||||||
|
// Base class for small objects with value semantics - offers fast allocations &
|
||||||
|
// deallocations. Destructor is non-virtual, inline, and protected.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
template <class> class ThreadingModel = DEFAULT_THREADING,
|
||||||
|
std::size_t chunkSize = DEFAULT_CHUNK_SIZE,
|
||||||
|
std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE,
|
||||||
|
std::size_t objectAlignSize = LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
||||||
|
template <class> class LifetimePolicy = Loki::NoDestroy
|
||||||
|
>
|
||||||
|
class SmallValueObject : public SmallObjectBase< ThreadingModel, chunkSize,
|
||||||
|
maxSmallObjectSize, objectAlignSize, LifetimePolicy >
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
inline SmallValueObject( void ) {}
|
||||||
|
inline SmallValueObject( const SmallValueObject & ) {}
|
||||||
|
inline SmallValueObject & operator = ( const SmallValueObject & ) {}
|
||||||
|
inline ~SmallValueObject() {}
|
||||||
|
}; // end class SmallValueObject
|
||||||
|
|
||||||
} // namespace Loki
|
} // namespace Loki
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -163,3 +261,7 @@ namespace Loki
|
||||||
|
|
||||||
#endif // SMALLOBJ_INC_
|
#endif // SMALLOBJ_INC_
|
||||||
|
|
||||||
|
// $Log$
|
||||||
|
// Revision 1.2 2005/07/22 00:22:38 rich_sposato
|
||||||
|
// Added SmallValueObject, SmallObjectBase, and AllocatorSingleton classes.
|
||||||
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue