/** * @file NFMemPool.h * @brief Packet Memory °ü¸®°´Ã¼ * @remarks * @author °­µ¿¸í(edith2580@gmail.com) * @date 2009-05-09 */ #pragma once #include #include namespace NaveServer { #pragma pack(push, struct_packing_before) #pragma pack(1) /** * @class NFMemPool * @brief IOCP¿¡¼­ »ç¿ëÇÒ ÆÐŶ ¹öÆÛ¸¦ °ü¸®ÇÒ ¸Þ¸ð¸®Pool Ŭ·¡½º * @remarks * * @par * @author Edith * @date 2009-08-28 */ template class NFMemPool { public: /// ÇÒ´ç ¹ÞÀ» °¹¼ö¿Í ¹öÆÛ »çÀÌÁî ÀÔ·Â NFMemPool(INT nTotalCnt, INT nAllocBufferSize=0); /// ÇÒ´ç ÇØÁ¦ ó¸® ~NFMemPool(); /** * @brief ·Î±×ÆÄÀÏÀÇ À̸§À» °áÁ¤ÇÕ´Ï´Ù. * @param strLogTitle ·Î±×ÀÇ À̸§ */ VOID SetLogTitle(WCHAR* strLogTitle) { wcscpy(m_strLogTitle, strLogTitle); } /// ÇöÀç ÇÒ´ç ¹ÞÀº ¼ö INT GetCount(); /// ºñ¾î ÀÖ´Â ÆÐŶ ¼ö INT GetEmpty(); /// ¹öÆÛ¿¡ µû¸¥ À妽º ¾ò±â INT GetIndex( TYPE *ptr ); /// ÇÒ´çµÈ ÆÐŶÁß ºó ÆÐŶ ¹Ýȯ TYPE* Alloc(); /// ÇÒ´ç ¹ÞÀº ¸Þ¸ð¸®¸¦ ÇØÁ¦ BOOL Free( TYPE *ptr ); private: /// INDEX Structure struct INDEX { /// ´ÙÀ½ Index Æ÷ÀÎÅ͸¦ °¡Áø´Ù INDEX* pNext; /// ÇöÀç À妽º ¹øÈ£ INT nIndex; /// Structure constructure INDEX(){ pNext = NULL; nIndex = 0; } }; private: /// ÇöÀç ÇÒ´ç ¹ÞÀº ¼ö INT m_nCount; /// ¸¸µé¾îÁø ÇÒ´ç ÆÐŶ ¼ö INT m_nTotalCnt; /// ÇÑ ÆÐŶ´ç ÇÒ´ç ¹ÞÀº ¹öÆÛ »çÀÌÁî INT m_nAllocBufferSize; /// ÇÑ ÆÐŶ´ç Àüü »çÀÌÁî INT m_nPerPacketSize; /// ·Î±×ÆÄÀÏ À̸§ WCHAR m_strLogTitle[32]; /// Àüü ÇÒ´ç Æ÷ÀÎÅÍ PVOID m_pPakets; /// ÇöÀç ºñ¾îÀִ ó¸® À妽º Æ÷ÀÎÅÍ INDEX* m_pFreeRoom; Nave::NFSync m_Sync; }; #pragma pack( pop, struct_packing_before ) template NFMemPool::NFMemPool( INT nTotalCnt, INT nAllocBufferSize ) { assert( nTotalCnt > 0 ); m_nCount = 0; m_pFreeRoom = NULL; m_pPakets = NULL; m_nTotalCnt = nTotalCnt; // MAXUSER * 2 m_nAllocBufferSize = nAllocBufferSize; // 1024 + 64 m_nPerPacketSize = sizeof(INDEX) + sizeof(TYPE) + m_nAllocBufferSize; m_pPakets = VirtualAlloc( NULL, m_nTotalCnt * m_nPerPacketSize, MEM_RESERVE | MEM_COMMIT, // reserve and commit PAGE_READWRITE ); ////////////////////////////////////////////////////////// // < ÇÒ´ç µ¥ÀÌŸ ºí·°µµ > // // // // ----------------------------------------------- // // | INDEX | TYPE | m_nExBlockSize | // // ----------------------------------------------- // ////////////////////////////////////////////////////////// assert( m_pPakets ); INDEX* pIndex = (INDEX*) m_pPakets; assert( pIndex ); ////////////////////////////////////////// // init linear linked list for buffer pool // ÇÒ´ç µ¥ÀÌŸ ±¸Á¶ ¸Ç ¸¶Áö¸· ´ÜÀ§ÀÇ Æ÷ÀÎÅÍ ¾ò±â pIndex = (INDEX*) ((DWORD)pIndex + (m_nTotalCnt - 1) * m_nPerPacketSize); // ÇÒ´ç µ¥ÀÌŸ ±¸Á¶ÀÇ ¸¶Áö¸· ºÎÅÍ Linked List¸¦ ±¸¼ºÇÏ¿© ¿Ã¶ó¿À±â for( INT i = m_nTotalCnt-1; i >= 0; i-- ) { pIndex->pNext = m_pFreeRoom; // ¸Ç ¸¶Áö¸·ÀÇ pNext = NULLÀÌ´Ù pIndex->nIndex = i; // INDEX ÀÛ¾÷ m_pFreeRoom = pIndex; // ´ÙÀ½ ¿¬°áÀ» À§ÇÑ ¼¼ÆÃ #ifdef _DEBUG // °¢ ºí·° ¸¶´Ù ExBlockSizeÀÇ ºÎºÐ¿¡ µ¥ÀÌŸ ¼¼ÆÃ ÀÛ¾÷ if( m_nAllocBufferSize ) memset((PVOID)( (DWORD)pIndex+sizeof(INDEX)+sizeof(TYPE)), (i%10+'0'), m_nAllocBufferSize ); #endif // ´ÙÀ½ ¸®½ºÆ®·Î C8List Æ÷ÀÎÆ® À̵¿ pIndex = (INDEX*)((DWORD)pIndex - m_nPerPacketSize); } } template NFMemPool::~NFMemPool() { if(NULL != m_pPakets) VirtualFree( m_pPakets, 0, MEM_RELEASE ); } template TYPE* NFMemPool::Alloc() { // º¯¼ö ÃʱâÈ­ INDEX* pIndex = NULL; TYPE* pType = NULL; Nave::NFSyncLock CL(&m_Sync); pIndex = m_pFreeRoom; if( pIndex != NULL ) { // ºó°ø°£ À̵¿ À妽º Æ÷ÀÎÅ͸¦ ´ÙÀ½ À妽º·Î À̵¿ m_pFreeRoom = m_pFreeRoom->pNext; m_nCount++; // Ä«¿îÆ® Áõ°¡ // ÁöÁ¤ÇÑ À妽º Æ÷ÀÎÅÍ¿¡¼­ ÅÛÇø´ ŸÀÔ À§Æ¼ Æ÷ÀÎÅÍ ¹Ýȯ pType = (TYPE*)(pIndex+1); /////////////////////////////////////////// // Ä¡¸íÀûÀÎ ¿¡·¯ ¹ß»ý // assert( m_nCount > 0 ); // make sure we don't overflow if(m_nCount > m_nTotalCnt) { LOG_ERROR((L"[%s] MemPool Alloc Overflow Count(%d) >= %d", m_strLogTitle, m_nCount, m_nTotalCnt)); return NULL; } } else LOG_ERROR((L"[%s] MemPool Alloc m_pFreeRoom = NULL, Count(%d)", m_strLogTitle, m_nCount)); return pType; // ÅÛÇø´ ŸÀÔ ¹Ýȯ } template BOOL NFMemPool::Free( TYPE *ptr ) { Nave::NFSyncLock CL(&m_Sync); BOOL bRet = FALSE; INDEX* pIndex = ((INDEX*)(ptr))-1; // »ç¿ë ÆÐŶÀÇ À妽º Æ÷ÀÎÅÍ ¾ò±â // »ç¿ëÁßÀÎ ÆÐŶÀÌ ÀÖ´Ù¸é if( m_nCount > 0 ) { // ºó°ø°£ À妽º Æ÷ÀÎÅ͸¦ ¾ÕÀ¸·Î ´ç±â´Â ·çƾ pIndex->pNext = m_pFreeRoom; m_pFreeRoom = pIndex; m_nCount--; // »ç¿ë ÆÐŶ¼ö 1 °¨¼Ò bRet = TRUE; // Á¤»ó ó¸® ¾Ë¸² } else LOG_ERROR((L"[%s] MemPool Free Faild Count(%d) <= 0", m_strLogTitle, m_nCount)); return bRet; // Á¤»ó ó¸® À¯¹« ¹Ýȯ } template INT NFMemPool::GetCount() { Nave::NFSyncLock CL(&m_Sync); INT nRet = m_nCount; // º¯¼ö ¼³Á¤ return nRet; // ¹Ýȯ } template INT NFMemPool::GetEmpty() { Nave::NFSyncLock CL(&m_Sync); INT nRet = m_nTotalCnt - m_nCount; // ¼³Á¤ return nRet; // ¹Ýȯ } template INT NFMemPool::GetIndex( TYPE *ptr ) { Nave::NFSyncLock CL(&m_Sync); INT nRet = 0; // º¯¼ö ÃʱâÈ­ INDEX* pIndex = ((INDEX*)(ptr))-1; // Àε¥½º Æ÷ÀÎÅÍ ¾ò±â nRet = pIndex->nIndex; // º¯¼ö ¼³Á¤ return nRet; // ¹Ýȯ } }