首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

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

2013-01-28 
AMPS:内存管理模块源码解读(二)上节看了AMPS中通过数组单链表实现的内存池,本节看看另一个实现方式。此方法

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

  上节看了AMPS中通过数组+单链表实现的内存池,本节看看另一个实现方式。此方法思路如下:其内存池结构为一个存放已分配内存信息的双链表,一个表示内存池大小的变量,一个指向当前内存链表结点的指针链表,如下:

#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"/*****************************************************************函数名称: createNewMemNode功能描述: 创建内存结点入参:      int nSizeOfBuff 大小 出参:            返回值:      t_NewMM_MemoryNode******************************************************************/t_NewMM_MemoryNode* createNewMemNode(int nSizeOfBuff){t_NewMM_MemoryNode* newNode = NULL;    /*分配一块内存,前面存放结点信息,后面是结点实际的块大小*/char* pchTempPtr = (char*)OS_Malloc(sizeof(t_NewMM_MemoryNode) + nSizeOfBuff);newNode = (t_NewMM_MemoryNode*)pchTempPtr;if(NULL != newNode){newNode->nAllocatedBytesInBlock = 0; newNode->memBuff = (char*)(pchTempPtr + sizeof(t_NewMM_MemoryNode));                           newNode->pchCurrPtrInBlock = newNode->memBuff;}else{return NULL;}return newNode;}/*分配与释放计数器*/int g_nNumAlloc=0; int g_nNumFree=0;/*****************************************************************函数名称: MM_New_Init功能描述: 内存模块初始化入参:      int nSizeOfBuff 大小 出参:            返回值:      t_NewMM_MemoryNode******************************************************************/void* MM_New_Init(int nSizeOfBuff){    /*创建一个内存池*/t_NewMMContext* newContext = OS_Malloc(sizeof(t_NewMMContext));t_AMPSDList* memBuffList = NULL;        if(NULL == newContext){printf("NewMM: unable to create new memory context---out of memory\n");return NULL;}    /*内存池大小*/newContext->nSizeOfBuff = nSizeOfBuff;    /*初始化内存链表*/memBuffList = DList_Init(&memBuffList);    /*链表挂在内存池中*/if(NULL != memBuffList){t_NewMM_MemoryNode* newNode = NULL;newContext->memBuffList = memBuffList;newNode = createNewMemNode(nSizeOfBuff);if(NULL != newNode){printf("init mem: allocated new buffer %p\n",newNode);g_nNumAlloc++;/*已分配结点数+1*/newContext->poCurrentListPtr = DList_Append(memBuffList,(void*)newNode);}else{OS_Free(newContext);DList_Free(&memBuffList,NULL);return NULL;}}else{        OS_Free(newContext);    DList_Free(&memBuffList,NULL);    return NULL;}    return newContext;}/*****************************************************************函数名称: compareAvailableBytes功能描述: 看是否有可用的内存入参:      void* size 大小      void* listData 链表出参:            返回值:      t_NewMM_MemoryNode******************************************************************/int compareAvailableBytes(void* size, void* listData){    t_NewMemSizeCmp* sizeCmp = (t_NewMemSizeCmp*)size;t_NewMM_MemoryNode* memNode = (t_NewMM_MemoryNode*)listData;//printf("sizeCmp=%p AND memNode=%p \n", sizeCmp, memNode);    /*结点内总内存块指针,指向结尾*/char* endOfBuff = memNode->memBuff + sizeCmp->maxSize;    /*判断结点内剩余的内存是否满足所要求分配的*/if( (endOfBuff - memNode->pchCurrPtrInBlock) >= sizeCmp->nSizeRequired ){//printf("Available=%d AND sizeCmp->nSizeRequired=%d \n", (endOfBuff - memNode->pchCurrPtrInBlock), sizeCmp->nSizeRequired);   return 0;}return -1;}/*****************************************************************函数名称: MM_New_Malloc功能描述: 分配内存入参:      void* mm_Object 内存池指针      int nSize 大小出参:            返回值:      t_NewMM_MemoryNode******************************************************************/void* MM_New_Malloc(void* mm_Object,int nSize){    t_NewMMContext* mmContext = (t_NewMMContext*)mm_Object;    int nActualSize = 0;    t_AMPSSList* listNode = NULL;    t_NewMM_MemoryNode* memNode = NULL;//printf("MALLOC: Ctxt=%p, Size=%d \n", mmContext, nSize);if(nSize < 0){        printf("MALLOC: bad allocation request size %d\n",nSize);return NULL;}if(NULL == mm_Object){return NULL;}        /*要求的大小大于池中允许大小*/if(nSize > mmContext->nSizeOfBuff){printf("MALLOC: too large allocation request for size %d: the memory manager supports up to %d bytes requests\n",nSize,mmContext->nSizeOfBuff);return NULL;}if(0 == nSize){nSize = 4;/*后面偏移使用*/}    /*指定大小为实际要分配的大小+内存比较头大小*/nActualSize = nSize + sizeof(t_NewMMBuffDescriptor);    /*向后移4个字节*/nActualSize =  ((nActualSize + 3) >> 2) << 2;   // go to next four byte boundary    //printf("MALLOC: Ctxtt=%p, nActualSize = %d, On mmContext->memBuffList =%p \n", mmContext, nActualSize, mmContext->memBuffList);    /*指向池当前指针*/listNode = mmContext->poCurrentListPtr;if(NULL != listNode){        t_NewMemSizeCmp sizeCmp;        sizeCmp.nSizeRequired = nActualSize;         sizeCmp.maxSize       = mmContext->nSizeOfBuff;        /*比较是否有内存可供分配*/if( -1 == compareAvailableBytes((void*)&sizeCmp, listNode->pvData)){listNode = NULL;}    //listNode = DList_Search(mmContext->memBuffList,compareAvailableBytes,(void*)&sizeCmp);}    /*有则取已有内存结点,无则分配一个新的结点*///printf("MALLOC: Ctxt=%p, nSize (after DListSearch)=%d listNode=%p  \n", mmContext, nSize, listNode);    if(NULL != listNode){memNode = (t_NewMM_MemoryNode*)listNode->pvData;//printf("Ctxt=%p,memNode->memBuff=%p, memNode->pchCurrPtrInBlock=%p \n",mmContext, memNode->memBuff, memNode->pchCurrPtrInBlock);}else {t_NewMM_MemoryNode* newNode = createNewMemNode(mmContext->nSizeOfBuff);if(NULL!= newNode){g_nNumAlloc++;             listNode = DList_Append(mmContext->memBuffList,(void*)newNode); if(NULL == listNode)             { printf("****new mm malloc: dlist append failed..\n"); OS_Free(newNode); return NULL;             } //printf("Ctxt=%pallocated new buffer %p, total buffers allocated=%d, listNode=%p \n",mmContext, newNode, g_nNumAlloc, listNode); memNode = newNode; mmContext->poCurrentListPtr = listNode;}else{printf("MALLOC: unable to allocate new node\n");return NULL;}}{         /*执向取到的结点内的内存块当前指针*/         char* tempPtr = memNode->pchCurrPtrInBlock; t_NewMMBuffDescriptor* buffDescriptorPtr = (t_NewMMBuffDescriptor*)tempPtr;         /*内存描述内容前4个字节赋值DEAD*/         memcpy(buffDescriptorPtr->markerBytes,"DEAD",4);         /*此块内存大小*/         buffDescriptorPtr->nSizeOfBuff = nActualSize;         /*存放当前内存结点指针*/         buffDescriptorPtr->dlistNode = listNode;  // store the back ptr to mem node         /*结点内内存分配字节数递增*/ memNode->nAllocatedBytesInBlock += nActualSize;         /*跳过内存描述信息区*/ tempPtr += sizeof(t_NewMMBuffDescriptor);  // tempPtr now points to writeable area of this buffer for the application         /*结点内当前指针向后移动*/         memNode->pchCurrPtrInBlock += nActualSize; // current ptr now advances to next buffer to be allocated     memset(tempPtr,0,nSize); // zero out the contents of the allocated memory //printf("MALLOC: mmContext=%p: memNode->nAllocatedBytesInBlock=%d and Requested Size =%d\n", mmContext, memNode->nAllocatedBytesInBlock, nSize); return tempPtr;}}/*****************************************************************函数名称: MM_New_Free功能描述: 分配释放入参:      void* mm_Object 内存池指针      char* buffToFree 要释放的内存指针出参:            返回值:      void*****************************************************************/void MM_New_Free(void* mm_Object,char* buffToFree){t_NewMMContext* mmContext = (t_NewMMContext*)mm_Object;char* tempPtr = buffToFree;t_NewMM_MemoryNode* memNode = NULL;t_AMPSSList* listNode = NULL;t_NewMMBuffDescriptor* buffDescriptorPtr = NULL;    /*要释放的指针向前移动,找到内存描述区*/tempPtr -= sizeof(t_NewMMBuffDescriptor);buffDescriptorPtr = (t_NewMMBuffDescriptor*)tempPtr;        if(NULL == tempPtr){        printf("FREE: buffer descriptor ptr is NULL..memory corruption\n");return;}    /*从内存描述区取出分配时存放的结点指针*/listNode = (t_AMPSSList*)buffDescriptorPtr->dlistNode;memNode = (t_NewMM_MemoryNode*)listNode->pvData;      /*如果此时描述区内标记不为DAED,说明此块内存出错(例如被覆盖)*/  if((0 != memcmp(buffDescriptorPtr->markerBytes,"DEAD",4)))      {          printf("FREE: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> marker string not found..memory corruption. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");          return;      }      /*结点为空,说明已经被释放*/      if(NULL == listNode)      {          printf("FREE: listNode is NULL: double free or corruption\n");          return;      }    if(NULL == memNode)      {         printf("FREE: memNode is NULL: double free or corruption\n");         return;      }      /*结点已用内存数减少释放的字节数*/  memNode->nAllocatedBytesInBlock -= buffDescriptorPtr->nSizeOfBuff;      /*如果已用内存数为小于0或大于池大小,出错*/  if(memNode->nAllocatedBytesInBlock < 0 || memNode->nAllocatedBytesInBlock > mmContext->nSizeOfBuff)  {  printf("FREE: allocated bytes = %d, double free or corruption\n",memNode->nAllocatedBytesInBlock);  return;  }  //printf("FREE: mmContext=%p: memNode->nAllocatedBytesInBlock=%d \n", mmContext, memNode->nAllocatedBytesInBlock);      /*如果已用内存为0,则释放这个结点*/  if( 0 == memNode->nAllocatedBytesInBlock)  {  g_nNumFree++;          //printf("Ctxt=%pavailable bytes are 0..freeing memNode %p, total buffers free'd =%d \n",mmContext, memNode, g_nNumFree);  if(listNode == mmContext->poCurrentListPtr)  {  mmContext->poCurrentListPtr = NULL;  }  DList_Remove(&mmContext->memBuffList,listNode,NULL);  free(memNode);  }}



热点排行