VirtualBox

Ignore:
Timestamp:
Oct 20, 2010 9:36:48 PM (14 years ago)
Author:
vboxsync
Message:

RTMemCache: Fixed a bug in a calculation affect (too) small object and/or alignments. Tried to fix a more serious issue in the free list handling, but failed - disabled the free list optimization instead.

File:
1 edited

Legend:

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

    r30111 r33278  
    163163    if (cbAlignment == 0)
    164164    {
    165         cbAlignment = (size_t)1 << ASMBitLastSetU32((uint32_t)cbObject);
    166         if (cbAlignment > 64)
     165        if (cbObject <= 2)
     166            cbAlignment = cbObject;
     167        else if (cbObject <= 4)
     168            cbAlignment = 4;
     169        else if (cbObject <= 8)
     170            cbAlignment = 8;
     171        else if (cbObject <= 16)
     172            cbAlignment = 16;
     173        else if (cbObject <= 32)
     174            cbAlignment = 32;
     175        else
    167176            cbAlignment = 64;
    168177    }
     
    190199    pThis->cbAlignment      = (uint32_t)cbAlignment;
    191200    pThis->cPerPage         = (uint32_t)((PAGE_SIZE - RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), cbAlignment)) / pThis->cbObject);
    192     while (    RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), RT_MIN(cbAlignment, 8))
    193              + pThis->cPerPage * pThis->cbObject
    194              + RT_ALIGN(pThis->cPerPage, 64) / 8 * 2
     201    while (  RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), 8)
     202           + pThis->cPerPage * pThis->cbObject
     203           + RT_ALIGN(pThis->cPerPage, 64) / 8 * 2
    195204           > PAGE_SIZE)
    196205        pThis->cPerPage--;
     
    209218    pThis->pFreeTop         = NULL;
    210219
     220    /** @todo
     221     * Here is a puzzler (or maybe I'm just blind), the free list code breaks
     222     * badly on my macbook pro (i7) (32-bit).
     223     *
     224     * I tried changing the reads from unordered to ordered to no avail.  Then I
     225     * tried optimizing the code with the ASMAtomicCmpXchgExPtr function to
     226     * avoid some reads - no change. Inserting pause instructions did nothing
     227     * (as expected).  The only thing which seems to make a difference is
     228     * reading the pFreeTop pointer twice in the the free code... This is weird
     229     * or I'm overlooking something..
     230     *
     231     * No time to figure it out, so I'm disabling the broken code paths for
     232     * now. */
     233    pThis->fUseFreeList = false;
     234
    211235    *phMemCache = pThis;
    212236    return VINF_SUCCESS;
     
    223247#ifdef RT_STRICT
    224248    uint32_t cFree = pThis->cFree;
    225     for (PRTMEMCACHEFREEOBJ pFree = pThis->pFreeTop; pFree; pFree = pFree->pNext)
     249    for (PRTMEMCACHEFREEOBJ pFree = pThis->pFreeTop; pFree && cFree < pThis->cTotal + 5; pFree = pFree->pNext)
    226250        cFree++;
    227251    AssertMsg(cFree == pThis->cTotal, ("cFree=%u cTotal=%u\n", cFree, pThis->cTotal));
     
    295319            pb = RT_ALIGN_PT(pb, 8, uint8_t *);
    296320            pPage->pbmCtor      = pb;
    297             pb += pThis->cBits / 8 * 2;
    298321            pb = (uint8_t *)pPage + PAGE_SIZE - pThis->cbObject * cObjects;
    299322            pPage->pbObjects    = pb;   Assert(RT_ALIGN_P(pb, pThis->cbAlignment) == pb);
     
    362385    if (pObj)
    363386    {
    364         PRTMEMCACHEFREEOBJ pNext;
    365387        do
    366388        {
    367             pNext = ASMAtomicUoReadPtrT(&pObj->pNext, PRTMEMCACHEFREEOBJ);
    368             if (ASMAtomicCmpXchgPtr(&pThis->pFreeTop, pNext, pObj))
     389            PRTMEMCACHEFREEOBJ pNext = ASMAtomicUoReadPtrT(&pObj->pNext, PRTMEMCACHEFREEOBJ);
     390            PRTMEMCACHEFREEOBJ pObjOld;
     391            if (ASMAtomicCmpXchgExPtr(&pThis->pFreeTop, pNext, pObj, &pObjOld))
    369392            {
     393                Assert(pObjOld == pObj);
     394                Assert(pNext != pObjOld);
     395                pObj->pNext = NULL;
    370396                *ppvObj = pObj;
    371397                return VINF_SUCCESS;
    372398            }
    373             pObj = ASMAtomicUoReadPtrT(&pThis->pFreeTop, PRTMEMCACHEFREEOBJ);
     399            pObj = pObjOld;
     400            ASMNopPause();
    374401        } while (pObj);
    375402    }
     
    508535         */
    509536        PRTMEMCACHEFREEOBJ pObj = (PRTMEMCACHEFREEOBJ)pvObj;
    510         PRTMEMCACHEFREEOBJ pNext;
    511         do
    512         {
    513             pNext = ASMAtomicUoReadPtrT(&pThis->pFreeTop, PRTMEMCACHEFREEOBJ);
     537        PRTMEMCACHEFREEOBJ pNext = ASMAtomicUoReadPtrT(&pThis->pFreeTop, PRTMEMCACHEFREEOBJ);
     538        PRTMEMCACHEFREEOBJ pFreeTopOld;
     539        pObj->pNext = pNext;
     540        while (!ASMAtomicCmpXchgExPtr(&pThis->pFreeTop, pObj, pNext, &pFreeTopOld))
     541        {
     542            pNext = pFreeTopOld;
     543            Assert(pNext != pObj);
    514544            pObj->pNext = pNext;
    515         } while (!ASMAtomicCmpXchgPtr(&pThis->pFreeTop, pObj, pNext));
     545            ASMNopPause();
     546        }
    516547    }
    517548    else
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