⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbheap.c

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 C
📖 第 1 页 / 共 5 页
字号:
                {
                    pRegion->bitvGroupLo[indGroup] &=
                                            ~(0x80000000L >> (indNext - 32));
                    if (--pRegion->cntRegionSize[indNext] == 0)
                        pHeader->bitvEntryLo &=
                                            ~(0x80000000L >> (indNext - 32));
                }
            }

            //  unlink entry from list
            pNext->pEntryPrev->pEntryNext = pNext->pEntryNext;
            pNext->pEntryNext->pEntryPrev = pNext->pEntryPrev;

            //  add next entry size to present
            sizeEntry += sizeNext;
            indEntry = (sizeEntry >> 4) - 1;
            if (indEntry > 63)
                indEntry = 63;
        }

        //  connect leftover space with any free next entry

        //  add next entry to the start of the bucket list
        pHead = (PENTRY)((char *)&pGroup->listHead[indEntry] - sizeof(int));
        pEntry->pEntryNext = pHead->pEntryNext;
        pEntry->pEntryPrev = pHead;
        pHead->pEntryNext = pEntry;
        pEntry->pEntryNext->pEntryPrev = pEntry;

        //  test entry is sole member of bucket (next == prev),
        if (pEntry->pEntryNext == pEntry->pEntryPrev)
        {
            //  if region count was zero, set bit in region vector
            //  set bit in header entry vector, increment region count
            if (indEntry < 32)
            {
                if (pRegion->cntRegionSize[indEntry]++ == 0)
                    pHeader->bitvEntryHi |= 0x80000000L >> indEntry;
                pRegion->bitvGroupHi[indGroup] |= 0x80000000L >> indEntry;
            }
            else
            {
                if (pRegion->cntRegionSize[indEntry]++ == 0)
                    pHeader->bitvEntryLo |= 0x80000000L >> (indEntry - 32);
                pRegion->bitvGroupLo[indGroup] |= 0x80000000L >>
                                                           (indEntry - 32);
            }
        }

        //  adjust size fields of entry
        pEntry->sizeFront = sizeEntry;
        ((PENTRYEND)((char *)pEntry + sizeEntry -
                            sizeof(ENTRYEND)))->sizeBack = sizeEntry;
    }

    return TRUE;
}

/***
*int __sbh_heapmin() - minimize heap
*
*Purpose:
*       Minimize the heap by freeing any deferred group.
*
*Entry:
*       __sbh_pHeaderDefer  - pointer to HEADER of deferred group
*       __sbh_indGroupDefer - index of GROUP to defer
*
*Exit:
*       None.
*
*Exceptions:
*
*******************************************************************************/

void __cdecl __sbh_heapmin (void)
{
    void *      pHeapDecommit;

    //  if a group has been deferred, free that group
    if (__sbh_pHeaderDefer)
    {
        //  if now zero, decommit the group data heap
        pHeapDecommit = (void *)((char *)__sbh_pHeaderDefer->pHeapData +
                                    __sbh_indGroupDefer * BYTES_PER_GROUP);
        VirtualFree(pHeapDecommit, BYTES_PER_GROUP, MEM_DECOMMIT);

        //  set bit in commit vector
        __sbh_pHeaderDefer->bitvCommit |= 0x80000000 >> __sbh_indGroupDefer;

        //  clear entry vector for the group and header vector bit
        //  if needed
        __sbh_pHeaderDefer->pRegion->bitvGroupLo[__sbh_indGroupDefer] = 0;
        if (--__sbh_pHeaderDefer->pRegion->cntRegionSize[63] == 0)
            __sbh_pHeaderDefer->bitvEntryLo &= ~0x00000001L;

        //  if commit vector is the initial value,
        //  remove the region if it is not the last
        if (__sbh_pHeaderDefer->bitvCommit == BITV_COMMIT_INIT &&
                                                __sbh_cntHeaderList > 1)
        {
            //  free the region memory area
            HeapFree(_crtheap, 0, __sbh_pHeaderDefer->pRegion);

            //  remove entry from header list by copying over
            memmove((void *)__sbh_pHeaderDefer, (void *)(__sbh_pHeaderDefer + 1),
                            (int)(__sbh_pHeaderList + __sbh_cntHeaderList) -
                            (int)(__sbh_pHeaderDefer + 1));
            __sbh_cntHeaderList--;
        }

        //  clear deferred condition
        __sbh_pHeaderDefer = NULL;
    }
}

/***
*int __sbh_heap_check() - check small-block heap
*
*Purpose:
*       Perform validity checks on the small-block heap.
*
*Entry:
*       There are no arguments.
*
*Exit:
*       Returns 0 if the small-block is okay.
*       Returns < 0 if the small-block heap has an error. The exact value
*       identifies where, in the source code below, the error was detected.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl __sbh_heap_check (void)
{
    PHEADER     pHeader;
    PREGION     pRegion;
    PGROUP      pGroup;
    PENTRY      pEntry;
    PENTRY      pNext;
    PENTRY      pEntryLast;
    PENTRY      pEntryHead;
    PENTRY      pEntryPage;
    PENTRY      pEntryPageLast;
    int         indHeader;
    int         indGroup;
    int         indPage;
    int         indEntry;
    int         indHead;
    int         sizeEntry;
    int         sizeTrue;
    int         cntAllocated;
    int         cntFree[64];
    int         cntEntries;
    void *      pHeapGroup;
    void *      pHeapPage;
    void *      pPageStart;
    BITVEC      bitvCommit;
    BITVEC      bitvGroupHi;
    BITVEC      bitvGroupLo;
    BITVEC      bitvEntryHi;
    BITVEC      bitvEntryLo;

    //  check validity of header list
    if (IsBadWritePtr(__sbh_pHeaderList,
                      __sbh_cntHeaderList * sizeof(HEADER)))
        return -1;

    //  scan for all headers in list
    pHeader = __sbh_pHeaderList;
    for (indHeader = 0; indHeader < __sbh_cntHeaderList; indHeader++)
    {
        //  define region and test if valid
        pRegion = pHeader->pRegion;
        if (IsBadWritePtr(pRegion, sizeof(REGION)))
            return -2;

        //  scan for all groups in region
        pHeapGroup = pHeader->pHeapData;
        pGroup = &pRegion->grpHeadList[0];
        bitvCommit = pHeader->bitvCommit;
        bitvEntryHi = 0;
        bitvEntryLo = 0;
        for (indGroup = 0; indGroup < GROUPS_PER_REGION; indGroup++)
        {
            //  initialize entry vector and entry counts for group
            bitvGroupHi = 0;
            bitvGroupLo = 0;
            cntAllocated = 0;
            for (indEntry = 0; indEntry < 64; indEntry++)
                cntFree[indEntry] = 0;

            //  test if group is committed
            if ((int)bitvCommit >= 0)
            {
                //  committed, ensure addresses are accessable
                if (IsBadWritePtr(pHeapGroup, BYTES_PER_GROUP))
                    return -4;

                //  for each page in group, check validity of entries
                pHeapPage = pHeapGroup;
                for (indPage = 0; indPage < PAGES_PER_GROUP; indPage++)
                {
                    //  define pointers to first and past last entry
                    pEntry = (PENTRY)((char *)pHeapPage + ENTRY_OFFSET);
                    pEntryLast = (PENTRY)((char *)pEntry
                                                 + MAX_FREE_ENTRY_SIZE);

                    //  check front and back page sentinel values
                    if (*(int *)((char *)pEntry - sizeof(int)) != -1 ||
                                 *(int *)pEntryLast != -1)
                        return -5;

                    //  loop through each entry in page
                    do
                    {
                        //  get entry size and test if allocated
                        sizeEntry = sizeTrue = pEntry->sizeFront;
                        if (sizeEntry & 1)
                        {
                            //  allocated entry - set true size
                            sizeTrue--;

                            //  test against maximum allocated entry size
                            if (sizeTrue > MAX_ALLOC_ENTRY_SIZE)
                                return -6;

                            //  increment allocated count for group
                            cntAllocated++;
                        }
                        else
                        {
                            //  free entry - determine index and increment
                            //  count for list head checking
                            indEntry = (sizeTrue >> 4) - 1;
                            if (indEntry > 63)
                                indEntry = 63;
                            cntFree[indEntry]++;
                        }

                        //  check size validity
                        if (sizeTrue < 0x10 || sizeTrue & 0xf
                                        || sizeTrue > MAX_FREE_ENTRY_SIZE)
                            return -7;

                        //  check if back entry size same as front
                        if (((PENTRYEND)((char *)pEntry + sizeTrue
                                    - sizeof(int)))->sizeBack != sizeEntry)
                            return -8;

                        //  move to next entry in page
                        pEntry = (PENTRY)((char *)pEntry + sizeTrue);
                    }
                    while (pEntry < pEntryLast);

                    //  test if last entry did not overrun page end
                    if (pEntry != pEntryLast)
                        return -8;

                    //  point to next page in data heap
                    pHeapPage = (void *)((char *)pHeapPage + BYTES_PER_PAGE);
                }

                //  check if allocated entry count is correct
                if (pGroup->cntEntries != cntAllocated)
                    return -9;

                //  check validity of linked-lists of free entries
                pEntryHead = (PENTRY)((char *)&pGroup->listHead[0] -
                                                           sizeof(int));
                for (indHead = 0; indHead < 64; indHead++)
                {
                    //  scan through list until head is reached or expected
                    //  number of entries traversed
                    cntEntries = 0;
                    pEntry = pEntryHead;
                    while ((pNext = pEntry->pEntryNext) != pEntryHead &&
                                        cntEntries != cntFree[indHead])
                    {
                        //  test if next pointer is in group data area
                        if ((void *)pNext < pHeapGroup || (void *)pNext >=
                            (void *)((char *)pHeapGroup + BYTES_PER_GROUP))
                            return -10;

                        //  determine page address of next entry
                        pPageStart = (void *)((int)pNext &
                                                    ~(BYTES_PER_PAGE - 1));

                        //  point to first entry and past last in the page
                        pEntryPage = (PENTRY)((char *)pPageStart +
                                                        ENTRY_OFFSET);
                        pEntryPageLast = (PENTRY)((char *)pEntryPage +
                                                        MAX_FREE_ENTRY_SIZE);

                        //  do scan from start of page
                        //  no error checking since it was already scanned
                        while (pEntryPage != pEntryPageLast)
                        {
                            //  if entry matches, exit loop
                            if (pEntryPage == pNext)
                                break;

                            //  point to next entry
                            pEntryPage = (PENTRY)((char *)pEntryPage +
                                            (pEntryPage->sizeFront & ~1));
                        }

                        //  if page end reached, pNext was not valid
                        if (pEntryPage == pEntryPageLast)
                            return -11;

                        //  entry valid, but check if entry index matches
                        //  the header
                        indEntry = (pNext->sizeFront >> 4) - 1;
                        if (indEntry > 63)
                            indEntry = 63;
                        if (indEntry != indHead)
                            return -12;

                        //  check if previous pointer in pNext points
                        //  back to pEntry
                        if (pNext->pEntryPrev != pEntry)
                            return -13;

                        //  update scan pointer and counter
                        pEntry = pNext;
                        cntEntries++;
                    }

                    //  if nonzero number of entries, set bit in group
                    //  and region vectors
                    if (cntEntries)
                    {
                        if (indHead < 32)
                        {
                            bitvGroupHi |= 0x80000000L >> indHead;
                            bitvEntryHi |= 0x80000000L >> indHead;
                        }
                        else
                        {
                            bitvGroupLo |= 0x80000000L >> (indHead - 32);
                            bitvEntryLo |= 0x80000000L >> (indHead - 32);
                        }
                    }

                    //  check if list is exactly the expected size
                    if (pEntry->pEntryNext != pEntryHead ||
                                        cntEntries != cntFree[indHead])
                        return -14;

                    //  check if previous pointer in header points to
                    //  last entry processed
                    if (pEntryHead->pEntryPrev != pEntry)
                        return -15;

                    //  point to next linked-list header - note size
                    pEntryHead = (PENTRY)((char *)pEntryHead +
                                                      sizeof(LISTHEAD));
                }
            }

            //  test if group vector is valid
            if (bitvGroupHi != pRegion->bitvGroupHi[indGroup] ||
                bitvGroupLo != pRegion->bitvGroupLo[indGroup])
                return -16;

            //  adjust for next group in region
            pHeapGroup = (void *)((char *)pHeapGroup + BYTES_PER_GROUP);
            pGroup++;

⌨️ 快捷键说明

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