读书人

AMPS:内存储器管理模块源码解读(一)

发布时间: 2013-01-28 11:49:56 作者: rapoo

AMPS:内存管理模块源码解读(一)

在AMPS中,使用内存池来管理内存,具体机制见之前的文章《AMPS:内存管理(二)》,在代码中,使用了两种实现方式,第一种是数组+单链表。今天先看看这个方式下的内存池实现。

AMPS_MemoryMgt.h

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <math.h>#include "AMPS_LinkList.h"#include "AMPS_Core.h"#include "AMPS_Defines.h"#include "AMPS_MemMgt.h"t_MemContext* g_poMemContext;int g_nTotalMallocs = 0;int g_nTotalFrees = 0;/*****************************************************************函数名称: AMPS_InternalMalloc功能描述: 内部的内存分配函数入参::      int r_unSize 待分配的字节数出参:            返回值:      void* 分配完成后的内存块指针*****************************************************************/void* AMPS_InternalMalloc(int r_unSize){/*g_poMemContext->nNoOfMallocWithoutFree++;if(g_poMemContext->nNoOfMallocWithoutFree > 17600){printf("AMPS_InternalMalloc: ======================= App Memory Count %d\n", g_poMemContext->nNoOfMallocWithoutFree);}*///return(g_poMemContext->pfAMPS_InternalMallocCallback(r_unSize));void* pvReturnValue = NULL;pvReturnValue = malloc(r_unSize);if(NULL == pvReturnValue){printf("OS_Malloc: malloc failed for size %d.\n", r_unSize);return NULL;}memset(pvReturnValue, 0, r_unSize);return pvReturnValue;}/*****************************************************************函数名称: AMPS_InternalRealloc功能描述: 重新分配内存入参::      void* r_pvData 待重新分配的内存块      int r_unSize  需要增加的字节数出参:            返回值:      void* 分配完成后的内存块指针*****************************************************************/void* AMPS_InternalRealloc(void* r_pvData, int r_unSize){    //return(g_poMemContext->pfAMPS_InternalReallocCallback(r_pvData, r_unSize));void* pvReturnValue = NULL;pvReturnValue = realloc(r_pvData, r_unSize); if(NULL == pvReturnValue){printf("OS_Realloc: realloc failed for size %d.\n", r_unSize);return NULL;}return pvReturnValue;}/*****************************************************************函数名称: AMPS_InternalFree功能描述: 内存释放入参::      void* r_pvData 待释放内存地址出参:            返回值:      void*****************************************************************/void AMPS_InternalFree(void* r_pvData){/*g_poMemContext->nNoOfMallocWithoutFree--;if(g_poMemContext->nNoOfMallocWithoutFree < 17600){printf("AMPS_InternalFree: =+=+=+=+=+=+=+=+=+=+=+=+= App Memory Count %d\n", g_poMemContext->nNoOfMallocWithoutFree);}*///g_poMemContext->pfAMPS_InternalFreeCallback(r_pvData);free(r_pvData);r_pvData = NULL;}/*****************************************************************函数名称: OS_Malloc功能描述: 操作系统提供的内存分配入参::      int r_unSize出参:            返回值:      void*****************************************************************/void* OS_Malloc(int r_unSize){    void* pvReturnValue = NULL;    pvReturnValue = malloc(r_unSize);if(NULL == pvReturnValue){printf("OS_Malloc: malloc failed for size %d.\n", r_unSize);return NULL;}    memset(pvReturnValue, 0, r_unSize);//g_nTotalMallocs++;//printf("total mallocs=%d.\n", g_nTotalMallocs);    return pvReturnValue;}/*****************************************************************函数名称: OS_Realloc功能描述: 操作系统提供的内存重新分配入参:      void* r_pvData      int r_unSize出参:            返回值:      void*****************************************************************/void* OS_Realloc(void* r_pvData, int r_unSize){    void* pvReturnValue = NULL;    pvReturnValue = realloc(r_pvData, r_unSize); if(NULL == pvReturnValue){printf("OS_Realloc: realloc failed for size %d.\n", r_unSize);return NULL;}    return pvReturnValue;}/*****************************************************************函数名称: OS_Free功能描述: 操作系统提供的内存释放入参:      void* r_pvData出参:            返回值:      void*****************************************************************/void OS_Free(void* r_pvData){/*if(NULL == r_pvData){printf("OS_Free: NULL pointer.\n");return;}*/    free(r_pvData);//g_nTotalMallocs--;//printf("total frees=%d.\n", g_nTotalMallocs);    r_pvData = NULL;}//inialize all the blocks here..//array of structures of different sized chunks//|0| = |2k|-|2k|-|2k|...//|1| = |4k|-|4k|-|4k|...//|2| = |6k|-|6k|-|6k|.../*****************************************************************函数名称: MM_Init功能描述: 内存管理模块初始化入参:      int r_bMMEnable 是否使用内存池出参:            返回值:      void******************************************************************/void* MM_Init(int r_bMMEnable){int i,j =0;int nLargeMemSize = 0;    /*内存模块指针*/g_poMemContext = malloc(sizeof(t_MemContext));if(NULL == g_poMemContext){printf("MM_Init: malloc is failed for g_poMemContext.\n");return NULL;}g_poMemContext->nNoOfMallocWithoutFree = 0;g_poMemContext->bMMEnable = (AMPS_BOOL)r_bMMEnable;    /*是否使用内存池管理内存*/if(AMPS_TRUE == r_bMMEnable){        /*初始化小块内存池,池中有42个链表(32个小块内存链表+10个大块内存链表)        这些链表有32k,64k,96K....的内存,链表的每一个结点,分别是32B, 64B....        同一个链表中各结点大小一样,结点中间都会有一个32位整形的索引值,比如第        一个链表的结构如下:        |0|32B|0|32B|0|32B|......*/for(i=0, j=1; i<NO_OF_SMALL_MEM_POOLS; i++,j++) //low limit elements{printf("Initializing buffer with size = %d at index = %d \n", nLargeMemSize, i);MM_BufferInit(&g_poMemContext->poMemoryPools[i], i, j*MINIMUM_SMALL_MEM_BLOCK_SIZE, NO_OF_BLOCKS_OF_SMALL_MEM_POOL);}        /*初始化大内存块,原理与小内存块初始化一样*/nLargeMemSize = MINIMUM_LARGE_MEM_BLOCK_SIZE;for(i=0,j=1; i<NO_OF_LARGE_MEM_POOLS; i++,j++){printf("Initializing buffer with size = %d at index = %d \n", nLargeMemSize, NO_OF_SMALL_MEM_POOLS+i);MM_BufferInit(&g_poMemContext->poMemoryPools[NO_OF_SMALL_MEM_POOLS+i], NO_OF_SMALL_MEM_POOLS+i, nLargeMemSize, NO_OF_BLOCKS_OF_LARGE_MEM_POOL);nLargeMemSize = nLargeMemSize*2;}        /*内存操作函数*/g_poMemContext->pfAMPS_InternalMallocCallback = MM_Malloc;g_poMemContext->pfAMPS_InternalReallocCallback = MM_Realloc;g_poMemContext->pfAMPS_InternalFreeCallback = MM_Free;}else{        /*不使用内存池,直接使用操作系统提供的内存分配函数*/g_poMemContext->pfAMPS_InternalMallocCallback = OS_Malloc;g_poMemContext->pfAMPS_InternalReallocCallback = OS_Realloc;g_poMemContext->pfAMPS_InternalFreeCallback = OS_Free;}/*j = i;MM_BufferInit(&g_poMemContext->poMemoryPools[j], j, 262144, NO_OF_BLOCKS_OF_LARGE_MEM_POOL);*/return g_poMemContext;}/*****************************************************************函数名称: MM_Cleanup功能描述: 内存管理模块销毁入参:      int r_bMMEnable出参:            返回值:      void******************************************************************/void MM_Cleanup(void){t_MemContext* poMemContext = g_poMemContext;t_MemoryPool* poNextMemoryPool = NULL;t_MemoryPool* poPrevMemoryPool = NULL;int i =0;if(AMPS_TRUE == g_poMemContext->bMMEnable){if(NULL != poMemContext){               /*逐一释放内存池中各链表结点内存*/for(i=0; i<NO_OF_SMALL_MEM_POOLS+NO_OF_LARGE_MEM_POOLS; i++){free(poMemContext->poMemoryPools[i].puchBuffer);poNextMemoryPool = poMemContext->poMemoryPools[i].poMemoryPoolNext;while(NULL != poNextMemoryPool){poPrevMemoryPool = poNextMemoryPool;poNextMemoryPool = poNextMemoryPool->poMemoryPoolNext;MM_BufferDestroy(poPrevMemoryPool);free(poPrevMemoryPool);}}}}        /*释放内存池指针所占内存*/free(poMemContext);}/*****************************************************************函数名称: MM_Malloc功能描述: 内存管理模块内存分配入参:      int r_nSize出参:            返回值:      void******************************************************************/void* MM_Malloc(int r_nSize){t_MemContext* poMemContext = g_poMemContext;t_MemoryPool* poMemoryPool = NULL;t_node* poNode = NULL;    /*根据大小获取一个偏移量,用于在内存池中查找对应的内存链表*/int index = GET_MEM_BUFFER_INDEX(r_nSize);if(AMPS_ERROR_FAILURE == index){printf("AMPS_InternalMalloc: Invalid size arguement given %d \n", r_nSize);return NULL;}    /*分配的内存块总数目加1*/poMemContext->nMallocCounts[index]++;    /*指向找到的内存链表*/poMemoryPool = &poMemContext->poMemoryPools[index];    /*从链表头获取一个节点*/poNode = poMemoryPool->poHead;poMemoryPool->poHead = poMemoryPool->poHead->poAMPSSListNext;if(NULL != poMemoryPool->poHead){poMemoryPool->poHead->poAMPSSListPrev = NULL;}else{        /*如果链表中无可用内存,重新分配*/MM_BufferNew(poMemoryPool->nSize);}memset((void*)poNode, 0, r_nSize);return poNode;}/*****************************************************************函数名称: MM_Realloc功能描述: 内存管理模块重新内存分配入参:      void* r_pvData 原内存指针      int r_unSize 大小出参:            返回值:      void******************************************************************/void* MM_Realloc(void* r_pvData, int r_unSize){unsigned char* newptr = NULL;int oldBuffSize = -1;int index = 0;t_MemContext* poMemContext = g_poMemContext;unsigned char* puchData = (unsigned char*)r_pvData;if(NULL == puchData){return NULL;}    /*计算当前所在内存指针在池中的链表索引*/index = GET_INDEX_FROM_BUFFER(puchData);if(AMPS_ERROR_FAILURE == index){printf("AMPS_InternalRealloc: Invalid pvData pointer given for realloc \n");return NULL;}oldBuffSize = poMemContext->poMemoryPools[index].nSize;newptr = AMPS_InternalMalloc(r_unSize);if(NULL == newptr){printf("AMPS_InternalRealloc: Unable to allocate new memory for requested size = %d \n", r_unSize);return NULL;}memcpy(newptr, puchData, oldBuffSize);AMPS_InternalFree(puchData);return newptr;}/*****************************************************************函数名称: MM_Free功能描述: 内存管理模块内存释放入参:      void* r_pvData出参:            返回值:      void*****************************************************************/void MM_Free(void* r_pvData){t_MemContext* poMemContext = g_poMemContext;unsigned char* puchData = (unsigned char*)r_pvData;t_MemoryPool* poMemoryPool = NULL;t_node* poNode = NULL;    int index  = 0;        if (NULL == r_pvData)    {        return;    }    /*获取池中链表索引*/    index = GET_INDEX_FROM_BUFFER(puchData);    if(AMPS_ERROR_FAILURE == index){printf("AMPS_InternalFree: Invalid pvData pointer given for free \n");return ;}//poMemContext->nMallocCounts[index]--;    /*从链表头删除此结点*/poMemoryPool = &poMemContext->poMemoryPools[index];poNode = (t_node*)puchData;poNode->poAMPSSListPrev = NULL;poNode->poAMPSSListNext = poMemoryPool->poHead;if(NULL != poMemoryPool->poHead) //there was no node left in the current buffer so poAMPSSListHead was NULL{poMemoryPool->poHead->poAMPSSListPrev = poNode;}poMemoryPool->poHead = poNode;}/*****************************************************************函数名称: MM_BufferInit功能描述: 内存链表头结点入参:      t_MemoryPool* r_poMemoryPool 内存池中结点指针      int indexOfBuff 此结点在内存池中的位置      int size        待分配的各结点内存大小      int chunks      结点个数出参:            返回值:      void******************************************************************/// Mark this buffer for use..//1- initialize the poAMPSSListHead.//2- write the chunk array index into it.void MM_BufferInit(t_MemoryPool* r_poMemoryPool, int indexOfBuff, int size, int chunks){t_MemoryPool* poMemoryPool = r_poMemoryPool;t_node* prev_node = NULL;t_node* node = NULL;unsigned int* indexTag = 0;int i=0;    /*以下假设indexOfbuff=0,size=32,chunks=1000进行讲解*/    /*分配所表示链表占用的总内存*/poMemoryPool->puchBuffer = malloc(size*chunks + chunks*sizeof(int));    /*链表结点个数*/poMemoryPool->nSize = size;    /*下一个结点置NULL*/   poMemoryPool->poMemoryPoolNext = NULL;    /*内存前4个字节置为当前总链表数组偏移量*/indexTag = (unsigned int*)&poMemoryPool->puchBuffer[0];*indexTag = indexOfBuff;    /*第二个结点从内存块的第4个字节开始,因为前四个字已经存放了下标*/node = (t_node*)&poMemoryPool->puchBuffer[sizeof(int)];node->poAMPSSListPrev = NULL;node->poAMPSSListNext = NULL;    /*链表头指针这个结点*/poMemoryPool->poHead = node;prev_node = node;for(i=1; i< chunks; i++){int index = 0;        /*跳过前四个结点,中间再相隔32个字节*/indexTag = (unsigned int*)&poMemoryPool->puchBuffer[i*size + i* sizeof(int)];*indexTag = indexOfBuff;        /*再计算下一个节点的位置,最终形成了一个这样的链表:        每个结点前4个字节值一样,存放当前链表在整个池中的便宜量,        然后接着是32个字节。再下来就是下一个节点,其有1000个这样的结点*/index = i*size + ((i*sizeof(int))+sizeof(int));node = (t_node*)&poMemoryPool->puchBuffer[index];prev_node->poAMPSSListNext = node;node->poAMPSSListPrev = prev_node;node->poAMPSSListNext = NULL;prev_node = node;}}/*****************************************************************函数名称: MM_BufferDestroy功能描述: 内存链表结点销毁入参:      t_MemoryPool* r_poMemoryPool 内存池中结点指针出参:            返回值:      void*****************************************************************/void MM_BufferDestroy(t_MemoryPool* r_poMemoryPool){if(NULL != r_poMemoryPool->puchBuffer){free(r_poMemoryPool->puchBuffer);}r_poMemoryPool->poHead = NULL;r_poMemoryPool->puchBuffer = NULL;}/*****************************************************************函数名称: MM_BufferNew功能描述: 新分配一个内存链表入参:      tr_nSize 大小出参:            返回值:      void*****************************************************************/void MM_BufferNew(int r_nSize){int chunks = 0;t_MemoryPool* poNextMemoryPool = NULL;t_MemoryPool* poNewMemBuff = NULL;t_MemContext* poMemContext = (t_MemContext*)g_poMemContext;    /*获取池中链表索引*/int index = GET_MEM_BUFFER_INDEX(r_nSize);if(AMPS_ERROR_FAILURE == index){printf("MM_BufferNew: Unable to get new buffer \n");return ;}    /*计算需要的块个数*/chunks = MM_GetNoOfChunks(r_nSize)/2;poNewMemBuff = malloc(sizeof(t_MemoryPool));if(NULL == poNewMemBuff){printf("MM_BufferNew: Unable to malloc for new buffer \n");return ;}    /*建立一个新的内存链表*/MM_BufferInit(poNewMemBuff, index, r_nSize, chunks);    /*把新分配的链表挂在内存池上*///go to last node to add a new nodepoNextMemoryPool = &poMemContext->poMemoryPools[index];while(NULL != poNextMemoryPool->poMemoryPoolNext){poNextMemoryPool = poNextMemoryPool->poMemoryPoolNext;}poNextMemoryPool->poMemoryPoolNext = poNewMemBuff;poMemContext->poMemoryPools[index].poHead = poNewMemBuff->poHead;}/*****************************************************************函数名称: MM_GetNoOfChunks功能描述: 根据大小,计算所需要的内存块个数(一个块的大小为32B)入参:      tr_nSize 大小出参:            返回值:      int*****************************************************************/int MM_GetNoOfChunks(int bufferSize){if(bufferSize < 1024){int sizeIndex = (bufferSize-1)/32;switch(sizeIndex){case 0:return 100;break;case 1:return 125;break;case 2:return 100;break;case 3:return 100;break;case 4:return 100;break;default :return 28;}}else{return 100;}}/*****************************************************************函数名称: MM_BufferShow功能描述: 遍历内存链表入参:      t_MemoryPool* r_poMemoryPool      tr_nSize 大小出参:            返回值:      int*****************************************************************///simply debug utility function to see if link list has been created correctlyvoid MM_BufferShow(t_MemoryPool* r_poMemoryPool, int r_nSize){t_MemoryPool* poMemoryPool = r_poMemoryPool;t_node* poNode = NULL;int i=0;poNode = (t_node*)&poMemoryPool->poHead;while(NULL != poNode->poAMPSSListNext){poNode = poNode->poAMPSSListNext;i++;}}void MM_BufferDump(unsigned char* buff, int size){int i=0;for(i=0; i< size; i++){ //printf%.2x ,", buff[i]);if(i%8 == 0 && i!=0){ //printf\n");}}}/*****************************************************************函数名称: MM_CalculateAndDisplayMemoryStats功能描述: 查看内存池使用情况(总大小,已分配大小)入参:      void出参:            返回值:      int*****************************************************************/void MM_CalculateAndDisplayMemoryStats (void){    int i =0,j=0;int nLargeMemSize = MINIMUM_LARGE_MEM_BLOCK_SIZE;    int nTotalMemory = 0;printf(" ====== Memory Usage Count for Small memory chunks.=====\n");for(i=0,j=1; i< NO_OF_SMALL_MEM_POOLS; i++,j++){if(0 != g_poMemContext->nMallocCounts[i]){            nTotalMemory += ((g_poMemContext->nMallocCounts[i] * (j*32))/1024);printf("Pool Size = %d No Of Mallocs = %d  total = %d kilo bytes\n", j*32, g_poMemContext->nMallocCounts[i], ((g_poMemContext->nMallocCounts[i] * (j*32))/1024));}}printf(" ====== Memory Usage Count for Large memory chunks.=====\n");for(i=0,j=1; i< NO_OF_LARGE_MEM_POOLS; i++,j++){if(i == 0){nLargeMemSize = nLargeMemSize;}else        {            nLargeMemSize = nLargeMemSize * 2;        }        if(0 != g_poMemContext->nMallocCounts[NO_OF_SMALL_MEM_POOLS + i])        {            nTotalMemory += ((g_poMemContext->nMallocCounts[NO_OF_SMALL_MEM_POOLS+i] * (nLargeMemSize))/1024);            printf("Pool Size = %d No Of Mallocs = %d  total = %d kilo bytes\n", nLargeMemSize, g_poMemContext->nMallocCounts[NO_OF_SMALL_MEM_POOLS+i], ((g_poMemContext->nMallocCounts[NO_OF_SMALL_MEM_POOLS+i] * (nLargeMemSize))/1024));        }        }    printf("Total Memory Consumed is = %d Megs.\n", nTotalMemory/1024);}



读书人网 >编程

热点推荐