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 + -
显示快捷键?