#ifndef __MEMORYPOOLFACTORY_H__ #define __MEMORYPOOLFACTORY_H__ // MemoryPoolFactory.h: interface for the CMemoryPoolFactory class. // Memory Pool Management Class version 1.01 // source code created by Min-Wook Kim (taiyo@webzen.co.kr) // 2004-1-10 // //------------------------------------------------------------------- // History. // 2004-3-31 : MemoryPoolTempl class ver 0.1 // 2004-6-18 : MemoryPoolTempl class ver 0.2 // 2004-6-21 : Error Check Byte added ver 0.21 // 2004-7-26 : MemoryPool Framework ver1.0 // 2005-1-10 : SafeMemoryPoolFactory class added 1.01 // 2005-3-28 : set default value as dwPoolExtendSize = dwPoolBasicSize/2+1 // Be Done // - MemoryPool template class of inherited-method and factory-method // - Multi-thread safety // - Buffer overflow write check // To do // - Analysis of amount used for band // - alloc() for various data type //------------------------------------------------------------------- // example) // // 1. Thread-NonSafetyPool sample code // class Money1 { ... }; // // void main() // { // CMemoryPoolFactory * pool = new CMemoryPoolFactory; // pool->Initialize( 10000, 510 ); // // Money1 * pmoney11 = pool->Alloc(); // pool->Free(pmoney11); // // pool->Release(); // } // // 2. Thread-SafetyPool sample code // class Money1 { ... }; // // void main() // { // SafeMemoryPoolFactory * pool = new SafeMemoryPoolFactory; //!!!!!!!! different thing !!!!!!! // pool->Initialize( 10000, 510 ); // // Money1 * pmoney11 = pool->Alloc(); // pool->Free(pmoney11); // // pool->Release(); // } // // error situation) // If (m_pFreeBand of m_pFreeBand->pNext) is NULL in Free() function, // =>possibility // 1. Free()À» Alloc()È£ÃâÇÑ È½¼öÀÌ»óÀ» È£ÃâÇßÀ» ¶§ // 2. ¶Ç´Â Free(node)ÀÇ node°¡ Áߺ¹µÇ°Ô FreeµÇ¾úÀ» ¶§ ////////////////////////////////////////////////////////////////////// #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "PublicDefine.h" #include "MemBand.h" #include //-------------------------------------------------------------------------------- #define __DECL_CUSTOMPOOL_PTR(_ClassType) \ typedef util::CMemoryPoolFactory<_ClassType> * CUSTOM_POOL_PTR; \ private: \ static CUSTOM_POOL_PTR s_pPool; \ public: \ static VOID SetPool( CUSTOM_POOL_PTR spPool ) { s_pPool = spPool; } \ static _ClassType * ALLOC() { return s_pPool->Alloc(); } \ static VOID FREE( _ClassType * pClass ) { s_pPool->Free( pClass ); } // static VOID DisplayerPoolInfo() \ //{ \ // DISPMSG( "[%4u,%4u][band:%u node:%u]", s_pPool->GetPoolBasicSize(), s_pPool->GetPoolExtendSize(), \ // s_pPool->GetNumberOfBands(), s_pPool->GetAvailableNumberOfTypes() ); \ //} #define __IMPL_CUSTOMPOOL_PTR(_ClassType) \ _ClassType::CUSTOM_POOL_PTR _ClassType::s_pPool = NULL; //-------------------------------------------------------------------------------- namespace util { template class CMemoryPoolFactory { public: CMemoryPoolFactory() : m_pBandHead( NULL ), m_pFreeBand( NULL ), m_dwPoolExtendSize( 0 ) { } virtual ~CMemoryPoolFactory() { Release(); } BOOL Initialize( DWORD dwPoolBasicSize, DWORD dwPoolExtendSize = 0 ) { if( 0 == dwPoolExtendSize ) m_dwPoolExtendSize = dwPoolBasicSize/2+1; else m_dwPoolExtendSize = dwPoolExtendSize; if( NULL == m_pBandHead ) { CMemTypeBand::AllocBand( m_pBandHead, dwPoolBasicSize ); m_pFreeBand = m_pBandHead; if( !m_pFreeBand ) return FALSE; return TRUE; } return FALSE; } void Release() { if( m_pBandHead ) { CMemTypeBand::FreeBand( m_pBandHead ); //m_pBandHead->FreeBand(); m_pBandHead = NULL; m_pFreeBand = NULL; } } inline Type * Alloc() { Type * pn = m_pFreeBand->AlloObject(); if(pn == NULL) { if( !m_pFreeBand->pPrev ) { CMemTypeBand::AllocBand( m_pBandHead, m_dwPoolExtendSize ); m_pFreeBand = m_pBandHead; pn = m_pFreeBand->AlloObject(); } else { m_pFreeBand = m_pFreeBand->pPrev; pn = m_pFreeBand->AlloObject(); } } UASSERT( !IsBadReadPtr( pn, sizeof(Type) ) ); UASSERT( !IsBadWritePtr( pn, sizeof(Type) ) ); return pn; } inline BOOL Free(Type * pNode) { UASSERT( !IsBadReadPtr( pNode, sizeof(Type) ) ); UASSERT( !IsBadWritePtr( pNode, sizeof(Type) ) ); if(!m_pFreeBand->FreeObject(pNode)) { if( !m_pFreeBand->pNext ) { printf( "¹ÝȯÀ» ¸¹ÀÌ Çß´Ù.\n" ); return FALSE; } m_pFreeBand = m_pFreeBand->pNext; if(!m_pFreeBand->FreeObject(pNode)) //< ¿©±â¼­ »¶ ³¯°æ¿ì ( m_pFreeBand == NULL ), °³¼ö ÀÌ»óÀÇ pNode¸¦ ¹ÝȯÇÏ¿© »ý±è { return FALSE; } } return TRUE; } inline DWORD GetPoolBasicSize() { CMemTypeBand * pHead = m_pBandHead; CMemTypeBand * ptmpHead = NULL; while(pHead) { ptmpHead = pHead; pHead = pHead->pNext; } if( ptmpHead ) return ptmpHead->GetMaxNumberOfObjects(); return 0; } inline DWORD GetPoolExtendSize() { return m_dwPoolExtendSize; } inline DWORD GetNumberOfBands() { DWORD dwTotalNum = 0; CMemTypeBand * pHead = m_pBandHead; while( pHead ) { ++dwTotalNum; pHead = pHead->pNext; } return dwTotalNum; } inline DWORD GetAvailableNumberOfTypes() { DWORD dwTotalNum = 0; CMemTypeBand * pHead = m_pBandHead; while(pHead) { dwTotalNum += pHead->GetAvailableNumberOfObjects(); pHead = pHead->pNext; } return dwTotalNum; } protected: CMemTypeBand * m_pBandHead; CMemTypeBand * m_pFreeBand; DWORD m_dwPoolExtendSize; }; } /// namespace util #endif //__MEMORYPOOLFACTORY_H__