- Timestamp:
- Dec 30, 2022 10:49:43 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibPhysHeap.cpp
r97923 r97924 215 215 216 216 217 DECLINLINE(void *) vbglPhysHeapBlock2Data(VBGLPHYSHEAPBLOCK *pBlock)218 {219 if (pBlock)220 return pBlock + 1;221 return NULL;222 }223 224 225 DECLINLINE(int) vbglPhysHeapEnter(void)226 {227 int rc = RTSemFastMutexRequest(g_vbgldata.mutexHeap);228 229 VBGL_PH_ASSERT_MSG(RT_SUCCESS(rc), ("Failed to request heap mutex, rc = %Rrc\n", rc));230 231 return rc;232 }233 234 235 217 DECLINLINE(void) vbglPhysHeapLeave(void) 236 218 { … … 239 221 240 222 241 static void vbglPhysHeapInit Block(VBGLPHYSHEAPBLOCK *pBlock, VBGLPHYSHEAPCHUNK *pChunk, uint32_t cbDataSize)223 static void vbglPhysHeapInitFreeBlock(VBGLPHYSHEAPBLOCK *pBlock, VBGLPHYSHEAPCHUNK *pChunk, uint32_t cbDataSize) 242 224 { 243 225 VBGL_PH_ASSERT(pBlock != NULL); … … 393 375 /* Initialize the free block, which now occupies entire chunk. */ 394 376 pBlock = (VBGLPHYSHEAPBLOCK *)(pChunk + 1); 395 vbglPhysHeapInit Block(pBlock, pChunk, cbChunk - sizeof(VBGLPHYSHEAPCHUNK) - sizeof(VBGLPHYSHEAPBLOCK));377 vbglPhysHeapInitFreeBlock(pBlock, pChunk, cbChunk - sizeof(VBGLPHYSHEAPCHUNK) - sizeof(VBGLPHYSHEAPBLOCK)); 396 378 vbglPhysHeapInsertBlock(NULL, pBlock); 397 379 … … 461 443 */ 462 444 cbSize = RT_ALIGN_32(cbSize, sizeof(void *)); 463 464 rc = vbglPhysHeapEnter(); 465 if (RT_FAILURE(rc)) 466 return NULL; 445 AssertStmt(cbSize > 0, cbSize = sizeof(void *)); /* avoid allocating zero bytes */ 446 447 448 rc = RTSemFastMutexRequest(g_vbgldata.mutexHeap); 449 AssertRCReturn(rc, NULL); 467 450 468 451 dumpheap("pre alloc"); … … 472 455 * there to be many blocks in the heap. 473 456 */ 474 475 457 /** @todo r=bird: Don't walk these lists for ever, use the block count 476 458 * statistics to limit the walking to the first X or something. */ … … 480 462 /* Smaller than 3/4 page: Prefer a free block that can keep the request within a single page, 481 463 so HGCM processing in VMMDev can use page locks instead of several reads and writes. */ 482 483 464 VBGLPHYSHEAPBLOCK *pFallback = NULL; 484 465 for (pIter = g_vbgldata.pFreeBlocksHead; pIter != NULL; pIter = pIter->pNext) 466 { 467 AssertBreak(pIter->u32Signature == VBGL_PH_BLOCKSIGNATURE); 485 468 if (pIter->cbDataSize >= cbSize) 486 469 { 487 470 if (pIter->cbDataSize == cbSize) 488 471 { 489 if (PAGE_SIZE - ((uintptr_t) vbglPhysHeapBlock2Data(pIter) & PAGE_OFFSET_MASK) >= cbSize)472 if (PAGE_SIZE - ((uintptr_t)(pIter + 1) & PAGE_OFFSET_MASK) >= cbSize) 490 473 { 491 474 pBlock = pIter; … … 498 481 if (!pFallback || pIter->cbDataSize < pFallback->cbDataSize) 499 482 pFallback = pIter; 500 if (PAGE_SIZE - ((uintptr_t) vbglPhysHeapBlock2Data(pIter) & PAGE_OFFSET_MASK) >= cbSize)483 if (PAGE_SIZE - ((uintptr_t)(pIter + 1) & PAGE_OFFSET_MASK) >= cbSize) 501 484 if (!pBlock || pIter->cbDataSize < pBlock->cbDataSize) 502 485 pBlock = pIter; 503 486 } 504 487 } 488 } 505 489 506 490 if (!pBlock) … … 509 493 else 510 494 { 511 /* Large than 3/4 page: Find smallest free list match. */ 512 495 /* Large than 3/4 page: Find closest free list match. */ 513 496 for (pIter = g_vbgldata.pFreeBlocksHead; pIter != NULL; pIter = pIter->pNext) 497 { 498 AssertBreak(pIter->u32Signature == VBGL_PH_BLOCKSIGNATURE); 514 499 if (pIter->cbDataSize >= cbSize) 515 500 { … … 525 510 pBlock = pIter; 526 511 } 512 } 527 513 } 528 514 … … 536 522 if (pBlock) 537 523 { 524 /* We have a free block, either found or allocated. */ 538 525 VBGL_PH_ASSERT_MSG(pBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE, 539 526 ("pBlock = %p, pBlock->u32Signature = %08X\n", pBlock, pBlock->u32Signature)); 540 527 VBGL_PH_ASSERT_MSG(!pBlock->fAllocated, ("pBlock = %p\n", pBlock)); 541 528 542 /* We have a free block, either found or allocated. */ 543 529 /* 530 * If the block is too large, split off a free block with the unused space. 531 * 532 * We do this before unlinking the block so we can preserve the location 533 * in the free list. 534 */ 544 535 if (pBlock->cbDataSize >= sizeof(VBGLPHYSHEAPBLOCK) * 2 + VBGL_PH_MIN_SPLIT_FREE_BLOCK + cbSize) 545 536 { 546 /* Data will occupy less than a half of the block,547 * split off the tail end into a new free list entry.548 */549 537 pIter = (VBGLPHYSHEAPBLOCK *)((uintptr_t)(pBlock + 1) + cbSize); 550 551 /* Init the new 'pIter' block, initialized blocks are always marked as free. */ 552 vbglPhysHeapInitBlock(pIter, pBlock->pChunk, pBlock->cbDataSize - cbSize - sizeof(VBGLPHYSHEAPBLOCK)); 538 vbglPhysHeapInitFreeBlock(pIter, pBlock->pChunk, pBlock->cbDataSize - cbSize - sizeof(VBGLPHYSHEAPBLOCK)); 553 539 554 540 pBlock->cbDataSize = cbSize; 555 541 556 /* Insert the new 'pIter' block after the 'pBlock' in the free list */542 /* Insert the new 'pIter' block after the 'pBlock' in the free list. */ 557 543 vbglPhysHeapInsertBlock(pBlock, pIter); 558 544 } 559 545 560 /* Exclude pBlock from free list */ 546 /* 547 * Unlink the block from the free list, mark it as allocated and insert 548 * it in the allocated list. 549 */ 561 550 vbglPhysHeapExcludeBlock(pBlock); 562 563 /* Mark as allocated */564 551 pBlock->fAllocated = true; 565 566 /* Insert to allocated list */567 552 vbglPhysHeapInsertBlock(NULL, pBlock); 568 } 569 570 dumpheap("post alloc"); 571 572 vbglPhysHeapLeave(); 573 VBGL_PH_dprintf(("VbglR0PhysHeapAlloc %x size %x\n", vbglPhysHeapBlock2Data(pBlock), pBlock->cbDataSize)); 574 575 return vbglPhysHeapBlock2Data(pBlock); 553 554 dumpheap("post alloc"); 555 556 rc = RTSemFastMutexRelease(g_vbgldata.mutexHeap); 557 558 VBGL_PH_dprintf(("VbglR0PhysHeapAlloc: returns %p size %x\n", pBlock + 1, pBlock->cbDataSize)); 559 return pBlock + 1; 560 } 561 562 rc = RTSemFastMutexRelease(g_vbgldata.mutexHeap); 563 AssertRC(rc); 564 565 VBGL_PH_dprintf(("VbglR0PhysHeapAlloc: returns NULL (requested %#x bytes)\n", cbSize)); 566 return NULL; 576 567 } 577 568 … … 656 647 pBlock->cbDataSize += pNeighbour->cbDataSize + sizeof(VBGLPHYSHEAPBLOCK); 657 648 658 /* Exclude the next neighbour*/649 /* Unlink the following node and invalid it. */ 659 650 vbglPhysHeapExcludeBlock(pNeighbour); 651 652 pNeighbour->u32Signature = ~VBGL_PH_BLOCKSIGNATURE; 653 pNeighbour->cbDataSize = UINT32_MAX / 4; 660 654 661 655 dumpheap("post merge");
Note:
See TracChangeset
for help on using the changeset viewer.