Ignore:
Timestamp:
Jan 23, 2000, 4:20:53 AM (26 years ago)
Author:
bird
Message:

Initial resident heap coding completed.
The AVL heap is seems to be much faster; it uses 40% of the time that the
traditional linked-list based heap is using when executing the heaptest.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/misc/rmalloc_avl.c

    r2501 r2503  
    1 /* $Id: rmalloc_avl.c,v 1.1 2000-01-22 18:21:03 bird Exp $
     1/* $Id: rmalloc_avl.c,v 1.2 2000-01-23 03:20:53 bird Exp $
    22 *
    33 * Resident Heap - AVL.
     
    1818#ifdef DEBUG
    1919    #define DEBUG_ALLOC
    20     #define ALLWAYS_HEAPCHECK
     20    #undef ALLWAYS_HEAPCHECK
    2121#endif
    2222
     
    3131                            ((PMEMBLOCKFREE)((unsigned)(a) - CB_HDR + 4))
    3232#define BLOCKSIZE (1024*256)            /* 256KB */
    33 
     33#define ALIGNMENT 4
    3434
    3535#define INCL_DOS
     
    139139static PMEMBLOCK    resFindUsedBlock(PHEAPANCHOR *ppha, void *pvUser);
    140140static PMEMBLOCK    resFindWithinUsedBlock(PHEAPANCHOR *ppha, void *pvUser);
     141static int          resCheckAVLTree(PMEMBLOCK pmb);
     142static int          resCheckAVLTreeFree(PAVLNODECORE pNode);
    141143static unsigned     _res_dump_subheaps_callback(PMEMBLOCK pmb, PSUBHEAPS_CALLBACK_PARAM pCb);
    142144static unsigned     _res_dump_allocated_callback(PMEMBLOCK pmb, PALLOCATED_CALLBACK_PARAM pParam);
     
    193195            else
    194196            {   /* other nodes of this size: replace pmbf with the first node in the chain. */
    195                 memcpy((void*)&pmbfTmp->pmbfNext->coreFree, (void*)&pmbfTmp->coreFree,
    196                        sizeof(pmbfTmp->coreFree));
     197                memcpy((void*)&pmbfTmp->pmbfNext->coreFree, (void*)&pmbfTmp->coreFree, sizeof(pmbfTmp->coreFree));
    197198                if (pmbfParent != NULL)
    198199                {
    199200                    pmbfParent = MEMBLOCKFREE_FROM_FREESIZENODE(pmbfParent);
    200                     if (pmbfTmp->coreFree.Key > pmbfParent->coreFree.Key)
    201                         pmbfParent->coreFree.pLeft = (PAVLNODECORE)pmbf->pmbfNext;
     201                    if (pmbfTmp->coreFree.Key < pmbfParent->coreFree.Key)
     202                        pmbfParent->coreFree.pLeft = (PAVLNODECORE)&pmbf->pmbfNext->coreFree;
    202203                    else
    203                         pmbfParent->coreFree.pRight = (PAVLNODECORE)pmbf->pmbfNext;
     204                        pmbfParent->coreFree.pRight = (PAVLNODECORE)&pmbf->pmbfNext->coreFree;
    204205                }
    205206                else
    206                     pha->pcoreFreeSize = (PAVLNODECORE)pmbf->pmbfNext;
     207                    pha->pcoreFreeSize = (PAVLNODECORE)&pmbf->pmbfNext->coreFree;
    207208            }
    208209        }
     
    231232    }
    232233    else
     234    {
     235        pmbf->pmbfNext = NULL;
    233236        AVLInsert((PPAVLNODECORE)&pha->pcoreFreeSize, &pmbf->coreFree);
     237    }
    234238}
    235239
     
    271275    if (pmbfLeft == NULL && pmbfRight == NULL)
    272276    {   /* 1 - insert no merge */
     277        pmbf->core.Key = (AVLKEY)pmbf;
    273278        AVLInsert((PPAVLNODECORE)&pha->pmbFree, (PAVLNODECORE)pmbf);
    274279        resInsertIntoFreeSize(pha, pmbf);
    275280    }
    276281    else if (pmbfLeft != NULL && pmbfRight == NULL)
    277     {   /* 2 - insert left merge */
     282    {   /* 2 - insert left merge: just add pmbf to pmbfLeft. */
    278283        resRemoveFromFreeSize(pha, pmbfLeft);
    279284        pmbfLeft->coreFree.Key += CB_HDR + pmbf->coreFree.Key;
     
    282287    }
    283288    else if (pmbfLeft == NULL && pmbfRight != NULL)
    284     {   /* 3 - insert right merge */
     289    {   /* 3 - insert right merge: replace pmbfRight with pmbf in the pmbfFree tree; */
    285290        resRemoveFromFreeSize(pha, pmbfRight);
    286         memcpy((void*)&pmbf->pmbfNext->core, (void*)&pmbfRight->core,
    287                sizeof(pmbf->core));
     291        memcpy((void*)&pmbf->core, (void*)&pmbfRight->core, sizeof(pmbf->core));
    288292        pmbf->core.Key = (AVLKEY)pmbf;
    289293        pmbf->coreFree.Key += CB_HDR + pmbfRight->coreFree.Key;
     
    302306    else
    303307    {   /* 4 -insert both left and right merge */
     308        if (AVLRemove((PPAVLNODECORE)&pha->pmbFree, (AVLKEY)pmbfRight) != (PAVLNODECORE)pmbfRight)
     309        {
     310            kprintf(("resInsertFree: AVLRemove on pmbfRight failed.\n"));
     311            return;
     312        }
    304313        resRemoveFromFreeSize(pha, pmbfLeft);
    305314        resRemoveFromFreeSize(pha, pmbfRight);
    306         pmbfRight = (PMEMBLOCKFREE)AVLRemove((PPAVLNODECORE)&pha->pmbFree,
    307                                              (AVLKEY)PNEXT_BLOCK(pmb));
    308315        pmbfLeft->coreFree.Key += CB_HDR*2 + pmbf->coreFree.Key + pmbfRight->coreFree.Key;
    309316        pha->cbFree += CB_HDR*2;
     
    328335    unsigned cbTotalSize = 0;
    329336
    330     cbUserSize = MAX(ALIGN(cbUserSize, 4), sizeof(MEMBLOCKFREE) - CB_HDR);
     337    cbUserSize = MAX(ALIGN(cbUserSize, ALIGNMENT), sizeof(MEMBLOCKFREE) - CB_HDR);
    331338
    332339    *ppha = phaFirst;
     
    335342        if ((*ppha)->cbFree >= cbUserSize + CB_HDR)
    336343        {
    337             PMEMBLOCKFREE pmbfTmp;
    338344            PMEMBLOCKFREE pmbf;
    339345
     
    342348            {
    343349                pmbf = MEMBLOCKFREE_FROM_FREESIZENODE(pmbf);
    344                 if (pmbf->pmbfNext == NULL)
     350                resRemoveFromFreeSize(*ppha, pmbf);
     351                (*ppha)->cbFree -= pmbf->coreFree.Key;
     352
     353                /* pmbf is now the block which we are to return, but do we have to split it? */
     354                if (pmbf->coreFree.Key > sizeof(MEMBLOCKFREE) + cbUserSize)
    345355                {
    346                     if (AVLRemove(&(*ppha)->pcoreFreeSize, pmbf->coreFree.Key) == NULL)
    347                     {
    348                         kprintf(("resGetFreeMemblock: internal error AVLRemove from the free-size list failed.\n"));
    349                         continue;
    350                     }
     356                    PMEMBLOCKFREE pmbfTmp = pmbf;
     357                    pmbf = (PMEMBLOCKFREE)((unsigned)pmbfTmp + pmbfTmp->coreFree.Key - cbUserSize);
     358                    #ifdef DEBUG_ALLOC
     359                        pmbf->ulSignature = MEMBLOCK_SIGNATURE;
     360                    #endif
     361                    pmbfTmp->coreFree.Key -= CB_HDR + cbUserSize;
     362                    pmbf->coreFree.Key = cbUserSize;
     363                    (*ppha)->cbFree += pmbfTmp->coreFree.Key;
     364                    resInsertIntoFreeSize(*ppha, pmbfTmp);
    351365                }
    352366                else
    353367                {
    354                     pmbfTmp = pmbf;
    355                     pmbf = pmbf->pmbfNext;
    356                     pmbfTmp->pmbfNext = pmbf->pmbfNext;
    357                 }
    358                 AVLRemove((PPAVLNODECORE)&(*ppha)->pmbFree, (AVLKEY)pmbf);
    359                 (*ppha)->cbFree -= pmbf->coreFree.Key;
    360 
    361                 /* pmbf is now the block which we are to return, but do we have to split it? */
    362                 if (pmbf->coreFree.Key > sizeof(MEMBLOCKFREE) + cbUserSize)
    363                 {
    364                     pmbfTmp = (PMEMBLOCKFREE)((unsigned)pmbf + CB_HDR + cbUserSize);
    365                     #ifdef DEBUG_ALLOC
    366                         pmbfTmp->ulSignature = MEMBLOCK_SIGNATURE;
    367                     #endif
    368                     pmbfTmp->coreFree.Key = pmbf->coreFree.Key - CB_HDR - cbUserSize;
    369                     pmbf->coreFree.Key = cbUserSize;
    370                     resInsertFree(*ppha, (PMEMBLOCK)pmbfTmp);
     368                    PMEMBLOCKFREE pmbfTmp = (PMEMBLOCKFREE)AVLRemove((PPAVLNODECORE)&(*ppha)->pmbFree, (AVLKEY)pmbf);
     369                    if (pmbfTmp != pmbf)
     370                    {
     371                        kprintf(("resGetFreeMemblock: Internal heap error - failed to Remove best fit block!\n"));
     372                        return NULL;
     373                    }
    371374                }
    372375                return (PMEMBLOCK)pmbf;
     
    653656 * @returns   Pointer to new heapblock.
    654657 * @param     pv     Pointer to the block to realloc.
     658 *                   If pv is NULL, this call is equal to malloc.
    655659 * @param     cbNew  The new block size.
    656660 */
     
    660664    PHEAPANCHOR pha;
    661665
     666    #ifdef ALLWAYS_HEAPCHECK
     667        if (!_res_heap_check())
     668        {
     669            kprintf(("rmalloc: _res_heap_check failed!\n"));
     670            return NULL;
     671        }
     672    #endif
    662673    pmb = resFindUsedBlock(SSToDS(&pha), pv);
    663674    if (pmb != NULL)
     
    665676        void *pvRet;
    666677
    667         cbNew = ALIGN(cbNew, 4);
     678        cbNew = MAX(ALIGN(cbNew, ALIGNMENT), sizeof(MEMBLOCKFREE) - CB_HDR);
    668679        if (cbNew <= pmb->cbSize)
    669680        {   /* shrink block */
     
    671682            if (cbNew + sizeof(MEMBLOCKFREE) <= pmb->cbSize)
    672683            {   /* split block */
    673                 PMEMBLOCK pmbNew = (PMEMBLOCK)((unsigned)pmb + CB_HDR + cbNew);
     684                PMEMBLOCKFREE pmbfNew = (PMEMBLOCKFREE)((unsigned)pmb + CB_HDR + cbNew);
    674685                #ifdef DEBUG_ALLOC
    675                     pmbNew->ulSignature = MEMBLOCK_SIGNATURE;
     686                    pmbfNew->ulSignature = MEMBLOCK_SIGNATURE;
    676687                #endif
    677                 pmbNew->cbSize = pmb->cbSize - cbNew - CB_HDR;
     688                pha->cbUsed -= pmb->cbSize - cbNew;
     689                pmbfNew->coreFree.Key = pmb->cbSize - cbNew - CB_HDR;
    678690                pmb->cbSize = cbNew;
    679                 resInsertFree(pha, pmbNew);
     691                resInsertFree(pha, (PMEMBLOCK)pmbfNew);
     692                #ifdef ALLWAYS_HEAPCHECK
     693                    if (!_res_heap_check())
     694                    {
     695                        kprintf(("rrealloc: _res_heap_check failed!\n"));
     696                        return NULL;
     697                    }
     698                #endif
    680699            }
    681700        }
    682701        else
    683702        {   /* expand block - this code may be more optimized... */
    684             pvRet = rmalloc(cbNew);
    685             if (pvRet != NULL)
    686             {
    687                 memcpy(pvRet, pv, pmb->cbSize);
    688                 rfree(pv);
    689             }
     703            #if 1
     704                pvRet = rmalloc(cbNew);
     705                if (pvRet != NULL)
     706                {
     707                    memcpy(pvRet, pv, pmb->cbSize);
     708                    rfree(pv);
     709                }
     710            #else
     711                /* optimized */
     712                PMEMBLOCK pmb
     713            #endif
    690714        }
    691715        return pvRet;
     716    }
     717    else
     718    {
     719        if (pv == NULL)
     720            return rmalloc(cbNew);
     721        kprintf(("rrealloc: invalid user pointer, pv=0x%08x\n", pv));
    692722    }
    693723    return NULL;
     
    855885        {
    856886            kprintf(("_res_heap_check: invalid signature for pha=0x%08x\n", pha));
     887            Int3();
    857888            return FALSE;
    858889        }
     
    861892        {
    862893            kprintf(("_res_heap_check: cbFree + cbUsed >= cbSize for pha=0x%08x\n", pha));
     894            Int3();
    863895            return FALSE;
    864896        }
     
    867899        {
    868900            kprintf(("_res_heap_check: error in heap anchor chain.\n"));
     901            Int3();
    869902            return FALSE;
    870903        }
     
    875908                     "    block. pmbFree=0x%08x, pmbUsed=0x%08x, pha+1=0x%08x\n",
    876909                     pmbFree, pmbUsed, pha+1));
     910            Int3();
     911            return FALSE;
     912        }
     913
     914        /*
     915         * Check the tree AVL-trees - !extra debug test!
     916         */
     917        if (resCheckAVLTree(pha->pmbUsed) != 0)
     918        {
     919            kprintf(("_res_heap_check: the Used tree is invalid.\n"));
     920            Int3();
     921            return FALSE;
     922        }
     923        if (resCheckAVLTree(pha->pmbFree) != 0)
     924        {
     925            kprintf(("_res_heap_check: the Free tree is invalid.\n"));
     926            Int3();
     927            return FALSE;
     928        }
     929        if (resCheckAVLTreeFree(pha->pcoreFreeSize) != 0)
     930        {
     931            kprintf(("_res_heap_check: the free-size tree is invalid.\n"));
     932            Int3();
    877933            return FALSE;
    878934        }
     
    905961                /* error hole */
    906962                kprintf(("_res_heap_check: internal error - memory hole!\n"));
     963                Int3();
    907964                return FALSE;
    908965                }
     
    914971                cbUsed += pmbUsed->cbSize;
    915972                if (pmbUsed->ulSignature != MEMBLOCK_SIGNATURE)
     973                {
     974                    kprintf(("_res_heap_check: invalid signature on used block, pmbUsed=0x%08x\n", pmbUsed));
     975                    Int3();
    916976                    return FALSE;
     977                }
     978                if (pmbUsed->cbSize < sizeof(MEMBLOCKFREE) - CB_HDR)
     979                {
     980                    kprintf(("_res_heap_check: internal error - cbSize is to small! (used), cbSize=%d\n", pmbUsed->cbSize));
     981                    Int3();
     982                    return FALSE;
     983                }
    917984                pmbLast = pmbUsed;
    918985                pmbUsed = pmbUsedNext;
     
    921988            else
    922989            {
     990                PMEMBLOCKFREE pmbf = (PMEMBLOCKFREE)AVLGet((PPAVLNODECORE)&pha->pcoreFreeSize, pmbFree->cbSize);
     991                if (pmbf != NULL)
     992                {
     993                    pmbf = MEMBLOCKFREE_FROM_FREESIZENODE(pmbf);
     994                    while (pmbf != NULL && pmbf != (PMEMBLOCKFREE)pmbFree)
     995                        pmbf = pmbf->pmbfNext;
     996                    if (pmbf == NULL)
     997                    {
     998                        kprintf(("_res_heap_check: pmbFree=0x%08 is not found in the free-size-tree.\n", pmbFree));
     999                        Int3();
     1000                        return FALSE;
     1001                    }
     1002                }
     1003                else
     1004                {
     1005                    kprintf(("_res_heap_check: pmbFree=0x%08 is not found in the free-size-tree.\n", pmbFree));
     1006                    Int3();
     1007                    return FALSE;
     1008                }
     1009
    9231010                cbSize += CB_HDR + pmbFree->cbSize;
    9241011                cbFree += pmbFree->cbSize;
    9251012                if (pmbFree->ulSignature != MEMBLOCK_SIGNATURE)
     1013                {
     1014                    kprintf(("_res_heap_check: invalid signature on free block, pmbUsed=0x%08x\n", pmbFree));
     1015                    Int3();
    9261016                    return FALSE;
     1017                }
     1018                if (pmbFree->cbSize < sizeof(MEMBLOCKFREE) - CB_HDR)
     1019                {
     1020                    kprintf(("_res_heap_check: internal error - cbSize is to small! (free), cbSize=%d\n", pmbFree->cbSize));
     1021                    Int3();
     1022                    return FALSE;
     1023                }
    9271024                pmbLast = pmbFree;
    9281025                pmbFree = pmbFreeNext;
     
    9381035        {
    9391036            kprintf(("_res_heap_check: cbFree(%d) != pha->cbFree(%d)\n", cbFree, pha->cbFree));
     1037            Int3();
    9401038            return FALSE;
    9411039        }
     
    9441042        {
    9451043            kprintf(("_res_heap_check: cbUsed(%d) != pha->cbUsed(%d)\n", cbUsed, pha->cbUsed));
     1044            Int3();
    9461045            return FALSE;
    9471046        }
     
    9501049        {
    9511050            kprintf(("_res_heap_check: cbTotal(%d) != pha->cbSize(%d)\n", cbSize, pha->cbSize));
     1051            Int3();
    9521052            return FALSE;
    9531053        }
     
    9601060                     "    pmbLast(end)=0x%08x, pha+pha->cbSize=0x%08x\n",
    9611061                     pmbLast != NULL ? PNEXT_BLOCK(pmbLast) : NULL, (unsigned)pha + pha->cbSize));
     1062            Int3();
    9621063            return FALSE;
    9631064        }
     
    9751076    {
    9761077        kprintf(("_res_heap_check: internal error - heap anchor chain didn't end on phaLast\n"));
     1078        Int3();
    9771079        return FALSE;
    9781080    }
     
    9831085}
    9841086
     1087
     1088/**
     1089 * Check the integrity of the a Free/Used AVL tree where Key == node pointer.
     1090 */
     1091static int resCheckAVLTree(PMEMBLOCK pmb)
     1092{
     1093    if (pmb == NULL)
     1094        return 0;
     1095    if (pmb->core.Key != (AVLKEY)pmb)
     1096    {
     1097        kprintf(("resCheckAVLTree: Invalid Key!\n"));
     1098        Int3();
     1099        return -1;
     1100    }
     1101    if (pmb->core.pLeft != NULL && (pmb->core.pLeft < (PAVLNODECORE)0x10000 || pmb->core.Key <= (AVLKEY)pmb->core.pLeft))
     1102    {
     1103        kprintf(("resCheckAVLTree: Invalid pLeft!\n"));
     1104        Int3();
     1105        return -1;
     1106    }
     1107    if (pmb->core.pRight != NULL && (pmb->core.pRight < (PAVLNODECORE)0x10000 || pmb->core.Key >= (AVLKEY)pmb->core.pRight))
     1108    {
     1109        kprintf(("resCheckAVLTree: Invalid pRight!\n"));
     1110        Int3();
     1111        return -1;
     1112    }
     1113    if (pmb->core.pLeft != NULL && resCheckAVLTree((PMEMBLOCK)pmb->core.pLeft) != 0)
     1114        return -1;
     1115    if (pmb->core.pRight != NULL && resCheckAVLTree((PMEMBLOCK)pmb->core.pRight) != 0)
     1116        return -1;
     1117    return 0;
     1118}
     1119
     1120
     1121/**
     1122 * Check the integrity of the a Free/Used AVL tree where Key == node pointer.
     1123 */
     1124static int resCheckAVLTreeFree(PAVLNODECORE pNode)
     1125{
     1126    PMEMBLOCKFREE pmbf;
     1127    if (pNode == NULL)
     1128        return 0;
     1129    if (pNode->Key < 4 || (pNode->Key % 4) != 0)
     1130    {
     1131        kprintf(("resCheckAVLTreeFree: Invalid Key! 0x%08x\n", pNode->Key));
     1132        Int3();
     1133        return -1;
     1134    }
     1135    if (pNode->pLeft != NULL && (pNode->pLeft < (PAVLNODECORE)0x10000 || pNode->Key <= pNode->pLeft->Key))
     1136    {
     1137        kprintf(("resCheckAVLTreeFree: Invalid pLeft!\n"));
     1138        Int3();
     1139        return -1;
     1140    }
     1141    if (pNode->pRight != NULL && (pNode->pRight < (PAVLNODECORE)0x10000 || pNode->Key >= pNode->pRight->Key))
     1142    {
     1143        kprintf(("resCheckAVLTreeFree: Invalid pRight!\n"));
     1144        Int3();
     1145        return -1;
     1146    }
     1147    pmbf = MEMBLOCKFREE_FROM_FREESIZENODE(pNode);
     1148    if (pmbf->pmbfNext != NULL && pmbf->pmbfNext < (PMEMBLOCKFREE)0x10000)
     1149    {
     1150        kprintf(("resCheckAVLTreeFree: invalid pmbfNext pointer, pmbfNext=0x%08x\n", pmbf->pmbfNext));
     1151        Int3();
     1152        return -1;
     1153    }
     1154    while (pmbf->pmbfNext != NULL)
     1155    {
     1156        if (pmbf->pmbfNext < (PMEMBLOCKFREE)0x10000)
     1157        {
     1158            kprintf(("resCheckAVLTreeFree: invalid pmbfNext pointer, pmbfNext=0x%08x\n", pmbf->pmbfNext));
     1159            Int3();
     1160            return -1;
     1161        }
     1162        if (pmbf->coreFree.Key != pNode->Key)
     1163        {
     1164            kprintf(("resCheckAVLTreeFree: invalid key, pmbf->coreFree.Key=%d, pNode->Key=%d\n", pmbf->coreFree.Key, pNode->Key));
     1165            Int3();
     1166            return -1;
     1167        }
     1168        /* next */
     1169        pmbf = pmbf->pmbfNext;
     1170    }
     1171
     1172    if (pNode->pLeft != NULL && resCheckAVLTreeFree(pNode->pLeft) != 0)
     1173        return -1;
     1174    if (pNode->pRight != NULL && resCheckAVLTreeFree(pNode->pRight) != 0)
     1175        return -1;
     1176    return 0;
     1177}
    9851178
    9861179
Note: See TracChangeset for help on using the changeset viewer.