VirtualBox

Ignore:
Timestamp:
Apr 14, 2015 2:56:12 PM (10 years ago)
Author:
vboxsync
Message:

memcache.cpp: Fixed problem with the free list (unused).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/alloc/memcache.cpp

    r46257 r55252  
    8787    /** Bitmap tracking which blocks that has been thru the constructor. */
    8888    void volatile              *pbmCtor;
    89     /** Pointer to the object array.. */
     89    /** Pointer to the object array. */
    9090    uint8_t                    *pbObjects;
    9191    /** The number of objects on this page.  */
     
    150150
    151151
     152/*******************************************************************************
     153*   Internal Functions                                                         *
     154*******************************************************************************/
     155static void rtMemCacheFreeList(RTMEMCACHEINT *pThis, PRTMEMCACHEFREEOBJ pHead);
     156
    152157
    153158RTDECL(int) RTMemCacheCreate(PRTMEMCACHE phMemCache, size_t cbObject, size_t cbAlignment, uint32_t cMaxObjects,
     
    221226    pThis->pFreeTop         = NULL;
    222227
     228#if 1 /* should be fixed now, enable shortly... */
    223229    /** @todo
    224230     * Here is a puzzler (or maybe I'm just blind), the free list code breaks
     
    235241     * now. */
    236242    pThis->fUseFreeList = false;
     243#endif
    237244
    238245    *phMemCache = pThis;
     
    382389    if (pObj)
    383390    {
    384         do
    385         {
    386             PRTMEMCACHEFREEOBJ pNext = ASMAtomicUoReadPtrT(&pObj->pNext, PRTMEMCACHEFREEOBJ);
    387             PRTMEMCACHEFREEOBJ pObjOld;
    388             if (ASMAtomicCmpXchgExPtr(&pThis->pFreeTop, pNext, pObj, &pObjOld))
     391        pObj = ASMAtomicXchgPtrT(&pThis->pFreeTop, NULL, PRTMEMCACHEFREEOBJ);
     392        if (pObj)
     393        {
     394            if (pObj->pNext)
    389395            {
    390                 Assert(pObjOld == pObj);
    391                 Assert(pNext != pObjOld);
    392                 pObj->pNext = NULL;
    393                 *ppvObj = pObj;
    394                 return VINF_SUCCESS;
     396                Assert(pObj->pNext != pObj);
     397                PRTMEMCACHEFREEOBJ pAllocRace = ASMAtomicXchgPtrT(&pThis->pFreeTop, pObj->pNext, PRTMEMCACHEFREEOBJ);
     398                if (pAllocRace)
     399                    rtMemCacheFreeList(pThis, pAllocRace);
    395400            }
    396             pObj = pObjOld;
    397             ASMNopPause();
    398         } while (pObj);
     401
     402            pObj->pNext = NULL;
     403            *ppvObj = pObj;
     404            return VINF_SUCCESS;
     405        }
    399406    }
    400407
     
    502509
    503510
     511
     512/**
     513 * Really frees one object.
     514 *
     515 * @param   pThis               The memory cache.
     516 * @param   pvObj               The memory object to free.
     517 */
     518static void rtMemCacheFreeOne(RTMEMCACHEINT *pThis, void *pvObj)
     519{
     520    /* Note: Do *NOT* attempt to poison the object! */
     521
     522    /*
     523     * Find the cache page.  The page structure is at the start of the page.
     524     */
     525    PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)(((uintptr_t)pvObj) & ~(uintptr_t)PAGE_OFFSET_MASK);
     526    Assert(pPage->pCache == pThis);
     527    Assert(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);
     528
     529    /*
     530     * Clear the bitmap bit and update the two object counter. Order matters!
     531     */
     532    uintptr_t offObj = (uintptr_t)pvObj - (uintptr_t)pPage->pbObjects;
     533    uintptr_t iObj   = offObj / pThis->cbObject;
     534    Assert(iObj * pThis->cbObject == offObj);
     535    Assert(iObj < pThis->cPerPage);
     536    AssertReturnVoid(ASMAtomicBitTestAndClear(pPage->pbmAlloc, iObj));
     537
     538    ASMAtomicIncS32(&pPage->cFree);
     539    ASMAtomicIncS32(&pThis->cFree);
     540}
     541
     542
     543/**
     544 * Really frees a list of 'freed' object.
     545 *
     546 * @param   pThis               The memory cache.
     547 * @param   pHead               The head of the list.
     548 */
     549static void rtMemCacheFreeList(RTMEMCACHEINT *pThis, PRTMEMCACHEFREEOBJ pHead)
     550{
     551    while (pHead)
     552    {
     553        PRTMEMCACHEFREEOBJ pFreeMe = pHead;
     554        pHead = pHead->pNext;
     555        pFreeMe->pNext = NULL;
     556        ASMCompilerBarrier();
     557        rtMemCacheFreeOne(pThis, pFreeMe);
     558    }
     559}
     560
     561
     562
    504563RTDECL(void) RTMemCacheFree(RTMEMCACHE hMemCache, void *pvObj)
    505564{
     
    514573    Assert(RT_ALIGN_P(pvObj, pThis->cbAlignment) == pvObj);
    515574
    516     if (pThis->fUseFreeList)
     575    if (!pThis->fUseFreeList)
     576        rtMemCacheFreeOne(pThis, pvObj);
     577    else
    517578    {
    518579# ifdef RT_STRICT
     
    532593         */
    533594        PRTMEMCACHEFREEOBJ pObj = (PRTMEMCACHEFREEOBJ)pvObj;
    534         PRTMEMCACHEFREEOBJ pNext = ASMAtomicUoReadPtrT(&pThis->pFreeTop, PRTMEMCACHEFREEOBJ);
    535         PRTMEMCACHEFREEOBJ pFreeTopOld;
    536         pObj->pNext = pNext;
    537         while (!ASMAtomicCmpXchgExPtr(&pThis->pFreeTop, pObj, pNext, &pFreeTopOld))
    538         {
    539             pNext = pFreeTopOld;
    540             Assert(pNext != pObj);
    541             pObj->pNext = pNext;
    542             ASMNopPause();
    543         }
    544     }
    545     else
    546     {
    547         /* Note: Do *NOT* attempt to poison the object! */
    548 
    549         /*
    550          * Find the cache page.  The page structure is at the start of the page.
    551          */
    552         PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)(((uintptr_t)pvObj) & ~(uintptr_t)PAGE_OFFSET_MASK);
    553         Assert(pPage->pCache == pThis);
    554         Assert(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);
    555 
    556         /*
    557          * Clear the bitmap bit and update the two object counter. Order matters!
    558          */
    559         uintptr_t offObj = (uintptr_t)pvObj - (uintptr_t)pPage->pbObjects;
    560         uintptr_t iObj   = offObj / pThis->cbObject;
    561         Assert(iObj * pThis->cbObject == offObj);
    562         Assert(iObj < pThis->cPerPage);
    563         AssertReturnVoid(ASMAtomicBitTestAndClear(pPage->pbmAlloc, iObj));
    564 
    565         ASMAtomicIncS32(&pPage->cFree);
    566         ASMAtomicIncS32(&pThis->cFree);
    567     }
    568 }
    569 
     595        pObj->pNext = ASMAtomicXchgPtrT(&pThis->pFreeTop, NULL, PRTMEMCACHEFREEOBJ);
     596        PRTMEMCACHEFREEOBJ pFreeRace = ASMAtomicXchgPtrT(&pThis->pFreeTop, pObj, PRTMEMCACHEFREEOBJ);
     597        if (pFreeRace)
     598            rtMemCacheFreeList(pThis, pFreeRace);
     599    }
     600}
     601
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