Changeset 97921 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Dec 30, 2022 9:15:10 PM (2 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxGuest/lib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibInternal.h
r97913 r97921 119 119 /** 120 120 * Global VBGL ring-0 data. 121 * Lives in V bglR0Init.cpp.121 * Lives in VBoxGuestR0LibInit.cpp. 122 122 */ 123 123 typedef struct VBGLDATA … … 132 132 * @{ 133 133 */ 134 RTSEMFASTMUTEX mutexHeap; 134 135 VBGLPHYSHEAPBLOCK *pFreeBlocksHead; 135 136 VBGLPHYSHEAPBLOCK *pAllocBlocksHead; 137 /** Indexed by VBGLPHYSHEAPBLOCK::fAllocated, so zero is the free ones and 138 * one the allocated ones. */ 139 int32_t acBlocks[2]; 136 140 VBGLPHYSHEAPCHUNK *pChunkHead; 137 138 RTSEMFASTMUTEX mutexHeap;139 141 /** @} */ 140 142 -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibPhysHeap.cpp
r97919 r97921 145 145 uint32_t physAddr; 146 146 147 /** Number of allocated blocks in the chunk */ 148 int32_t cAllocatedBlocks; 147 uint32_t uPadding1; 148 149 /** Indexed by VBGLPHYSHEAPBLOCK::fAllocated, so zero is the free ones and 150 * one the allocated ones. */ 151 int32_t acBlocks[2]; 149 152 150 153 /** Pointer to the next chunk. */ … … 152 155 /** Pointer to the previous chunk. */ 153 156 VBGLPHYSHEAPCHUNK *pPrev; 157 #if ARCH_BITS == 64 158 /** Pad the size up to 64 bytes. */ 159 uintptr_t auPadding2[3]; 160 #endif 154 161 }; 162 #if ARCH_BITS == 64 163 AssertCompileSize(VBGLPHYSHEAPCHUNK, 64); 164 #endif 155 165 156 166 … … 257 267 258 268 269 /** 270 * Links @a pBlock onto the appropriate chain accoring to @a pInsertAfter or @a 271 * pBlock->fAllocated. 272 * 273 * This also update the per-chunk block counts. 274 */ 259 275 static void vbglPhysHeapInsertBlock(VBGLPHYSHEAPBLOCK *pInsertAfter, VBGLPHYSHEAPBLOCK *pBlock) 260 276 { 277 bool const fAllocated = pBlock->fAllocated; 278 261 279 VBGL_PH_ASSERT_MSG(pBlock->pNext == NULL, ("pBlock->pNext = %p\n", pBlock->pNext)); 262 280 VBGL_PH_ASSERT_MSG(pBlock->pPrev == NULL, ("pBlock->pPrev = %p\n", pBlock->pPrev)); … … 277 295 pBlock->pPrev = NULL; 278 296 279 if ( pBlock->fAllocated)297 if (fAllocated) 280 298 { 281 299 pBlock->pNext = g_vbgldata.pAllocBlocksHead; … … 296 314 } 297 315 } 316 317 /* Update the block counts: */ 318 g_vbgldata.acBlocks[fAllocated] += 1; 319 pBlock->pChunk->acBlocks[fAllocated] += 1; 320 AssertMsg( (uint32_t)pBlock->pChunk->acBlocks[fAllocated] 321 <= pBlock->pChunk->cbSize / (sizeof(*pBlock) + sizeof(void *)), 322 ("pChunk=%p: cbSize=%#x acBlocks[%u]=%d\n", 323 pBlock->pChunk, pBlock->pChunk->cbSize, pBlock->pChunk->acBlocks[fAllocated])); 298 324 } 299 325 300 326 301 327 /** 302 * Unlinks @a pBlock from the chain its on. 328 * Unlinks @a pBlock from the chain it's on. 329 * 330 * This also update the per-chunk block counts. 303 331 */ 304 332 static void vbglPhysHeapExcludeBlock(VBGLPHYSHEAPBLOCK *pBlock) 305 333 { 334 bool const fAllocated = pBlock->fAllocated; 335 306 336 if (pBlock->pNext) 307 337 pBlock->pNext->pPrev = pBlock->pPrev; … … 310 340 if (pBlock->pPrev) 311 341 pBlock->pPrev->pNext = pBlock->pNext; 312 else if ( pBlock->fAllocated)342 else if (fAllocated) 313 343 { 314 344 Assert(g_vbgldata.pAllocBlocksHead == pBlock); … … 323 353 pBlock->pNext = NULL; 324 354 pBlock->pPrev = NULL; 325 } 355 356 /* Update the per-chunk counts: */ 357 g_vbgldata.acBlocks[fAllocated] -= 1; 358 pBlock->pChunk->acBlocks[fAllocated] -= 1; 359 AssertMsg(pBlock->pChunk->acBlocks[fAllocated] >= 0, 360 ("pChunk=%p: cbSize=%#x acBlocks[%u]=%d\n", 361 pBlock->pChunk, pBlock->pChunk->cbSize, pBlock->pChunk->acBlocks[fAllocated])); 362 Assert(g_vbgldata.acBlocks[fAllocated] >= 0); 363 } 364 326 365 327 366 static VBGLPHYSHEAPBLOCK *vbglPhysHeapChunkAlloc(uint32_t cbMinBlock) … … 355 394 pChunk->cbSize = cbChunk; 356 395 pChunk->physAddr = (uint32_t)PhysAddr; 357 pChunk->cAllocatedBlocks = 0; 396 pChunk->acBlocks[0] = 0; 397 pChunk->acBlocks[1] = 0; 358 398 pChunk->pNext = NULL; 359 399 pChunk->pPrev = NULL; 400 pChunk->uPadding1 = UINT32_C(0xADDCAAA1); 401 #if ARCH_BITS == 64 402 pChunk->auPadding2[0] = UINT64_C(0xADDCAAA3ADDCAAA2); 403 pChunk->auPadding2[1] = UINT64_C(0xADDCAAA5ADDCAAA4); 404 pChunk->auPadding2[2] = UINT64_C(0xADDCAAA7ADDCAAA6); 405 #endif 360 406 361 407 /* Initialize the free block, which now occupies entire chunk. */ … … 532 578 /* Insert to allocated list */ 533 579 vbglPhysHeapInsertBlock(NULL, pBlock); 534 535 /* Adjust the chunk allocated blocks counter */536 pBlock->pChunk->cAllocatedBlocks++;537 580 } 538 581 … … 560 603 return physAddr; 561 604 } 605 562 606 563 607 DECLR0VBGL(void) VbglR0PhysHeapFree(void *pv) … … 571 615 return; 572 616 573 dumpheap 617 dumpheap("pre free"); 574 618 575 619 pBlock = vbglPhysHeapData2Block(pv); … … 598 642 dumpheap("post insert"); 599 643 600 /* Adjust the chunk allocated blocks counter */601 644 pChunk = pBlock->pChunk; 602 pChunk->cAllocatedBlocks--;603 604 VBGL_PH_ASSERT(pChunk->cAllocatedBlocks >= 0);605 645 606 646 /* Check if we can merge 2 free blocks. To simplify heap maintenance, … … 631 671 632 672 /* now check if there are 2 or more free (unused) chunks */ 633 if (pChunk-> cAllocatedBlocks== 0)673 if (pChunk->acBlocks[1 /*allocated*/] == 0) 634 674 { 635 675 VBGLPHYSHEAPCHUNK *pCurChunk; … … 640 680 { 641 681 Assert(pCurChunk->u32Signature == VBGL_PH_CHUNKSIGNATURE); 642 if (pCurChunk-> cAllocatedBlocks== 0)682 if (pCurChunk->acBlocks[1 /*allocated*/] == 0) 643 683 cUnusedChunks++; 644 684 } … … 687 727 } 688 728 729 730 /** 731 * Checks the heap, caller responsible for locking. 732 * 733 * @returns VINF_SUCCESS if okay, error status if not. 734 * @param pErrInfo Where to return more error details, optional. 735 */ 689 736 static int vbglR0PhysHeapCheckLocked(PRTERRINFO pErrInfo) 690 737 { … … 692 739 * Scan the blocks in each chunk. 693 740 */ 694 unsigned cTotalFreeBlocks = 0; 695 unsigned cTotalUsedBlocks = 0; 696 for (VBGLPHYSHEAPCHUNK *pCurChunk = g_vbgldata.pChunkHead; pCurChunk; pCurChunk = pCurChunk->pNext) 741 unsigned acTotalBlocks[2] = { 0, 0 }; 742 for (VBGLPHYSHEAPCHUNK *pCurChunk = g_vbgldata.pChunkHead, *pPrevChunk = NULL; pCurChunk; pCurChunk = pCurChunk->pNext) 697 743 { 698 744 AssertReturn(pCurChunk->u32Signature == VBGL_PH_CHUNKSIGNATURE, 699 RTErrInfoSetF(pErrInfo, VERR_INVALID_MAGIC, "pCurChunk=%p: magic=%#x\n", pCurChunk, pCurChunk->u32Signature)); 745 RTErrInfoSetF(pErrInfo, VERR_INVALID_MAGIC, "pCurChunk=%p: magic=%#x", pCurChunk, pCurChunk->u32Signature)); 746 AssertReturn(pCurChunk->pPrev == pPrevChunk, 747 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_2, 748 "pCurChunk=%p: pPrev=%p, expected %p", pCurChunk, pCurChunk->pPrev, pPrevChunk)); 700 749 701 750 uintptr_t const uEnd = (uintptr_t)pCurChunk + pCurChunk->cbSize; 702 751 const VBGLPHYSHEAPBLOCK *pCurBlock = (const VBGLPHYSHEAPBLOCK *)(pCurChunk + 1); 703 unsigned cUsedBlocks = 0;752 unsigned acBlocks[2] = { 0, 0 }; 704 753 while ((uintptr_t)pCurBlock < uEnd) 705 754 { 706 755 AssertReturn(pCurBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE, 707 756 RTErrInfoSetF(pErrInfo, VERR_INVALID_MAGIC, 708 "pCurBlock=%p: magic=%#x \n", pCurBlock, pCurBlock->u32Signature));757 "pCurBlock=%p: magic=%#x", pCurBlock, pCurBlock->u32Signature)); 709 758 AssertReturn(pCurBlock->pChunk == pCurChunk, 710 759 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_2, 711 "pCurBlock=%p: pChunk=%p, expected %p \n", pCurBlock, pCurBlock->pChunk, pCurChunk));712 AssertReturn( pCurBlock->cbDataSize >= 8760 "pCurBlock=%p: pChunk=%p, expected %p", pCurBlock, pCurBlock->pChunk, pCurChunk)); 761 AssertReturn( pCurBlock->cbDataSize >= sizeof(void *) 713 762 && pCurBlock->cbDataSize < _128M 714 763 && RT_ALIGN_32(pCurBlock->cbDataSize, sizeof(void *)) == pCurBlock->cbDataSize, 715 764 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_3, 716 "pCurBlock=%p: cbDataSize=%#x\n", pCurBlock, pCurBlock->cbDataSize)); 717 if (pCurBlock->fAllocated) 718 cUsedBlocks += 1; 719 else 720 cTotalFreeBlocks += 1; 765 "pCurBlock=%p: cbDataSize=%#x", pCurBlock, pCurBlock->cbDataSize)); 766 acBlocks[pCurBlock->fAllocated] += 1; 721 767 722 768 /* advance */ … … 725 771 AssertReturn((uintptr_t)pCurBlock == uEnd, 726 772 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_4, 727 "pCurBlock=%p uEnd=%p\n", pCurBlock, uEnd)); 728 AssertReturn(cUsedBlocks == (uint32_t)pCurChunk->cAllocatedBlocks, 773 "pCurBlock=%p uEnd=%p", pCurBlock, uEnd)); 774 775 acTotalBlocks[1] += acBlocks[1]; 776 AssertReturn(acBlocks[1] == (uint32_t)pCurChunk->acBlocks[1], 729 777 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_4, 730 "pCurChunk=%p: cAllocatedBlocks=%u, expected %u\n", 731 pCurChunk, pCurChunk->cAllocatedBlocks, cUsedBlocks)); 732 cTotalUsedBlocks += cUsedBlocks; 733 } 778 "pCurChunk=%p: cAllocatedBlocks=%u, expected %u", 779 pCurChunk, pCurChunk->acBlocks[1], acBlocks[1])); 780 781 acTotalBlocks[0] += acBlocks[0]; 782 AssertReturn(acBlocks[0] == (uint32_t)pCurChunk->acBlocks[0], 783 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_5, 784 "pCurChunk=%p: cFreeBlocks=%u, expected %u", 785 pCurChunk, pCurChunk->acBlocks[0], acBlocks[0])); 786 787 pPrevChunk = pCurChunk; 788 } 789 790 AssertReturn(acTotalBlocks[0] == (uint32_t)g_vbgldata.acBlocks[0], 791 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR, 792 "g_vbgldata.acBlocks[0]=%u, expected %u", g_vbgldata.acBlocks[0], acTotalBlocks[0])); 793 AssertReturn(acTotalBlocks[1] == (uint32_t)g_vbgldata.acBlocks[1], 794 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR, 795 "g_vbgldata.acBlocks[1]=%u, expected %u", g_vbgldata.acBlocks[1], acTotalBlocks[1])); 796 797 /* 798 * Count each list and check that they contain the same number of nodes. 799 */ 800 VBGLPHYSHEAPBLOCK *apHeads[2] = { g_vbgldata.pFreeBlocksHead, g_vbgldata.pAllocBlocksHead }; 801 for (unsigned iType = 0; iType < RT_ELEMENTS(apHeads); iType++) 802 { 803 unsigned cBlocks = 0; 804 VBGLPHYSHEAPBLOCK *pPrevBlock = NULL; 805 for (VBGLPHYSHEAPBLOCK *pCurBlock = apHeads[iType]; pCurBlock; pCurBlock = pCurBlock->pNext) 806 { 807 AssertReturn(pCurBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE, 808 RTErrInfoSetF(pErrInfo, VERR_INVALID_MAGIC, 809 "pCurBlock=%p/%u: magic=%#x", pCurBlock, iType, pCurBlock->u32Signature)); 810 AssertReturn(pCurBlock->pPrev == pPrevBlock, 811 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_2, 812 "pCurBlock=%p/%u: pPrev=%p, expected %p", pCurBlock, iType, pCurBlock->pPrev, pPrevBlock)); 813 AssertReturn(pCurBlock->pChunk->u32Signature == VBGL_PH_CHUNKSIGNATURE, 814 RTErrInfoSetF(pErrInfo, VERR_INVALID_MAGIC, "pCurBlock=%p/%u: chunk (%p) magic=%#x", 815 pCurBlock, iType, pCurBlock->pChunk, pCurBlock->pChunk->u32Signature)); 816 cBlocks++; 817 pPrevBlock = pCurBlock; 818 } 819 820 AssertReturn(cBlocks == acTotalBlocks[iType], 821 RTErrInfoSetF(pErrInfo, VERR_INTERNAL_ERROR_3, 822 "iType=%u: Found %u in list, expected %u", iType, cBlocks, acTotalBlocks[iType])); 823 } 824 734 825 return VINF_SUCCESS; 735 826 } 827 736 828 737 829 /** … … 739 831 * 740 832 * @returns Problem description on failure, NULL on success. 833 * @param pErrInfo Where to return more error details, optional. 741 834 */ 742 835 DECLVBGL(int) VbglR0PhysHeapCheck(PRTERRINFO pErrInfo) … … 751 844 } 752 845 753 754 846 #endif /* IN_TESTCASE */ 755 756 847 757 848 DECLR0VBGL(int) VbglR0PhysHeapInit(void) -
trunk/src/VBox/Additions/common/VBoxGuest/lib/testcase/tstVbglR0PhysHeap-1.cpp
r97913 r97921 345 345 s_aHistory[i].pv = NULL; 346 346 } 347 RTTestIPrintf(RTTESTLVL_ALWAYS, "after free-all: cFreeBlocks=%u in %u chunk(s)\n", g_vbgldata.acBlocks[0], g_cChunks); 347 348 RTTESTI_CHECK_MSG(g_cChunks == 1, ("g_cChunks=%d\n", g_cChunks)); 349 RTTESTI_CHECK_MSG(g_vbgldata.acBlocks[1] == 0, ("g_vbgldata.acBlocks[1]=%d\n", g_vbgldata.acBlocks[0])); 348 350 #if 0 349 351 for (VBGLPHYSHEAPCHUNK *pCurChunk = g_vbgldata.pChunkHead; pCurChunk; pCurChunk = pCurChunk->pNext)
Note:
See TracChangeset
for help on using the changeset viewer.