VirtualBox

Changeset 97924 in vbox for trunk


Ignore:
Timestamp:
Dec 30, 2022 10:49:43 PM (2 years ago)
Author:
vboxsync
Message:

Add/VBoxGuestR0LibPhysHeap.cpp: Same for VbglR0PhysHeapAlloc and made VbglR0PhysHeapFree properly invalidate the neighbour block after merging with it. Cleanups.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibPhysHeap.cpp

    r97923 r97924  
    215215
    216216
    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 
    235217DECLINLINE(void) vbglPhysHeapLeave(void)
    236218{
     
    239221
    240222
    241 static void vbglPhysHeapInitBlock(VBGLPHYSHEAPBLOCK *pBlock, VBGLPHYSHEAPCHUNK *pChunk, uint32_t cbDataSize)
     223static void vbglPhysHeapInitFreeBlock(VBGLPHYSHEAPBLOCK *pBlock, VBGLPHYSHEAPCHUNK *pChunk, uint32_t cbDataSize)
    242224{
    243225    VBGL_PH_ASSERT(pBlock != NULL);
     
    393375        /* Initialize the free block, which now occupies entire chunk. */
    394376        pBlock = (VBGLPHYSHEAPBLOCK *)(pChunk + 1);
    395         vbglPhysHeapInitBlock(pBlock, pChunk, cbChunk - sizeof(VBGLPHYSHEAPCHUNK) - sizeof(VBGLPHYSHEAPBLOCK));
     377        vbglPhysHeapInitFreeBlock(pBlock, pChunk, cbChunk - sizeof(VBGLPHYSHEAPCHUNK) - sizeof(VBGLPHYSHEAPBLOCK));
    396378        vbglPhysHeapInsertBlock(NULL, pBlock);
    397379
     
    461443     */
    462444    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);
    467450
    468451    dumpheap("pre alloc");
     
    472455     * there to be many blocks in the heap.
    473456     */
    474 
    475457    /** @todo r=bird: Don't walk these lists for ever, use the block count
    476458     *        statistics to limit the walking to the first X or something. */
     
    480462        /* Smaller than 3/4 page:  Prefer a free block that can keep the request within a single page,
    481463           so HGCM processing in VMMDev can use page locks instead of several reads and writes. */
    482 
    483464        VBGLPHYSHEAPBLOCK *pFallback = NULL;
    484465        for (pIter = g_vbgldata.pFreeBlocksHead; pIter != NULL; pIter = pIter->pNext)
     466        {
     467            AssertBreak(pIter->u32Signature == VBGL_PH_BLOCKSIGNATURE);
    485468            if (pIter->cbDataSize >= cbSize)
    486469            {
    487470                if (pIter->cbDataSize == cbSize)
    488471                {
    489                     if (PAGE_SIZE - ((uintptr_t)vbglPhysHeapBlock2Data(pIter) & PAGE_OFFSET_MASK) >= cbSize)
     472                    if (PAGE_SIZE - ((uintptr_t)(pIter + 1) & PAGE_OFFSET_MASK) >= cbSize)
    490473                    {
    491474                        pBlock = pIter;
     
    498481                    if (!pFallback || pIter->cbDataSize < pFallback->cbDataSize)
    499482                        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)
    501484                        if (!pBlock || pIter->cbDataSize < pBlock->cbDataSize)
    502485                            pBlock = pIter;
    503486                }
    504487            }
     488        }
    505489
    506490        if (!pBlock)
     
    509493    else
    510494    {
    511         /* Large than 3/4 page:  Find smallest free list match. */
    512 
     495        /* Large than 3/4 page:  Find closest free list match. */
    513496        for (pIter = g_vbgldata.pFreeBlocksHead; pIter != NULL; pIter = pIter->pNext)
     497        {
     498            AssertBreak(pIter->u32Signature == VBGL_PH_BLOCKSIGNATURE);
    514499            if (pIter->cbDataSize >= cbSize)
    515500            {
     
    525510                    pBlock = pIter;
    526511            }
     512        }
    527513    }
    528514
     
    536522    if (pBlock)
    537523    {
     524        /* We have a free block, either found or allocated. */
    538525        VBGL_PH_ASSERT_MSG(pBlock->u32Signature == VBGL_PH_BLOCKSIGNATURE,
    539526                           ("pBlock = %p, pBlock->u32Signature = %08X\n", pBlock, pBlock->u32Signature));
    540527        VBGL_PH_ASSERT_MSG(!pBlock->fAllocated, ("pBlock = %p\n", pBlock));
    541528
    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         */
    544535        if (pBlock->cbDataSize >= sizeof(VBGLPHYSHEAPBLOCK) * 2 + VBGL_PH_MIN_SPLIT_FREE_BLOCK + cbSize)
    545536        {
    546             /* Data will occupy less than a half of the block,
    547              * split off the tail end into a new free list entry.
    548              */
    549537            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));
    553539
    554540            pBlock->cbDataSize = cbSize;
    555541
    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. */
    557543            vbglPhysHeapInsertBlock(pBlock, pIter);
    558544        }
    559545
    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         */
    561550        vbglPhysHeapExcludeBlock(pBlock);
    562 
    563         /* Mark as allocated */
    564551        pBlock->fAllocated = true;
    565 
    566         /* Insert to allocated list */
    567552        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;
    576567}
    577568
     
    656647                pBlock->cbDataSize += pNeighbour->cbDataSize + sizeof(VBGLPHYSHEAPBLOCK);
    657648
    658                 /* Exclude the next neighbour */
     649                /* Unlink the following node and invalid it. */
    659650                vbglPhysHeapExcludeBlock(pNeighbour);
     651
     652                pNeighbour->u32Signature = ~VBGL_PH_BLOCKSIGNATURE;
     653                pNeighbour->cbDataSize   = UINT32_MAX / 4;
    660654
    661655                dumpheap("post merge");
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette