/** * Basic API checks. * We'll return if any of these fails. */ static void tst1(void) { RTTestISub("Basics"); /* Create one without constructor or destructor. */ uint32_t const cObjects = PAGE_SIZE * 2 / 256; RTMEMCACHE hMemCache; RTTESTI_CHECK_RC_RETV(RTMemCacheCreate(&hMemCache, 256, cObjects, 32, NULL, NULL, NULL, 0 /*fFlags*/), VINF_SUCCESS); RTTESTI_CHECK_RETV(hMemCache != NIL_RTMEMCACHE); /* Allocate a bit and free it again. */ void *pv = NULL; RTTESTI_CHECK_RC_RETV(RTMemCacheAllocEx(hMemCache, &pv), VINF_SUCCESS); RTTESTI_CHECK_RETV(pv != NULL); RTTESTI_CHECK_RETV(RT_ALIGN_P(pv, 32) == pv); RTMemCacheFree(hMemCache, pv); RTTESTI_CHECK((pv = RTMemCacheAlloc(hMemCache)) != NULL); RTMemCacheFree(hMemCache, pv); /* Allocate everything and free it again, checking size constraints. */ for (uint32_t iLoop = 0; iLoop < 20; iLoop++) { /* Allocate everything. */ void *apv[cObjects]; for (uint32_t i = 0; i < cObjects; i++) { apv[i] = NULL; RTTESTI_CHECK_RC(RTMemCacheAllocEx(hMemCache, &apv[i]), VINF_SUCCESS); } /* Check that we've got it all. */ int rc; RTTESTI_CHECK_RC(rc = RTMemCacheAllocEx(hMemCache, &pv), VERR_MEM_CACHE_MAX_SIZE); if (RT_SUCCESS(rc)) RTMemCacheFree(hMemCache, pv); RTTESTI_CHECK((pv = RTMemCacheAlloc(hMemCache)) == NULL); RTMemCacheFree(hMemCache, pv); /* Free all the allocations. */ for (uint32_t i = 0; i < cObjects; i++) { RTMemCacheFree(hMemCache, apv[i]); RTTESTI_CHECK((pv = RTMemCacheAlloc(hMemCache)) != NULL); RTMemCacheFree(hMemCache, pv); } } /* Destroy it. */ RTTESTI_CHECK_RC(RTMemCacheDestroy(hMemCache), VINF_SUCCESS); RTTESTI_CHECK_RC(RTMemCacheDestroy(NIL_RTMEMCACHE), VINF_SUCCESS); }
VBOXDDU_DECL(int) VSCSIDeviceReqCreate(VSCSIDEVICE hVScsiDevice, PVSCSIREQ phVScsiReq, uint32_t iLun, uint8_t *pbCDB, size_t cbCDB, size_t cbSGList, unsigned cSGListEntries, PCRTSGSEG paSGList, uint8_t *pbSense, size_t cbSense, void *pvVScsiReqUser) { PVSCSIDEVICEINT pVScsiDevice = (PVSCSIDEVICEINT)hVScsiDevice; PVSCSIREQINT pVScsiReq = NULL; /* Parameter checks */ AssertPtrReturn(pVScsiDevice, VERR_INVALID_HANDLE); AssertPtrReturn(phVScsiReq, VERR_INVALID_POINTER); AssertPtrReturn(pbCDB, VERR_INVALID_PARAMETER); AssertReturn(cbCDB > 0, VERR_INVALID_PARAMETER); pVScsiReq = (PVSCSIREQINT)RTMemCacheAlloc(pVScsiDevice->hCacheReq); if (!pVScsiReq) return VERR_NO_MEMORY; pVScsiReq->iLun = iLun; pVScsiReq->pbCDB = pbCDB; pVScsiReq->cbCDB = cbCDB; pVScsiReq->pbSense = pbSense; pVScsiReq->cbSense = cbSense; pVScsiReq->pvVScsiReqUser = pvVScsiReqUser; if (cSGListEntries) RTSgBufInit(&pVScsiReq->SgBuf, paSGList, cSGListEntries); *phVScsiReq = pVScsiReq; return VINF_SUCCESS; }
VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbDisplayWindowRootVr::entryAlloc() { #ifndef VBOXVDBG_MEMCACHE_DISABLE return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemCacheAlloc(g_CrPresenter.CEntryLookasideList); #else return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemAlloc(sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY)); #endif }
/** @copydoc RTDBGMODVTDBG::pfnLineAdd */ static DECLCALLBACK(int) rtDbgModContainer_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo, uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal) { PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv; /* * Validate the input address. */ AssertMsgReturn(iSeg < pThis->cSegs, ("iSeg=%#x cSegs=%#x\n", iSeg, pThis->cSegs), VERR_DBG_INVALID_SEGMENT_INDEX); AssertMsgReturn(off < pThis->paSegs[iSeg].cb, ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb), VERR_DBG_INVALID_SEGMENT_OFFSET); /* * Create a new entry. */ #ifdef RTDBGMODCNT_WITH_MEM_CACHE PRTDBGMODCTNLINE pLine = (PRTDBGMODCTNLINE)RTMemCacheAlloc(pThis->hLineNumAllocator); #else PRTDBGMODCTNLINE pLine = (PRTDBGMODCTNLINE)RTMemAllocZ(sizeof(*pLine)); #endif if (!pLine) return VERR_NO_MEMORY; pLine->AddrCore.Key = off; pLine->OrdinalCore.Key = pThis->iNextLineOrdinal; pLine->uLineNo = uLineNo; pLine->iSeg = iSeg; pLine->pszFile = RTStrCacheEnterN(g_hDbgModStrCache, pszFile, cchFile); int rc; if (pLine->pszFile) { if (RTAvlUIntPtrInsert(&pThis->paSegs[iSeg].LineAddrTree, &pLine->AddrCore)) { if (RTAvlU32Insert(&pThis->LineOrdinalTree, &pLine->OrdinalCore)) { if (piOrdinal) *piOrdinal = pThis->iNextLineOrdinal; pThis->iNextLineOrdinal++; return VINF_SUCCESS; } rc = VERR_INTERNAL_ERROR_5; RTAvlUIntPtrRemove(&pThis->paSegs[iSeg].LineAddrTree, pLine->AddrCore.Key); } /* bail out */ rc = VERR_DBG_ADDRESS_CONFLICT; RTStrCacheRelease(g_hDbgModStrCache, pLine->pszFile); } else rc = VERR_NO_MEMORY; #ifdef RTDBGMODCNT_WITH_MEM_CACHE RTMemCacheFree(pThis->hLineNumAllocator, pLine); #else RTMemFree(pLine); #endif return rc; }
/** * Thread that allocates * @returns * @param hThreadSelf The thread. * @param pvArg Pointer to fUseCache. */ static DECLCALLBACK(int) tst3Thread(RTTHREAD hThreadSelf, void *pvArg) { PTST3THREAD pThread = (PTST3THREAD)(pvArg); size_t cbObject = pThread->cbObject; uint64_t cIterations = 0; /* wait for the kick-off */ RTTEST_CHECK_RC_OK(g_hTest, RTSemEventMultiWait(pThread->hEvt, RT_INDEFINITE_WAIT)); /* allocate and free loop */ if (pThread->fUseCache) { while (!g_fTst3Stop) { void *apv[64]; for (unsigned i = 0; i < RT_ELEMENTS(apv); i++) { apv[i] = RTMemCacheAlloc(g_hMemCache); RTTEST_CHECK(g_hTest, apv[i] != NULL); } for (unsigned i = 0; i < RT_ELEMENTS(apv); i++) RTMemCacheFree(g_hMemCache, apv[i]); cIterations += RT_ELEMENTS(apv); } } else { while (!g_fTst3Stop) { void *apv[64]; for (unsigned i = 0; i < RT_ELEMENTS(apv); i++) { apv[i] = RTMemAlloc(cbObject); RTTEST_CHECK(g_hTest, apv[i] != NULL); } for (unsigned i = 0; i < RT_ELEMENTS(apv); i++) RTMemFree(apv[i]); cIterations += RT_ELEMENTS(apv); } } /* report back the status */ pThread->cIterations = cIterations; return VINF_SUCCESS; }
/** * Test constructor / destructor. */ static void tst2(void) { RTTestISub("Ctor/Dtor"); /* Create one without constructor or destructor. */ bool fFail = false; uint32_t const cObjects = PAGE_SIZE * 2 / 256; RTTESTI_CHECK_RC_RETV(RTMemCacheCreate(&g_hMemCache, 256, cObjects, 32, tst2Ctor, tst2Dtor, &fFail, 0 /*fFlags*/), VINF_SUCCESS); /* A failure run first. */ fFail = true; void *pv = (void *)0x42; RTTESTI_CHECK_RC_RETV(RTMemCacheAllocEx(g_hMemCache, &pv), VERR_RESOURCE_BUSY); RTTESTI_CHECK(pv == (void *)0x42); fFail = false; /* To two rounds where we allocate all the objects and free them again. */ for (uint32_t iLoop = 0; iLoop < 2; iLoop++) { void *apv[cObjects]; for (uint32_t i = 0; i < cObjects; i++) { apv[i] = NULL; RTTESTI_CHECK_RC_RETV(RTMemCacheAllocEx(g_hMemCache, &apv[i]), VINF_SUCCESS); if (iLoop == 0) RTTESTI_CHECK(!strcmp((char *)apv[i], "ctor was called\n")); else RTTESTI_CHECK(!strcmp((char *)apv[i], "ctor was called\nused\n")); strcat((char *)apv[i], "used\n"); } RTTESTI_CHECK_RETV((pv = RTMemCacheAlloc(g_hMemCache)) == NULL); RTMemCacheFree(g_hMemCache, pv); for (uint32_t i = 0; i < cObjects; i++) RTMemCacheFree(g_hMemCache, apv[i]); } /* Cone, destroy the cache. */ RTTESTI_CHECK_RC(RTMemCacheDestroy(g_hMemCache), VINF_SUCCESS); }
VBOXDDU_DECL(int) VDDbgIoLogStartDiscard(VDIOLOGGER hIoLogger, bool fAsync, PCRTRANGE paRanges, unsigned cRanges, PVDIOLOGENT phIoLogEntry) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; PVDIOLOGENTINT pIoLogEntry = NULL; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries); if (pIoLogEntry) { IoLogEntryStart Entry; pIoLogEntry->idStart = pIoLogger->idNext++; Entry.u32Type = VDIOLOG_EVENT_START; Entry.u8AsyncIo = fAsync ? 1 : 0; Entry.u32ReqType = VDDBGIOLOGREQ_DISCARD; Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart); Entry.Discard.cRanges = RT_H2LE_U32(cRanges); /* Write new entry. */ rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { pIoLogger->offWriteNext += sizeof(Entry); IoLogEntryDiscard DiscardRange; for (unsigned i = 0; i < cRanges; i++) { DiscardRange.u64Off = RT_H2LE_U64(paRanges[i].offStart); DiscardRange.u32Discard = RT_H2LE_U32((uint32_t)paRanges[i].cbRange); rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext + i*sizeof(DiscardRange), &DiscardRange, sizeof(DiscardRange), NULL); if (RT_FAILURE(rc)) break; } if (RT_FAILURE(rc)) { pIoLogger->offWriteNext -= sizeof(Entry); rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext); } else pIoLogger->offWriteNext += cRanges * sizeof(DiscardRange); } if (RT_SUCCESS(rc)) { pIoLogEntry->tsStart = RTTimeProgramMilliTS(); pIoLogEntry->cbIo = 0; *phIoLogEntry = pIoLogEntry; } else { pIoLogger->idNext--; RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry); } } else rc = VERR_NO_MEMORY; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }
VBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGREQ enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf, PVDIOLOGENT phIoLogEntry) { int rc = VINF_SUCCESS; PVDIOLOGGERINT pIoLogger = hIoLogger; PVDIOLOGENTINT pIoLogEntry = NULL; AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE); AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER); AssertReturn(enmTxDir > VDDBGIOLOGREQ_INVALID && enmTxDir <= VDDBGIOLOGREQ_FLUSH, VERR_INVALID_PARAMETER); rc = RTSemFastMutexRequest(pIoLogger->hMtx); AssertRCReturn(rc, rc); pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries); if (pIoLogEntry) { IoLogEntryStart Entry; pIoLogEntry->idStart = pIoLogger->idNext++; Entry.u32Type = VDIOLOG_EVENT_START; Entry.u8AsyncIo = fAsync ? 1 : 0; Entry.u32ReqType = enmTxDir; Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart); Entry.Io.u64Off = RT_H2LE_U64(off); Entry.Io.u64IoSize = RT_H2LE_U64(cbIo); /* Write new entry. */ rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL); if (RT_SUCCESS(rc)) { pIoLogger->offWriteNext += sizeof(Entry); if ( enmTxDir == VDDBGIOLOGREQ_WRITE && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN)) { /* Write data. */ rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, cbIo); if (RT_FAILURE(rc)) { pIoLogger->offWriteNext -= sizeof(Entry); rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext); } else pIoLogger->offWriteNext += cbIo; } } if (RT_SUCCESS(rc)) { pIoLogEntry->tsStart = RTTimeProgramMilliTS(); if ( enmTxDir == VDDBGIOLOGREQ_READ && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_READ)) pIoLogEntry->cbIo = cbIo; else pIoLogEntry->cbIo = 0; *phIoLogEntry = pIoLogEntry; } else { pIoLogger->idNext--; RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry); } } else rc = VERR_NO_MEMORY; RTSemFastMutexRelease(pIoLogger->hMtx); return rc; }