Changeset 77063 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Jan 30, 2019 8:03:23 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 128509
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibPhysHeap.cpp
r76553 r77063 404 404 DECLR0VBGL(void *) VbglR0PhysHeapAlloc (uint32_t cbSize) 405 405 { 406 VBGLPHYSHEAPBLOCK *pBlock, * iter;406 VBGLPHYSHEAPBLOCK *pBlock, *pIter; 407 407 int rc = vbglPhysHeapEnter (); 408 408 … … 412 412 dumpheap ("pre alloc"); 413 413 414 /* 415 * Search the free list. We do this in linear fashion as we don't expect 416 * there to be many blocks in the heap. 417 */ 418 414 419 pBlock = NULL; 415 416 /* If there are free blocks in the heap, look at them. */ 417 iter = g_vbgldata.pFreeBlocksHead; 418 419 /* There will be not many blocks in the heap, so 420 * linear search would be fast enough. 421 */ 422 423 while (iter) 424 { 425 if (iter->cbDataSize == cbSize) 426 { 427 /* exact match */ 428 pBlock = iter; 429 break; 430 } 431 432 /* Looking for a free block with nearest size */ 433 if (iter->cbDataSize > cbSize) 434 { 435 if (pBlock) 420 if (cbSize <= PAGE_SIZE / 4 * 3) 421 { 422 /* Smaller than 3/4 page: Prefer a free block that can keep the request within a single page, 423 so HGCM processing in VMMDev can use page locks instead of several reads and writes. */ 424 425 VBGLPHYSHEAPBLOCK *pFallback = NULL; 426 for (pIter = g_vbgldata.pFreeBlocksHead; pIter != NULL; pIter = pIter->pNext) 427 if (pIter->cbDataSize >= cbSize) 436 428 { 437 if ( iter->cbDataSize < pBlock->cbDataSize)429 if (pIter->cbDataSize == cbSize) 438 430 { 439 pBlock = iter; 431 if (PAGE_SIZE - ((uintptr_t)vbglPhysHeapBlock2Data(pIter) & PAGE_OFFSET_MASK) >= cbSize) 432 { 433 pBlock = pIter; 434 break; 435 } 436 pFallback = pIter; 437 } 438 else 439 { 440 if (!pFallback || pIter->cbDataSize < pFallback->cbDataSize) 441 pFallback = pIter; 442 if (PAGE_SIZE - ((uintptr_t)vbglPhysHeapBlock2Data(pIter) & PAGE_OFFSET_MASK) >= cbSize) 443 if (!pBlock || pIter->cbDataSize < pBlock->cbDataSize) 444 pBlock = pIter; 440 445 } 441 446 } 442 else 447 448 if (!pBlock) 449 pBlock = pFallback; 450 } 451 else 452 { 453 /* Large than 3/4 page: Find smallest free list match. */ 454 455 for (pIter = g_vbgldata.pFreeBlocksHead; pIter != NULL; pIter = pIter->pNext) 456 if (pIter->cbDataSize >= cbSize) 443 457 { 444 pBlock = iter; 458 if (pIter->cbDataSize == cbSize) 459 { 460 /* Exact match - we're done! */ 461 pBlock = pIter; 462 break; 463 } 464 465 /* Looking for a free block with nearest size. */ 466 if (!pBlock || pIter->cbDataSize < pBlock->cbDataSize) 467 pBlock = pIter; 445 468 } 446 }447 448 iter = iter->pNext;449 469 } 450 470 … … 470 490 { 471 491 /* Data will occupy less than a half of the block, 472 * the block should be split.492 * split off the tail end into a new free list entry. 473 493 */ 474 iter = (VBGLPHYSHEAPBLOCK *)((char *)pBlock + sizeof (VBGLPHYSHEAPBLOCK) + cbSize);475 476 /* Init the new ' iter' block, initialized blocks are always marked as free. */477 vbglPhysHeapInitBlock ( iter, pBlock->pChunk, pBlock->cbDataSize - cbSize - sizeof (VBGLPHYSHEAPBLOCK));494 pIter = (VBGLPHYSHEAPBLOCK *)((char *)pBlock + sizeof (VBGLPHYSHEAPBLOCK) + cbSize); 495 496 /* Init the new 'pIter' block, initialized blocks are always marked as free. */ 497 vbglPhysHeapInitBlock (pIter, pBlock->pChunk, pBlock->cbDataSize - cbSize - sizeof (VBGLPHYSHEAPBLOCK)); 478 498 479 499 pBlock->cbDataSize = cbSize; 480 500 481 /* Insert the new ' iter' block after the 'pBlock' in the free list */482 vbglPhysHeapInsertBlock (pBlock, iter);501 /* Insert the new 'pIter' block after the 'pBlock' in the free list */ 502 vbglPhysHeapInsertBlock (pBlock, pIter); 483 503 } 484 504
Note:
See TracChangeset
for help on using the changeset viewer.