Changeset 2503 for trunk/src/win32k/misc/rmalloc_avl.c
- Timestamp:
- Jan 23, 2000, 4:20:53 AM (26 years ago)
- 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 $ 2 2 * 3 3 * Resident Heap - AVL. … … 18 18 #ifdef DEBUG 19 19 #define DEBUG_ALLOC 20 # defineALLWAYS_HEAPCHECK20 #undef ALLWAYS_HEAPCHECK 21 21 #endif 22 22 … … 31 31 ((PMEMBLOCKFREE)((unsigned)(a) - CB_HDR + 4)) 32 32 #define BLOCKSIZE (1024*256) /* 256KB */ 33 33 #define ALIGNMENT 4 34 34 35 35 #define INCL_DOS … … 139 139 static PMEMBLOCK resFindUsedBlock(PHEAPANCHOR *ppha, void *pvUser); 140 140 static PMEMBLOCK resFindWithinUsedBlock(PHEAPANCHOR *ppha, void *pvUser); 141 static int resCheckAVLTree(PMEMBLOCK pmb); 142 static int resCheckAVLTreeFree(PAVLNODECORE pNode); 141 143 static unsigned _res_dump_subheaps_callback(PMEMBLOCK pmb, PSUBHEAPS_CALLBACK_PARAM pCb); 142 144 static unsigned _res_dump_allocated_callback(PMEMBLOCK pmb, PALLOCATED_CALLBACK_PARAM pParam); … … 193 195 else 194 196 { /* 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)); 197 198 if (pmbfParent != NULL) 198 199 { 199 200 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; 202 203 else 203 pmbfParent->coreFree.pRight = (PAVLNODECORE) pmbf->pmbfNext;204 pmbfParent->coreFree.pRight = (PAVLNODECORE)&pmbf->pmbfNext->coreFree; 204 205 } 205 206 else 206 pha->pcoreFreeSize = (PAVLNODECORE) pmbf->pmbfNext;207 pha->pcoreFreeSize = (PAVLNODECORE)&pmbf->pmbfNext->coreFree; 207 208 } 208 209 } … … 231 232 } 232 233 else 234 { 235 pmbf->pmbfNext = NULL; 233 236 AVLInsert((PPAVLNODECORE)&pha->pcoreFreeSize, &pmbf->coreFree); 237 } 234 238 } 235 239 … … 271 275 if (pmbfLeft == NULL && pmbfRight == NULL) 272 276 { /* 1 - insert no merge */ 277 pmbf->core.Key = (AVLKEY)pmbf; 273 278 AVLInsert((PPAVLNODECORE)&pha->pmbFree, (PAVLNODECORE)pmbf); 274 279 resInsertIntoFreeSize(pha, pmbf); 275 280 } 276 281 else if (pmbfLeft != NULL && pmbfRight == NULL) 277 { /* 2 - insert left merge */282 { /* 2 - insert left merge: just add pmbf to pmbfLeft. */ 278 283 resRemoveFromFreeSize(pha, pmbfLeft); 279 284 pmbfLeft->coreFree.Key += CB_HDR + pmbf->coreFree.Key; … … 282 287 } 283 288 else if (pmbfLeft == NULL && pmbfRight != NULL) 284 { /* 3 - insert right merge */289 { /* 3 - insert right merge: replace pmbfRight with pmbf in the pmbfFree tree; */ 285 290 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)); 288 292 pmbf->core.Key = (AVLKEY)pmbf; 289 293 pmbf->coreFree.Key += CB_HDR + pmbfRight->coreFree.Key; … … 302 306 else 303 307 { /* 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 } 304 313 resRemoveFromFreeSize(pha, pmbfLeft); 305 314 resRemoveFromFreeSize(pha, pmbfRight); 306 pmbfRight = (PMEMBLOCKFREE)AVLRemove((PPAVLNODECORE)&pha->pmbFree,307 (AVLKEY)PNEXT_BLOCK(pmb));308 315 pmbfLeft->coreFree.Key += CB_HDR*2 + pmbf->coreFree.Key + pmbfRight->coreFree.Key; 309 316 pha->cbFree += CB_HDR*2; … … 328 335 unsigned cbTotalSize = 0; 329 336 330 cbUserSize = MAX(ALIGN(cbUserSize, 4), sizeof(MEMBLOCKFREE) - CB_HDR);337 cbUserSize = MAX(ALIGN(cbUserSize, ALIGNMENT), sizeof(MEMBLOCKFREE) - CB_HDR); 331 338 332 339 *ppha = phaFirst; … … 335 342 if ((*ppha)->cbFree >= cbUserSize + CB_HDR) 336 343 { 337 PMEMBLOCKFREE pmbfTmp;338 344 PMEMBLOCKFREE pmbf; 339 345 … … 342 348 { 343 349 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) 345 355 { 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); 351 365 } 352 366 else 353 367 { 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 } 371 374 } 372 375 return (PMEMBLOCK)pmbf; … … 653 656 * @returns Pointer to new heapblock. 654 657 * @param pv Pointer to the block to realloc. 658 * If pv is NULL, this call is equal to malloc. 655 659 * @param cbNew The new block size. 656 660 */ … … 660 664 PHEAPANCHOR pha; 661 665 666 #ifdef ALLWAYS_HEAPCHECK 667 if (!_res_heap_check()) 668 { 669 kprintf(("rmalloc: _res_heap_check failed!\n")); 670 return NULL; 671 } 672 #endif 662 673 pmb = resFindUsedBlock(SSToDS(&pha), pv); 663 674 if (pmb != NULL) … … 665 676 void *pvRet; 666 677 667 cbNew = ALIGN(cbNew, 4);678 cbNew = MAX(ALIGN(cbNew, ALIGNMENT), sizeof(MEMBLOCKFREE) - CB_HDR); 668 679 if (cbNew <= pmb->cbSize) 669 680 { /* shrink block */ … … 671 682 if (cbNew + sizeof(MEMBLOCKFREE) <= pmb->cbSize) 672 683 { /* split block */ 673 PMEMBLOCK pmbNew = (PMEMBLOCK)((unsigned)pmb + CB_HDR + cbNew);684 PMEMBLOCKFREE pmbfNew = (PMEMBLOCKFREE)((unsigned)pmb + CB_HDR + cbNew); 674 685 #ifdef DEBUG_ALLOC 675 pmb New->ulSignature = MEMBLOCK_SIGNATURE;686 pmbfNew->ulSignature = MEMBLOCK_SIGNATURE; 676 687 #endif 677 pmbNew->cbSize = pmb->cbSize - cbNew - CB_HDR; 688 pha->cbUsed -= pmb->cbSize - cbNew; 689 pmbfNew->coreFree.Key = pmb->cbSize - cbNew - CB_HDR; 678 690 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 680 699 } 681 700 } 682 701 else 683 702 { /* 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 690 714 } 691 715 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)); 692 722 } 693 723 return NULL; … … 855 885 { 856 886 kprintf(("_res_heap_check: invalid signature for pha=0x%08x\n", pha)); 887 Int3(); 857 888 return FALSE; 858 889 } … … 861 892 { 862 893 kprintf(("_res_heap_check: cbFree + cbUsed >= cbSize for pha=0x%08x\n", pha)); 894 Int3(); 863 895 return FALSE; 864 896 } … … 867 899 { 868 900 kprintf(("_res_heap_check: error in heap anchor chain.\n")); 901 Int3(); 869 902 return FALSE; 870 903 } … … 875 908 " block. pmbFree=0x%08x, pmbUsed=0x%08x, pha+1=0x%08x\n", 876 909 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(); 877 933 return FALSE; 878 934 } … … 905 961 /* error hole */ 906 962 kprintf(("_res_heap_check: internal error - memory hole!\n")); 963 Int3(); 907 964 return FALSE; 908 965 } … … 914 971 cbUsed += pmbUsed->cbSize; 915 972 if (pmbUsed->ulSignature != MEMBLOCK_SIGNATURE) 973 { 974 kprintf(("_res_heap_check: invalid signature on used block, pmbUsed=0x%08x\n", pmbUsed)); 975 Int3(); 916 976 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 } 917 984 pmbLast = pmbUsed; 918 985 pmbUsed = pmbUsedNext; … … 921 988 else 922 989 { 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 923 1010 cbSize += CB_HDR + pmbFree->cbSize; 924 1011 cbFree += pmbFree->cbSize; 925 1012 if (pmbFree->ulSignature != MEMBLOCK_SIGNATURE) 1013 { 1014 kprintf(("_res_heap_check: invalid signature on free block, pmbUsed=0x%08x\n", pmbFree)); 1015 Int3(); 926 1016 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 } 927 1024 pmbLast = pmbFree; 928 1025 pmbFree = pmbFreeNext; … … 938 1035 { 939 1036 kprintf(("_res_heap_check: cbFree(%d) != pha->cbFree(%d)\n", cbFree, pha->cbFree)); 1037 Int3(); 940 1038 return FALSE; 941 1039 } … … 944 1042 { 945 1043 kprintf(("_res_heap_check: cbUsed(%d) != pha->cbUsed(%d)\n", cbUsed, pha->cbUsed)); 1044 Int3(); 946 1045 return FALSE; 947 1046 } … … 950 1049 { 951 1050 kprintf(("_res_heap_check: cbTotal(%d) != pha->cbSize(%d)\n", cbSize, pha->cbSize)); 1051 Int3(); 952 1052 return FALSE; 953 1053 } … … 960 1060 " pmbLast(end)=0x%08x, pha+pha->cbSize=0x%08x\n", 961 1061 pmbLast != NULL ? PNEXT_BLOCK(pmbLast) : NULL, (unsigned)pha + pha->cbSize)); 1062 Int3(); 962 1063 return FALSE; 963 1064 } … … 975 1076 { 976 1077 kprintf(("_res_heap_check: internal error - heap anchor chain didn't end on phaLast\n")); 1078 Int3(); 977 1079 return FALSE; 978 1080 } … … 983 1085 } 984 1086 1087 1088 /** 1089 * Check the integrity of the a Free/Used AVL tree where Key == node pointer. 1090 */ 1091 static 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 */ 1124 static 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 } 985 1178 986 1179
Note:
See TracChangeset
for help on using the changeset viewer.