Changeset 55252 in vbox for trunk/src/VBox/Runtime/common/alloc
- Timestamp:
- Apr 14, 2015 2:56:12 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/alloc/memcache.cpp
r46257 r55252 87 87 /** Bitmap tracking which blocks that has been thru the constructor. */ 88 88 void volatile *pbmCtor; 89 /** Pointer to the object array. .*/89 /** Pointer to the object array. */ 90 90 uint8_t *pbObjects; 91 91 /** The number of objects on this page. */ … … 150 150 151 151 152 /******************************************************************************* 153 * Internal Functions * 154 *******************************************************************************/ 155 static void rtMemCacheFreeList(RTMEMCACHEINT *pThis, PRTMEMCACHEFREEOBJ pHead); 156 152 157 153 158 RTDECL(int) RTMemCacheCreate(PRTMEMCACHE phMemCache, size_t cbObject, size_t cbAlignment, uint32_t cMaxObjects, … … 221 226 pThis->pFreeTop = NULL; 222 227 228 #if 1 /* should be fixed now, enable shortly... */ 223 229 /** @todo 224 230 * Here is a puzzler (or maybe I'm just blind), the free list code breaks … … 235 241 * now. */ 236 242 pThis->fUseFreeList = false; 243 #endif 237 244 238 245 *phMemCache = pThis; … … 382 389 if (pObj) 383 390 { 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) 389 395 { 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); 395 400 } 396 pObj = pObjOld; 397 ASMNopPause(); 398 } while (pObj); 401 402 pObj->pNext = NULL; 403 *ppvObj = pObj; 404 return VINF_SUCCESS; 405 } 399 406 } 400 407 … … 502 509 503 510 511 512 /** 513 * Really frees one object. 514 * 515 * @param pThis The memory cache. 516 * @param pvObj The memory object to free. 517 */ 518 static 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 */ 549 static 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 504 563 RTDECL(void) RTMemCacheFree(RTMEMCACHE hMemCache, void *pvObj) 505 564 { … … 514 573 Assert(RT_ALIGN_P(pvObj, pThis->cbAlignment) == pvObj); 515 574 516 if (pThis->fUseFreeList) 575 if (!pThis->fUseFreeList) 576 rtMemCacheFreeOne(pThis, pvObj); 577 else 517 578 { 518 579 # ifdef RT_STRICT … … 532 593 */ 533 594 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.