memheap.c

来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 1,332 行 · 第 1/3 页

C
1,332
字号
                  /* modify the prevOff of the next elem */                  pNextElem = GETNEXT (pElem);                  if (pNextElem != 0)                     pElem_prevOff (pNextElem) = QOFFSETOF (pNextElem, pElem);               }                              TRACEMEMELEM (pMemBlk, pElem, "Reallocated");               CHECKMEMELEM (pMemBlk, pElem);               CHECKMEMELEM (pMemBlk, (!ISLAST (pElem)) ? GETNEXT (pElem) : 0);               CHECKMEMBLOCK (pMemHeap, pMemBlk);               return (mem_p);            }         }      }      /* If not successful, allocate a new element and move the data into it */      RTMEMDIAG1 ("memHeapRealloc: allocate new memory...\n");      CHECKMEMHEAP (pMemHeap);      newMem_p = memHeapAlloc (ppvMemHeap, nbytes);            if (newMem_p == 0)         return 0;      /* if the old memory block is marked as saved then mark the new block         as saved as well. */      if (ISSAVED (pElem))          memHeapMarkSaved (ppvMemHeap, newMem_p, TRUE);      CHECKMEMHEAP (pMemHeap);      memcpy (newMem_p, mem_p, (((ASN1UINT)pElem_nunits (pElem)) * 8u));      /* free old element */      RTMEMDIAG1 ("memHeapRealloc: free old pointer...\n");      memHeapFreePtr (ppvMemHeap, mem_p);      CHECKMEMHEAP (pMemHeap);      return (newMem_p);   }   else { /* shrinking */      RTMEMDIAG1 ("memHeapRealloc: shrinking ...\n");            /* just free the pointer, if nbytes == 0 */      if (nbytes == 0) {         RTMEMDIAG1 ("memHeapRealloc: free pointer...\n");         memHeapFreePtr (ppvMemHeap, mem_p);         return (NULL);      }      /* do not shrink, if size diff is too small */      /* sizeof (OSMemElemDescr) == 1 unit */      if (pElem_nunits (pElem) - nunits > 1) {                   /* if it is the last element in the block, then just change the size             and free_x. */         if (ISLAST (pElem)) {            pMemBlk->free_x -= (pElem_nunits (pElem) - nunits);            FILLFREEMEM (&pMemBlk->data [pMemBlk->free_x * 8u],                (pElem_nunits (pElem) - nunits) * 8u);         }         else {            OSMemElemDescr* pNewElem;            /* create new free element on the freed place */            pNewElem = (OSMemElemDescr*) (pElem_data (pElem) + nbytes);            /* sizeof (OSMemElemDescr) == 1 unit */            pElem_nunits (pNewElem) = (ASN1USINT)(pElem_nunits (pElem) - nunits - 1);                         initNewFreeElement (pMemBlk, pNewElem, pElem);                        pMemBlk->freeMem += (pElem_nunits (pElem) - nunits) - 1;         }         pElem_nunits (pElem) = (ASN1USINT)nunits;                  TRACEMEMELEM (pMemBlk, pElem, "Reallocated");         CHECKMEMELEM (pMemBlk, pElem);         CHECKMEMELEM (pMemBlk, (!ISLAST (pElem)) ? GETNEXT (pElem) : pElem);         CHECKMEMBLOCK (pMemHeap, pMemBlk);      }      return (mem_p);   }}/* Clears heap memory (frees all memory, reset all heap's variables) */void memHeapFreeAll (void** ppvMemHeap){   OSMemHeap* pMemHeap;   OSMemLink* pMemLink;   OSMemLink* pMemLink2;   if (ppvMemHeap == 0 || *ppvMemHeap == 0) return;   pMemHeap = *(OSMemHeap**)ppvMemHeap;   pMemLink = pMemHeap->phead;   RTMEMDIAG2 ("memHeapFreeAll: pMemHeap = 0x%x\n", pMemHeap);   TRACEFREE (pMemHeap, "memHeapFreeAll\n\n");   CHECKMEMHEAP (pMemHeap);   /* Release any dynamic memory blocks that may have been allocated */   while (pMemLink) {      pMemLink2 = pMemLink;      pMemLink  = pMemLink2->pnext;      RTMEMDIAG3 ("memHeapFreeAll: pMemLink2 = 0x%x, pMemLink = 0x%x\n",                   pMemLink2, pMemLink);      #ifdef _MEMDEBUG      if (pMemLink2->blockType & RTMEMSTD) {         OSMemBlk* pMemBlk = (OSMemBlk*) pMemLink2->pMemBlk;         FILLFREEMEM (pMemBlk->data, (pMemBlk->nunits * 8u));         FILLFREEMEM (pMemBlk, sizeof (*pMemBlk));      }#endif      if (!(pMemLink2->blockType & RTMEMSAVED)) {         OSMemBlk* pMemBlk = (OSMemBlk*) pMemLink2->pMemBlk;         /* unlink block first */         if(pMemLink2->pnext != 0) {            pMemLink2->pnext->pprev = pMemLink2->pprev;         }         if(pMemLink2->pprev != 0) {            pMemLink2->pprev->pnext = pMemLink2->pnext;         }         else { /* head */            pMemHeap->phead = pMemLink2->pnext;         }         /* correct heap's variables */         pMemHeap->usedUnits -= pMemBlk->nunits;         if (pMemBlk->free_x == 0)            pMemHeap->freeBlocks --;         else            pMemHeap->usedBlocks --;         /* free link and block */         if (((pMemLink2->blockType & RTMEMSTD) ||               (pMemLink2->blockType & RTMEMMALLOC)) &&              !(pMemLink2->blockType & RTMEMLINK))             g_free_func (pMemLink2->pMemBlk);         g_free_func (pMemLink2);      }   }}/* increments internal refCnt. use memHeapRelease to decrement and release */void memHeapAddRef (void** ppvMemHeap){   OSMemHeap* pMemHeap;   if (ppvMemHeap == 0 || *ppvMemHeap == 0) return;   pMemHeap = *(OSMemHeap**)ppvMemHeap;   pMemHeap->refCnt++;}/* Frees all memory and heap structure as well (if was allocated) */void memHeapRelease (void** ppvMemHeap){   OSMemHeap** ppMemHeap = (OSMemHeap**)ppvMemHeap;   if (ppMemHeap != 0 && *ppMemHeap != 0 && --(*ppMemHeap)->refCnt == 0) {      OSMemLink* pMemLink, *pMemLink2;      memHeapFreeAll (ppvMemHeap);      /* if there are RTMEMSAVED blocks - release memory for links only */      pMemLink = (*ppMemHeap)->phead;      while (pMemLink) {         pMemLink2 = pMemLink;         pMemLink  = pMemLink2->pnext;         free (pMemLink2);      }      if ((*ppMemHeap)->flags & RT_MH_FREEHEAPDESC)         free (*ppMemHeap);      *ppMemHeap = 0;   }}/* This function is used for marking memory block as "saved". It means * that the memory block containing the specified memory pointer won't be * freed after calls to memHeapFreeAll/memHeapReset. User is responsible  * for freeing the marked memory block by call to memFreeBlock */void* memHeapMarkSaved (void** ppvMemHeap, const void* mem_p,                         ASN1BOOL saved) {   OSMemHeap* pMemHeap;   OSMemLink* pMemLink;   ASN1UINT nsaved = 1;   RTMEMDIAG2 ("memHeapMarkSaved: for mem_p = 0x%x\n", mem_p);   if (ppvMemHeap == 0 || *ppvMemHeap == 0 || mem_p == 0)       return 0;   pMemHeap = *(OSMemHeap**)ppvMemHeap;   pMemLink = pMemHeap->phead;   /* look for chain of RAW blocks first */   for (; pMemLink != 0; pMemLink = pMemLink->pnextRaw) {      if ((pMemLink->blockType & RTMEMRAW) &&           pMemLink->pMemBlk == mem_p)       {         break;      }   }   if (pMemLink == 0) {      OSMemElemDescr* pElem;      OSMemBlk* pMemBlk;      /* gain the MemLink from pointer */      pElem = (OSMemElemDescr*) (((char*)mem_p) - sizeof_OSMemElemDescr);      if (ISFREE (pElem)) { /* already freed! */         RTMEMDIAG2 ("memHeapMarkSaved: the element 0x%x is "                         "already free!\n", pElem);         return 0;         }      if ((ISSAVED (pElem) && !saved) || (!ISSAVED (pElem) && saved)) {         pMemBlk = GET_MEMBLK (pElem);         CHECKMEMELEM (pMemBlk, pElem);         CHECKMEMBLOCK(pMemHeap, pMemBlk);         pMemLink = pMemBlk->plink;         if (saved)             SET_SAVED (pMemBlk, pElem);         else            CLEAR_SAVED (pMemBlk, pElem);         nsaved = pMemBlk->nsaved;      }      else         return 0;   }   if (saved && nsaved > 0)       pMemLink->blockType |= RTMEMSAVED;   else if (nsaved == 0)      pMemLink->blockType &= (~RTMEMSAVED);   return pMemLink->pMemBlk;}/* This function will set the free index in all blocks to zero thereby  *//* allowing the blocks to be reused (ED, 3/17/2002)..                   */void memHeapReset (void** ppvMemHeap){   OSMemHeap* pMemHeap;   OSMemLink *pMemLink;   if (ppvMemHeap == 0 || *ppvMemHeap == 0) return;   pMemHeap = *(OSMemHeap**)ppvMemHeap;   pMemLink = pMemHeap->phead;   TRACEFREE (pMemHeap, "memHeapReset\n\n");   while (pMemLink) {      if (!(pMemLink->blockType & RTMEMSAVED)) {         if (pMemLink->blockType & RTMEMSTD) {            OSMemBlk* pMemBlk = (OSMemBlk*) pMemLink->pMemBlk;            if (pMemBlk->free_x != 0) {               pMemHeap->freeUnits += pMemBlk->nunits;               pMemHeap->freeBlocks ++;            }            pMemBlk->free_x = 0;            pMemBlk->freeElemOff = 0;            pMemBlk->lastElemOff = 0;            pMemBlk->freeMem = 0;            FILLFREEMEM (pMemBlk->data, pMemBlk->nunits * 8u);         }         else if (pMemLink->blockType & RTMEMRAW) {            /* if RAW block - free it */            memHeapFreePtr (ppvMemHeap, pMemLink->pMemBlk);         }      }      pMemLink = pMemLink->pnext;   }}/* add memory block to list */static OSMemLink* memHeapAddBlock (OSMemLink** ppMemLink,                                      void* pMemBlk, int blockType){   OSMemLink* pMemLink;   /* if pMemBlk has RTMEMLINK flags it means that it is allocated     * cooperatively with OSMemLink, and we don't need to do additional    * allocations for it. Just use pointer's arithemtic. */   if (blockType & RTMEMLINK)       pMemLink = (OSMemLink*) (((ASN1OCTET*)pMemBlk) - sizeof (OSMemLink));   else {      pMemLink = (OSMemLink*) g_malloc_func (         sizeof(OSMemLink) + sizeof (int));      if (pMemLink == 0) return 0;      /* An extra integer is necessary to save a size of a RAW memory block         to perform rtMemRealloc through malloc/memcpy/free */      *(int*)(((char*)pMemLink) + sizeof (OSMemLink)) = (int)-1;   }   if (pMemLink == NULL)       return NULL;   pMemLink->blockType = (ASN1OCTET)blockType;   pMemLink->pMemBlk = pMemBlk;   pMemLink->pprev = 0;   pMemLink->pnext = *ppMemLink;   if (*ppMemLink != 0) {      if ((*ppMemLink)->blockType & RTMEMRAW)         pMemLink->pnextRaw = *ppMemLink;      else {         pMemLink->pnextRaw = (*ppMemLink)->pnextRaw;         (*ppMemLink)->pnextRaw = 0;      }   }   else {      pMemLink->pnextRaw = 0;   }   *ppMemLink = pMemLink;    if (pMemLink->pnext != 0)      pMemLink->pnext->pprev = pMemLink;   ((OSMemBlk*)pMemBlk)->plink = pMemLink; /*!AB */   RTMEMDIAG2 ("memHeapAddBlock: pMemLink = 0x%x\n", pMemLink);   RTMEMDIAG2 ("memHeapAddBlock: pMemLink->pnext = 0x%x\n",                     pMemLink->pnext);   RTMEMDIAG2 ("memHeapAddBlock: pMemLink->pprev = 0x%x\n",                     pMemLink->pprev);   return pMemLink;}int memHeapCheckPtr (void** ppvMemHeap, void* mem_p){   OSMemHeap* pMemHeap;   OSMemLink* pMemLink;   RTMEMDIAG2 ("memHeapCheckPtr: for mem_p = 0x%x\n", mem_p);   if (ppvMemHeap == 0 || *ppvMemHeap == 0 || mem_p == 0)       return 0;   pMemHeap = *(OSMemHeap**)ppvMemHeap;   pMemLink = pMemHeap->phead;   for (; pMemLink != 0; pMemLink = pMemLink->pnext) {      if (pMemLink->blockType & RTMEMRAW) {                  /* if RAW block, the pointer should be stored in pMemBlk */         if (pMemLink->pMemBlk == mem_p)             return 1;      }      else {         OSMemBlk* pMemBlk = (OSMemBlk*)pMemLink->pMemBlk;                  /* Check, is the pointer inside this memory page */         if (mem_p > pMemLink->pMemBlk &&              mem_p < (void*)(((ASN1OCTET*)pMemLink->pMemBlk) + pMemBlk->nunits * 8u))         {            /* Check, is the pointer a correct element of the mem page */            OSMemElemDescr* pElem = (OSMemElemDescr*) pMemBlk->data;            for (; pElem != 0; pElem = GETNEXT (pElem)) {                             void* curMem_p = (void*) pElem_data (pElem);               if (curMem_p == mem_p && !ISFREE (pElem))                  return 1;            }         }      }   }   return 0;}void memHeapSetProperty (void** ppvMemHeap, ASN1UINT propId, void* pProp){   OSMemHeap* pMemHeap;   if (ppvMemHeap == 0)       return;   if (*ppvMemHeap == 0)      memHeapCreate (ppvMemHeap);   pMemHeap = *(OSMemHeap**)ppvMemHeap;   switch (propId) {      case OSRTMH_PROPID_DEFBLKSIZE:         pMemHeap->defBlkSize = *(ASN1UINT*)pProp;         break;      case OSRTMH_PROPID_SETFLAGS:         pMemHeap->flags |= ((*(ASN1UINT*)pProp) & (~RT_MH_INTERNALMASK));         break;      case OSRTMH_PROPID_CLEARFLAGS:         pMemHeap->flags &= ((~(*(ASN1UINT*)pProp)) | RT_MH_INTERNALMASK);         break;   }} int memHeapCreate (void** ppvMemHeap) {   OSMemHeap* pMemHeap;   if (ppvMemHeap == 0) return ASN_E_INVPARAM;   pMemHeap = (OSMemHeap*) g_malloc_func (sizeof (OSMemHeap));   if (pMemHeap == NULL) return ASN_E_NOMEM;   memset (pMemHeap, 0, sizeof (OSMemHeap));   pMemHeap->defBlkSize = g_defBlkSize;   pMemHeap->refCnt = 1;   pMemHeap->flags = RT_MH_FREEHEAPDESC;   *ppvMemHeap = (void*)pMemHeap;   return ASN_OK;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?