内存池的一种实现
2012-05-30 13:52
274 查看
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include "Const.h"
#include "UtilityFunc.h"
#include "hashtable.h"
#include "logmsg.h"
#define SYSTEM_PAGE_SIZE 4096
#define DEFAULT_MAX_NUM 128
typedef enum EnumMemPoolOper // 对内存池的4种操作
{
MEMPOOL_MAX_NUM = 0, // 内存池总数
MEMPOOL_CURR_USED = 1, // 当前使用数
MEMPOOL_GET_SUCC = 2, // Get成功
MEMPOOL_GET1_FAIL = 3, // Get失败
MEMPOOL_GET2_FAIL = 4, // Get失败
MEMPOOL_PUT_SUCC = 5, // Put成功
MEMPOOL_PUT_NULL = 6, // Put失败
MEMPOOL_PUT1_FAIL = 7, // Put失败
MEMPOOL_PUT2_FAIL = 8, // Put失败
MEMPOOL_TOTAL_SIZE = 9, // 内存池的字节大小
MEMPOOL_DATA_SIZE = 10, // 每个池子的数据大小
MEMPOOL_POOL_COUNT = 11, // 池子个数
MEMPOOL_OPER_COUNT = 12 // 仅为计数
}EnumMemPoolOper;
extern bool g_bCollectorStarted;
template <class T>
class MemPoolCls
{
public:
MemPoolCls();
~MemPoolCls();
void enableDebug();
void setMaxNum(int maxNum, bool bPreAlloc=false);
// int getMaxNum() { return m_intMaxNum; };
// int getUsedNum() { return m_currPos; };
// int getSize() { return m_intMaxNum*sizeof(T); };
T* getMem();
bool recycleMem(T* pClsMem);
// void printAll();
unsigned long getRecycleFailedNum() { return (m_ulMemAccess[MEMPOOL_PUT1_FAIL] + m_ulMemAccess[MEMPOOL_PUT2_FAIL]); };
unsigned long* getMemAccess() { return m_ulMemAccess; };
protected:
void initMemPool();
T** m_ppMemPool;
int m_intMaxNum;
int m_currPos;
int m_intRecNum;
//sem_t m_semMemPool;
pthread_mutex_t m_mutex;
bool m_bPreAlloc;
bool m_bLogGet1Fail;
bool m_bLogPut1Fail;
unsigned long m_ulMemAccess[MEMPOOL_OPER_COUNT];
// 调试信息
bool DEBUG_MEMPOOL;
HashTableCls *m_mapAllPtr; // 存储所有指针
unsigned char *m_pUsedFlag;
};
template<class T>
MemPoolCls<T>::~MemPoolCls()
{
if(m_ppMemPool)
{
if( m_bPreAlloc )
{
if(m_ppMemPool[0])
free(m_ppMemPool[0]);
}
else
{
for(int i = 0 ; i < m_intMaxNum ; i++)
{
delete m_ppMemPool[i];
}
}
free(m_ppMemPool);
}
}
template<class T>
MemPoolCls<T>::MemPoolCls()
{
m_intMaxNum = DEFAULT_MAX_NUM;
//sem_init(&m_semMemPool, 0, 1);
pthread_mutex_init (&m_mutex, NULL);
m_ppMemPool = NULL;
m_currPos = 0;
m_intRecNum = 0;
DEBUG_MEMPOOL = false;
m_mapAllPtr = NULL;
m_pUsedFlag = NULL;
m_bPreAlloc = false;
m_bLogGet1Fail = false;
m_bLogPut1Fail = false;
bzero(m_ulMemAccess, sizeof(m_ulMemAccess));
m_ulMemAccess[MEMPOOL_DATA_SIZE] = sizeof(T);
}
template<class T>
void MemPoolCls<T>::enableDebug()
{
DEBUG_MEMPOOL = true;
m_mapAllPtr = new HashTableCls(1024000);
}
template<class T>
void MemPoolCls<T>::setMaxNum(int maxNum, bool bPreAlloc)
{
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
m_intMaxNum = maxNum;
m_ulMemAccess[MEMPOOL_MAX_NUM] = maxNum;
m_ulMemAccess[MEMPOOL_TOTAL_SIZE] = m_intMaxNum * sizeof(T);
//m_bPreAlloc = true;
m_bPreAlloc = bPreAlloc;
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
if(!m_ppMemPool)
initMemPool();
}
template<class T>
void MemPoolCls<T>::initMemPool()
{
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
m_ppMemPool = (T**)calloc(sizeof(T*),m_intMaxNum);
char strInfo[100] = "";
// 2011-02-18 理论上不应该出现
if ( g_bCollectorStarted )
{
snprintf(strInfo, 100, "initMemPool %u\n", m_intMaxNum);
LOG(LOGTYPE_ERROR, strInfo);
}
m_ulMemAccess[MEMPOOL_TOTAL_SIZE] = m_intMaxNum * sizeof(T);
pair<ITERTYPE_IP, bool> rslt;
///////////////////////////////////////////////////////////////////////////
// for heap memory alloc test.
//
if( m_bPreAlloc )
{
T* pStartBuffer = NULL;
//calculate the total bytes and round it to multiple of system page size.
unsigned long MemSize = m_intMaxNum * sizeof(T);
MemSize = MemSize / SYSTEM_PAGE_SIZE * SYSTEM_PAGE_SIZE + SYSTEM_PAGE_SIZE;
try
{
pStartBuffer = (T*)malloc(MemSize);//PAGE_NOACCESS);
if( pStartBuffer == NULL )
{
printf("VM alloc failed!\n");
exit(-1);
}
}
catch( ... )
{
//STATUS_NO_MEMORY
//STATUS_ACCESS_VIOLATION
for(int i = 0 ; i < m_intMaxNum ; i++)
{
m_ppMemPool[i] = NULL;
}
m_currPos = 0;
m_intRecNum = 0;
//e->Delete();
printf( " Sys mem alloc fail! exiting ... " );
getchar();
exit(-1);
//return;
}
for(int i = 0 ; i < m_intMaxNum ; i++)
{
m_ppMemPool[i] = pStartBuffer;
// if ( DEBUG_MEMPOOL )
// {
// rslt = m_mapAllPtr.insert( VT_IP((unsigned long)pStartBuffer, NULL) );
// if ( !rslt.second )
// {
// ;
// }
// }
++pStartBuffer;
//test to see if we've got want we want.
try
{
memset(m_ppMemPool[i], 0, sizeof(T));
}
catch(...)
{
printf("Init mem failed! Please lower mem allocated.\n");
exit(-1);
}
}
m_currPos = 0;
m_intRecNum = 0;
// // dyn
// int m, n;
// for(m = 0 ; m < m_intMaxNum-1 ; m++)
// for(n = m+1 ; n < m_intMaxNum ; n++)
// if( m_ppMemPool[m] == m_ppMemPool
)
// printf( "Init Mem Dup! %d %d\n", m, n );
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
return;
}
///////////////////////////////////////////////////////////////////////////
void *pTemp = NULL;
int nTemp = 0;
for(int i = 0 ; i < m_intMaxNum ; i++)
{
m_ppMemPool[i] = new T;
bzero(m_ppMemPool[i], sizeof(T));
// 2011-02-21 记录地址和i的对应关系, [0]空出来
if ( DEBUG_MEMPOOL )
{
nTemp = i+1;
pTemp = m_mapAllPtr->insertItem( (UCHAR*)(&m_ppMemPool[i]), 4, (void*)nTemp );
if ( NULL == pTemp )
{
snprintf(strInfo, 100, "mempool insertitem fail : 0x%X-%u-%u\n", m_ppMemPool[i], m_intMaxNum, nTemp);
LOG(LOGTYPE_ERROR, strInfo);
exit(-1); // for debug
}
// 记录所有的指针
sprintf(strInfo, "%d, 0x%X\n", nTemp, m_ppMemPool[i]);
LOG(LOGTYPE_ERROR, strInfo);
}
}
// 2011-02-21 生成i的bitmap,表示是否被分配出去
if ( DEBUG_MEMPOOL )
{
int nTemp = 0;
if ( 0 == (m_intMaxNum % 8) )
{
nTemp = m_intMaxNum / 8 + 1;
m_pUsedFlag = new unsigned char[nTemp];
}
else
{
nTemp = m_intMaxNum / 8 + 2;
m_pUsedFlag = new unsigned char[nTemp];
}
bzero(m_pUsedFlag, nTemp);
}
m_currPos = 0;
m_intRecNum = 0;
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
}
template<class T>
T* MemPoolCls<T>::getMem()
{
if(!m_ppMemPool)
initMemPool();
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
char strInfo[200] = "";
unsigned long nOrg = 0;
unsigned char ucTemp = 0;
unsigned char ucMask = 0;
int nByte = 0;
int nBit = 0;
// // dyn
// int m, n;
// for(m = m_currPos ; m < m_intMaxNum-1 ; m++)
// for(n = m+1 ; n < m_intMaxNum ; n++)
// if( m_ppMemPool[m] == m_ppMemPool
)
// printf( "Get Mem Dup! %d %d\n", m, n );
T *pTemp = NULL;
if(m_currPos < m_intMaxNum)
{
pTemp = m_ppMemPool[m_currPos];
// 2011-01-15 ???? 为什么会出现这种请况?
if ( NULL == pTemp )
{
if ( !m_bLogGet1Fail )
{
m_bLogGet1Fail = true;
snprintf(strInfo, 100, "mempool get null : %u--%u(0x%X)\n", m_intMaxNum, m_currPos, m_ppMemPool[m_currPos]);
LOG(LOGTYPE_ERROR, strInfo);
//appendDebugInfo(0, strInfo);
// 输出所有内存池地址
// printAll();
}
m_ulMemAccess[MEMPOOL_GET1_FAIL]++;
goto FUNCTION_EXIT;
}
//bzero(pTemp, sizeof(T));
// 确保不被别人使用
if ( DEBUG_MEMPOOL )
{
nOrg = (unsigned long)m_mapAllPtr->lookupItem( (UCHAR*)&pTemp, 4 );
if ( 0 == nOrg )
{
snprintf(strInfo, 100, "mempool get fail: %u, %u, 0x%X\n", m_intMaxNum, m_currPos, m_ppMemPool[m_currPos]);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
m_ulMemAccess[MEMPOOL_GET1_FAIL]++;
pTemp = NULL;
goto FUNCTION_EXIT;
}
nByte = nOrg / 8 + 1;
nBit = nOrg % 8;
ucTemp = *(m_pUsedFlag + nByte);
ucMask = (ucTemp >> nBit) & 0x01;
if ( 0 == ucMask )
{
// 标志已经被分配出去了
*(m_pUsedFlag + nByte) |= (1<<nBit);
}
else
{
snprintf(strInfo, 100, "mempool reused : %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit, ucMask, m_ppMemPool[m_currPos]);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
// 死循环用于调试
printf("getMem endless loop\n");
while(1)
{
sleep(10);
}
m_ulMemAccess[MEMPOOL_GET1_FAIL]++;
pTemp = NULL;
goto FUNCTION_EXIT;
}
}
if ( DEBUG_MEMPOOL )
{
ucTemp = *(m_pUsedFlag + nByte); // 新的标志
ucMask = (ucTemp >> nBit) & 0x01;
sprintf(strInfo, "get mem : %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit,ucMask, m_ppMemPool[m_currPos]);
appendDebugInfo(0, strInfo);
}
m_ppMemPool[m_currPos] = NULL;
m_currPos = m_currPos + 1;
m_ulMemAccess[MEMPOOL_GET_SUCC]++;
m_ulMemAccess[MEMPOOL_CURR_USED] = m_currPos;
}
else
{
m_ulMemAccess[MEMPOOL_GET2_FAIL]++;
}
FUNCTION_EXIT:
if ( NULL == pTemp )
{
if( !m_bPreAlloc )
{
//printf("f");
//pTemp = new T; 2005/6/20 Never allocate! WangWei.
}
}
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
return pTemp;
}
template<class T>
bool MemPoolCls<T>::recycleMem(T* pClsMem)
{
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
bool bRet = false; // 方便在 MemFactoryCls中进行调试, 因为 .h 不好断点
char strInfo[200];
unsigned long ulTemp = (unsigned long)pClsMem;
unsigned long nOrg = 0;
unsigned char ucTemp = 0;
unsigned char ucMask = 0;
int nByte = 0;
int nBit = 0;
if ( NULL == pClsMem )
{
m_ulMemAccess[MEMPOOL_PUT_NULL]++;
bRet = false;
goto FUNCTION_EXIT;
}
// 确保是已经分配出去的
if ( DEBUG_MEMPOOL )
{
nOrg = (unsigned long)m_mapAllPtr->lookupItem( (UCHAR*)&ulTemp, sizeof(long) );
if ( 0 == nOrg )
{
snprintf(strInfo, 100, "mempool del fail: %u, %u, 0x%X\n", m_intMaxNum, m_currPos, nOrg);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
m_ulMemAccess[MEMPOOL_PUT1_FAIL]++;
goto FUNCTION_EXIT;
}
nByte = nOrg / 8 + 1;
nBit = nOrg % 8;
ucTemp = *(m_pUsedFlag + nByte);
ucMask = (ucTemp >> nBit) & 0x01;
if ( 1 == ucMask )
{
// 标志未被使用
*(m_pUsedFlag + nByte) &= ~(1<<nBit);
}
else
{
snprintf(strInfo, 100, "mempool recycle notused: %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit, ucMask, ulTemp);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
// 死循环用于调试
while(1)
{
printf("recycleMem endless loop\n");
sleep(10);
}
m_ulMemAccess[MEMPOOL_PUT1_FAIL]++;
goto FUNCTION_EXIT;
}
}
// // dyn
// int m;
// for(m = 0 ; m < m_intMaxNum ; m++)
// if( m_ppMemPool[m] != NULL && m_ppMemPool[m] == pClsMem)
// printf( "Recycle Mem Dup! %d\n", m );
if(m_currPos != 0 )
{
if ( NULL == m_ppMemPool[m_currPos-1] )
{
bRet = true;
}
else
{
if ( !m_bLogPut1Fail )
{
m_bLogPut1Fail = true;
sprintf(strInfo, "mempool recycle fail: %u, %u, 0x%X -- %u(0x%X)\n", m_currPos, nOrg, pClsMem, m_currPos-1, m_ppMemPool[m_currPos-1]);
LOG(LOGTYPE_ERROR, strInfo);
//appendDebugInfo(0, strInfo);
// 输出所有内存池地址
// printAll();
}
m_ulMemAccess[MEMPOOL_PUT1_FAIL]++;
bRet = false;
}
}
else
{
sprintf(strInfo, "mempool recycle error: %d, %d, 0x%X\n", m_currPos, nOrg, pClsMem);
LOG(LOGTYPE_ERROR, strInfo);
//appendDebugInfo(0, strInfo);
m_ulMemAccess[MEMPOOL_PUT2_FAIL]++;
bRet = false;
//if( !m_bPreAlloc )
//delete pClsMem; 2005/6/20 Never allocate! WangWei.
}
if ( bRet )
{
m_currPos = m_currPos - 1 ;
m_ppMemPool[m_currPos] = pClsMem;
m_ulMemAccess[MEMPOOL_PUT_SUCC]++;
m_ulMemAccess[MEMPOOL_CURR_USED] = m_currPos;
if ( DEBUG_MEMPOOL )
{
ucTemp = *(m_pUsedFlag + nByte);
ucMask = (ucTemp >> nBit) & 0x01;
sprintf(strInfo, "delete mem : %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit, ucMask, pClsMem);
appendDebugInfo(0, strInfo);
}
bzero(pClsMem, sizeof(T));
}
FUNCTION_EXIT:
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
return bRet;
}
//template<class T>
//void MemPoolCls<T>::printAll()
//{
// // 输出所有内存池地址
// int m = 0;
// int k = 0;
// char strTemp[300] = {0};
//
// for ( m = 0; m < m_intMaxNum; m++ )
// {
// if ( 0 == (m+1)%10 )
// {
// strTemp[0] = 0;
// k = 0;
// }
// k += sprintf(strTemp + k, "%8X ", m_ppMemPool[m]);
//
// if ( 0 == (m+1)%10 )
// {
// strcat(strTemp, "\n");
// LOG(LOGTYPE_ERROR, strTemp);
// }
// }
//}
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include "Const.h"
#include "UtilityFunc.h"
#include "hashtable.h"
#include "logmsg.h"
#define SYSTEM_PAGE_SIZE 4096
#define DEFAULT_MAX_NUM 128
typedef enum EnumMemPoolOper // 对内存池的4种操作
{
MEMPOOL_MAX_NUM = 0, // 内存池总数
MEMPOOL_CURR_USED = 1, // 当前使用数
MEMPOOL_GET_SUCC = 2, // Get成功
MEMPOOL_GET1_FAIL = 3, // Get失败
MEMPOOL_GET2_FAIL = 4, // Get失败
MEMPOOL_PUT_SUCC = 5, // Put成功
MEMPOOL_PUT_NULL = 6, // Put失败
MEMPOOL_PUT1_FAIL = 7, // Put失败
MEMPOOL_PUT2_FAIL = 8, // Put失败
MEMPOOL_TOTAL_SIZE = 9, // 内存池的字节大小
MEMPOOL_DATA_SIZE = 10, // 每个池子的数据大小
MEMPOOL_POOL_COUNT = 11, // 池子个数
MEMPOOL_OPER_COUNT = 12 // 仅为计数
}EnumMemPoolOper;
extern bool g_bCollectorStarted;
template <class T>
class MemPoolCls
{
public:
MemPoolCls();
~MemPoolCls();
void enableDebug();
void setMaxNum(int maxNum, bool bPreAlloc=false);
// int getMaxNum() { return m_intMaxNum; };
// int getUsedNum() { return m_currPos; };
// int getSize() { return m_intMaxNum*sizeof(T); };
T* getMem();
bool recycleMem(T* pClsMem);
// void printAll();
unsigned long getRecycleFailedNum() { return (m_ulMemAccess[MEMPOOL_PUT1_FAIL] + m_ulMemAccess[MEMPOOL_PUT2_FAIL]); };
unsigned long* getMemAccess() { return m_ulMemAccess; };
protected:
void initMemPool();
T** m_ppMemPool;
int m_intMaxNum;
int m_currPos;
int m_intRecNum;
//sem_t m_semMemPool;
pthread_mutex_t m_mutex;
bool m_bPreAlloc;
bool m_bLogGet1Fail;
bool m_bLogPut1Fail;
unsigned long m_ulMemAccess[MEMPOOL_OPER_COUNT];
// 调试信息
bool DEBUG_MEMPOOL;
HashTableCls *m_mapAllPtr; // 存储所有指针
unsigned char *m_pUsedFlag;
};
template<class T>
MemPoolCls<T>::~MemPoolCls()
{
if(m_ppMemPool)
{
if( m_bPreAlloc )
{
if(m_ppMemPool[0])
free(m_ppMemPool[0]);
}
else
{
for(int i = 0 ; i < m_intMaxNum ; i++)
{
delete m_ppMemPool[i];
}
}
free(m_ppMemPool);
}
}
template<class T>
MemPoolCls<T>::MemPoolCls()
{
m_intMaxNum = DEFAULT_MAX_NUM;
//sem_init(&m_semMemPool, 0, 1);
pthread_mutex_init (&m_mutex, NULL);
m_ppMemPool = NULL;
m_currPos = 0;
m_intRecNum = 0;
DEBUG_MEMPOOL = false;
m_mapAllPtr = NULL;
m_pUsedFlag = NULL;
m_bPreAlloc = false;
m_bLogGet1Fail = false;
m_bLogPut1Fail = false;
bzero(m_ulMemAccess, sizeof(m_ulMemAccess));
m_ulMemAccess[MEMPOOL_DATA_SIZE] = sizeof(T);
}
template<class T>
void MemPoolCls<T>::enableDebug()
{
DEBUG_MEMPOOL = true;
m_mapAllPtr = new HashTableCls(1024000);
}
template<class T>
void MemPoolCls<T>::setMaxNum(int maxNum, bool bPreAlloc)
{
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
m_intMaxNum = maxNum;
m_ulMemAccess[MEMPOOL_MAX_NUM] = maxNum;
m_ulMemAccess[MEMPOOL_TOTAL_SIZE] = m_intMaxNum * sizeof(T);
//m_bPreAlloc = true;
m_bPreAlloc = bPreAlloc;
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
if(!m_ppMemPool)
initMemPool();
}
template<class T>
void MemPoolCls<T>::initMemPool()
{
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
m_ppMemPool = (T**)calloc(sizeof(T*),m_intMaxNum);
char strInfo[100] = "";
// 2011-02-18 理论上不应该出现
if ( g_bCollectorStarted )
{
snprintf(strInfo, 100, "initMemPool %u\n", m_intMaxNum);
LOG(LOGTYPE_ERROR, strInfo);
}
m_ulMemAccess[MEMPOOL_TOTAL_SIZE] = m_intMaxNum * sizeof(T);
pair<ITERTYPE_IP, bool> rslt;
///////////////////////////////////////////////////////////////////////////
// for heap memory alloc test.
//
if( m_bPreAlloc )
{
T* pStartBuffer = NULL;
//calculate the total bytes and round it to multiple of system page size.
unsigned long MemSize = m_intMaxNum * sizeof(T);
MemSize = MemSize / SYSTEM_PAGE_SIZE * SYSTEM_PAGE_SIZE + SYSTEM_PAGE_SIZE;
try
{
pStartBuffer = (T*)malloc(MemSize);//PAGE_NOACCESS);
if( pStartBuffer == NULL )
{
printf("VM alloc failed!\n");
exit(-1);
}
}
catch( ... )
{
//STATUS_NO_MEMORY
//STATUS_ACCESS_VIOLATION
for(int i = 0 ; i < m_intMaxNum ; i++)
{
m_ppMemPool[i] = NULL;
}
m_currPos = 0;
m_intRecNum = 0;
//e->Delete();
printf( " Sys mem alloc fail! exiting ... " );
getchar();
exit(-1);
//return;
}
for(int i = 0 ; i < m_intMaxNum ; i++)
{
m_ppMemPool[i] = pStartBuffer;
// if ( DEBUG_MEMPOOL )
// {
// rslt = m_mapAllPtr.insert( VT_IP((unsigned long)pStartBuffer, NULL) );
// if ( !rslt.second )
// {
// ;
// }
// }
++pStartBuffer;
//test to see if we've got want we want.
try
{
memset(m_ppMemPool[i], 0, sizeof(T));
}
catch(...)
{
printf("Init mem failed! Please lower mem allocated.\n");
exit(-1);
}
}
m_currPos = 0;
m_intRecNum = 0;
// // dyn
// int m, n;
// for(m = 0 ; m < m_intMaxNum-1 ; m++)
// for(n = m+1 ; n < m_intMaxNum ; n++)
// if( m_ppMemPool[m] == m_ppMemPool
)
// printf( "Init Mem Dup! %d %d\n", m, n );
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
return;
}
///////////////////////////////////////////////////////////////////////////
void *pTemp = NULL;
int nTemp = 0;
for(int i = 0 ; i < m_intMaxNum ; i++)
{
m_ppMemPool[i] = new T;
bzero(m_ppMemPool[i], sizeof(T));
// 2011-02-21 记录地址和i的对应关系, [0]空出来
if ( DEBUG_MEMPOOL )
{
nTemp = i+1;
pTemp = m_mapAllPtr->insertItem( (UCHAR*)(&m_ppMemPool[i]), 4, (void*)nTemp );
if ( NULL == pTemp )
{
snprintf(strInfo, 100, "mempool insertitem fail : 0x%X-%u-%u\n", m_ppMemPool[i], m_intMaxNum, nTemp);
LOG(LOGTYPE_ERROR, strInfo);
exit(-1); // for debug
}
// 记录所有的指针
sprintf(strInfo, "%d, 0x%X\n", nTemp, m_ppMemPool[i]);
LOG(LOGTYPE_ERROR, strInfo);
}
}
// 2011-02-21 生成i的bitmap,表示是否被分配出去
if ( DEBUG_MEMPOOL )
{
int nTemp = 0;
if ( 0 == (m_intMaxNum % 8) )
{
nTemp = m_intMaxNum / 8 + 1;
m_pUsedFlag = new unsigned char[nTemp];
}
else
{
nTemp = m_intMaxNum / 8 + 2;
m_pUsedFlag = new unsigned char[nTemp];
}
bzero(m_pUsedFlag, nTemp);
}
m_currPos = 0;
m_intRecNum = 0;
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
}
template<class T>
T* MemPoolCls<T>::getMem()
{
if(!m_ppMemPool)
initMemPool();
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
char strInfo[200] = "";
unsigned long nOrg = 0;
unsigned char ucTemp = 0;
unsigned char ucMask = 0;
int nByte = 0;
int nBit = 0;
// // dyn
// int m, n;
// for(m = m_currPos ; m < m_intMaxNum-1 ; m++)
// for(n = m+1 ; n < m_intMaxNum ; n++)
// if( m_ppMemPool[m] == m_ppMemPool
)
// printf( "Get Mem Dup! %d %d\n", m, n );
T *pTemp = NULL;
if(m_currPos < m_intMaxNum)
{
pTemp = m_ppMemPool[m_currPos];
// 2011-01-15 ???? 为什么会出现这种请况?
if ( NULL == pTemp )
{
if ( !m_bLogGet1Fail )
{
m_bLogGet1Fail = true;
snprintf(strInfo, 100, "mempool get null : %u--%u(0x%X)\n", m_intMaxNum, m_currPos, m_ppMemPool[m_currPos]);
LOG(LOGTYPE_ERROR, strInfo);
//appendDebugInfo(0, strInfo);
// 输出所有内存池地址
// printAll();
}
m_ulMemAccess[MEMPOOL_GET1_FAIL]++;
goto FUNCTION_EXIT;
}
//bzero(pTemp, sizeof(T));
// 确保不被别人使用
if ( DEBUG_MEMPOOL )
{
nOrg = (unsigned long)m_mapAllPtr->lookupItem( (UCHAR*)&pTemp, 4 );
if ( 0 == nOrg )
{
snprintf(strInfo, 100, "mempool get fail: %u, %u, 0x%X\n", m_intMaxNum, m_currPos, m_ppMemPool[m_currPos]);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
m_ulMemAccess[MEMPOOL_GET1_FAIL]++;
pTemp = NULL;
goto FUNCTION_EXIT;
}
nByte = nOrg / 8 + 1;
nBit = nOrg % 8;
ucTemp = *(m_pUsedFlag + nByte);
ucMask = (ucTemp >> nBit) & 0x01;
if ( 0 == ucMask )
{
// 标志已经被分配出去了
*(m_pUsedFlag + nByte) |= (1<<nBit);
}
else
{
snprintf(strInfo, 100, "mempool reused : %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit, ucMask, m_ppMemPool[m_currPos]);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
// 死循环用于调试
printf("getMem endless loop\n");
while(1)
{
sleep(10);
}
m_ulMemAccess[MEMPOOL_GET1_FAIL]++;
pTemp = NULL;
goto FUNCTION_EXIT;
}
}
if ( DEBUG_MEMPOOL )
{
ucTemp = *(m_pUsedFlag + nByte); // 新的标志
ucMask = (ucTemp >> nBit) & 0x01;
sprintf(strInfo, "get mem : %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit,ucMask, m_ppMemPool[m_currPos]);
appendDebugInfo(0, strInfo);
}
m_ppMemPool[m_currPos] = NULL;
m_currPos = m_currPos + 1;
m_ulMemAccess[MEMPOOL_GET_SUCC]++;
m_ulMemAccess[MEMPOOL_CURR_USED] = m_currPos;
}
else
{
m_ulMemAccess[MEMPOOL_GET2_FAIL]++;
}
FUNCTION_EXIT:
if ( NULL == pTemp )
{
if( !m_bPreAlloc )
{
//printf("f");
//pTemp = new T; 2005/6/20 Never allocate! WangWei.
}
}
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
return pTemp;
}
template<class T>
bool MemPoolCls<T>::recycleMem(T* pClsMem)
{
//sem_wait(&m_semMemPool);
pthread_mutex_lock (&m_mutex);
bool bRet = false; // 方便在 MemFactoryCls中进行调试, 因为 .h 不好断点
char strInfo[200];
unsigned long ulTemp = (unsigned long)pClsMem;
unsigned long nOrg = 0;
unsigned char ucTemp = 0;
unsigned char ucMask = 0;
int nByte = 0;
int nBit = 0;
if ( NULL == pClsMem )
{
m_ulMemAccess[MEMPOOL_PUT_NULL]++;
bRet = false;
goto FUNCTION_EXIT;
}
// 确保是已经分配出去的
if ( DEBUG_MEMPOOL )
{
nOrg = (unsigned long)m_mapAllPtr->lookupItem( (UCHAR*)&ulTemp, sizeof(long) );
if ( 0 == nOrg )
{
snprintf(strInfo, 100, "mempool del fail: %u, %u, 0x%X\n", m_intMaxNum, m_currPos, nOrg);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
m_ulMemAccess[MEMPOOL_PUT1_FAIL]++;
goto FUNCTION_EXIT;
}
nByte = nOrg / 8 + 1;
nBit = nOrg % 8;
ucTemp = *(m_pUsedFlag + nByte);
ucMask = (ucTemp >> nBit) & 0x01;
if ( 1 == ucMask )
{
// 标志未被使用
*(m_pUsedFlag + nByte) &= ~(1<<nBit);
}
else
{
snprintf(strInfo, 100, "mempool recycle notused: %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit, ucMask, ulTemp);
//LOG(LOGTYPE_ERROR, strInfo);
appendDebugInfo(0, strInfo);
// 死循环用于调试
while(1)
{
printf("recycleMem endless loop\n");
sleep(10);
}
m_ulMemAccess[MEMPOOL_PUT1_FAIL]++;
goto FUNCTION_EXIT;
}
}
// // dyn
// int m;
// for(m = 0 ; m < m_intMaxNum ; m++)
// if( m_ppMemPool[m] != NULL && m_ppMemPool[m] == pClsMem)
// printf( "Recycle Mem Dup! %d\n", m );
if(m_currPos != 0 )
{
if ( NULL == m_ppMemPool[m_currPos-1] )
{
bRet = true;
}
else
{
if ( !m_bLogPut1Fail )
{
m_bLogPut1Fail = true;
sprintf(strInfo, "mempool recycle fail: %u, %u, 0x%X -- %u(0x%X)\n", m_currPos, nOrg, pClsMem, m_currPos-1, m_ppMemPool[m_currPos-1]);
LOG(LOGTYPE_ERROR, strInfo);
//appendDebugInfo(0, strInfo);
// 输出所有内存池地址
// printAll();
}
m_ulMemAccess[MEMPOOL_PUT1_FAIL]++;
bRet = false;
}
}
else
{
sprintf(strInfo, "mempool recycle error: %d, %d, 0x%X\n", m_currPos, nOrg, pClsMem);
LOG(LOGTYPE_ERROR, strInfo);
//appendDebugInfo(0, strInfo);
m_ulMemAccess[MEMPOOL_PUT2_FAIL]++;
bRet = false;
//if( !m_bPreAlloc )
//delete pClsMem; 2005/6/20 Never allocate! WangWei.
}
if ( bRet )
{
m_currPos = m_currPos - 1 ;
m_ppMemPool[m_currPos] = pClsMem;
m_ulMemAccess[MEMPOOL_PUT_SUCC]++;
m_ulMemAccess[MEMPOOL_CURR_USED] = m_currPos;
if ( DEBUG_MEMPOOL )
{
ucTemp = *(m_pUsedFlag + nByte);
ucMask = (ucTemp >> nBit) & 0x01;
sprintf(strInfo, "delete mem : %u, %u, %u(%d,%d,%d), 0x%X\n",
m_currPos, nOrg, ucTemp, nByte, nBit, ucMask, pClsMem);
appendDebugInfo(0, strInfo);
}
bzero(pClsMem, sizeof(T));
}
FUNCTION_EXIT:
//sem_post(&m_semMemPool);
pthread_mutex_unlock (&m_mutex);
return bRet;
}
//template<class T>
//void MemPoolCls<T>::printAll()
//{
// // 输出所有内存池地址
// int m = 0;
// int k = 0;
// char strTemp[300] = {0};
//
// for ( m = 0; m < m_intMaxNum; m++ )
// {
// if ( 0 == (m+1)%10 )
// {
// strTemp[0] = 0;
// k = 0;
// }
// k += sprintf(strTemp + k, "%8X ", m_ppMemPool[m]);
//
// if ( 0 == (m+1)%10 )
// {
// strcat(strTemp, "\n");
// LOG(LOGTYPE_ERROR, strTemp);
// }
// }
//}
相关文章推荐
- 一种高效快速的内存池实现(附源码)
- 一种固定内存池的实现(含代码)
- 基于策略的一种高效内存池的实现
- 一种固定内存池的实现(含代码)
- 一种内存池实现技术和原理
- 内存池的一种简单的实现
- 基于策略的一种高效内存池的实现
- 一种固定内存池的实现(含代码)
- 一种简单定长管理的内存池实现
- 一种固定内存池的实现(C++)
- 一种分割与组合文件的方法-Java实现
- 一种集合“相等性”的实现
- malloc函数的一种简单的原理性实现
- get-element-by-id 转成驼峰式的一种实现
- 实现文件拖放的一种简洁方法
- 浅谈TRACE、ASSERT宏的一种实现
- 观察者模式的一种实现——Caller
- 一种可展开伸缩的tableView实现
- 一种利用线程池线程执行任务, 并能够结束超时任务的方法 (.NET实现)
- 用verilog实现log2的一种方法