예제 #1
0
VBOXDDU_DECL(int) VSCSIDeviceCreate(PVSCSIDEVICE phVScsiDevice,
                                    PFNVSCSIREQCOMPLETED pfnVScsiReqCompleted,
                                    void *pvVScsiDeviceUser)
{
    int rc = VINF_SUCCESS;
    PVSCSIDEVICEINT pVScsiDevice = NULL;

    AssertPtrReturn(phVScsiDevice, VERR_INVALID_POINTER);
    AssertPtrReturn(pfnVScsiReqCompleted, VERR_INVALID_POINTER);

    pVScsiDevice = (PVSCSIDEVICEINT)RTMemAllocZ(sizeof(VSCSIDEVICEINT));
    if (!pVScsiDevice)
        return VERR_NO_MEMORY;

    pVScsiDevice->pfnVScsiReqCompleted = pfnVScsiReqCompleted;
    pVScsiDevice->pvVScsiDeviceUser    = pvVScsiDeviceUser;
    pVScsiDevice->cLunsAttached        = 0;
    pVScsiDevice->cLunsMax             = 0;
    pVScsiDevice->papVScsiLun          = NULL;
    vscsiSenseInit(&pVScsiDevice->VScsiSense);

    rc = RTMemCacheCreate(&pVScsiDevice->hCacheReq, sizeof(VSCSIREQINT), 0, UINT32_MAX,
                          NULL, NULL, NULL, 0);
    if (RT_SUCCESS(rc))
    {
        *phVScsiDevice = pVScsiDevice;
        LogFlow(("%s: hVScsiDevice=%#p -> VINF_SUCCESS\n", __FUNCTION__, pVScsiDevice));
        return VINF_SUCCESS;
    }

    RTMemFree(pVScsiDevice);

    return rc;
}
예제 #2
0
/**
 * Creates a new empty I/O logger.
 *
 * @returns VBox status code.
 * @param   ppIoLogger    Where to store the new I/O logger handle.
 */
static int vddbgIoLoggerCreate(PVDIOLOGGERINT *ppIoLogger)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = NULL;

    pIoLogger = (PVDIOLOGGERINT)RTMemAllocZ(sizeof(VDIOLOGGERINT));
    if (pIoLogger)
    {
        rc = RTSemFastMutexCreate(&pIoLogger->hMtx);
        if (RT_SUCCESS(rc))
        {
            rc = RTMemCacheCreate(&pIoLogger->hMemCacheIoLogEntries, sizeof(VDIOLOGENTINT),
                                  0, UINT32_MAX, NULL, NULL, NULL, 0);
            if (RT_SUCCESS(rc))
            {
                *ppIoLogger = pIoLogger;
                return rc;
            }
        }
        RTMemFree(pIoLogger);
    }
    else
        rc = VERR_NO_MEMORY;

    return rc;
}
예제 #3
0
/**
 * Time constrained test with and unlimited  N threads.
 */
static void tst3(uint32_t cThreads, uint32_t cbObject, int iMethod, uint32_t cSecs)
{
    RTTestISubF("Benchmark - %u threads, %u bytes, %u secs, %s", cThreads, cbObject, cSecs,
                iMethod == 0 ? "RTMemCache"
                : "RTMemAlloc");

    /*
     * Create a cache with unlimited space, a start semaphore and line up
     * the threads.
     */
    RTTESTI_CHECK_RC_RETV(RTMemCacheCreate(&g_hMemCache, cbObject, 0 /*cbAlignment*/, UINT32_MAX, NULL, NULL, NULL, 0 /*fFlags*/), VINF_SUCCESS);

    RTSEMEVENTMULTI hEvt;
    RTTESTI_CHECK_RC_OK_RETV(RTSemEventMultiCreate(&hEvt));

    TST3THREAD aThreads[64];
    RTTESTI_CHECK_RETV(cThreads < RT_ELEMENTS(aThreads));

    ASMAtomicWriteBool(&g_fTst3Stop, false);
    for (uint32_t i = 0; i < cThreads; i++)
    {
        aThreads[i].hThread     = NIL_RTTHREAD;
        aThreads[i].cIterations = 0;
        aThreads[i].fUseCache   = iMethod == 0;
        aThreads[i].cbObject    = cbObject;
        aThreads[i].hEvt        = hEvt;
        RTTESTI_CHECK_RC_OK_RETV(RTThreadCreateF(&aThreads[i].hThread, tst3Thread, &aThreads[i], 0,
                                                 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tst3-%u", i));
    }

    /*
     * Start the race.
     */
    RTTimeNanoTS(); /* warmup */

    uint64_t uStartTS = RTTimeNanoTS();
    RTTESTI_CHECK_RC_OK_RETV(RTSemEventMultiSignal(hEvt));
    RTThreadSleep(cSecs * 1000);
    ASMAtomicWriteBool(&g_fTst3Stop, true);
    for (uint32_t i = 0; i < cThreads; i++)
        RTTESTI_CHECK_RC_OK_RETV(RTThreadWait(aThreads[i].hThread, 60*1000, NULL));
    uint64_t cElapsedNS = RTTimeNanoTS() - uStartTS;

    /*
     * Sum up the counts.
     */
    uint64_t cIterations = 0;
    for (uint32_t i = 0; i < cThreads; i++)
        cIterations += aThreads[i].cIterations;

    RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second, %'llu ns on avg\n",
                  (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS),
                  cElapsedNS / cIterations);

    /* clean up */
    RTTESTI_CHECK_RC(RTMemCacheDestroy(g_hMemCache), VINF_SUCCESS);
    RTTESTI_CHECK_RC_OK(RTSemEventMultiDestroy(hEvt));
}
예제 #4
0
/**
 * 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);
}
예제 #5
0
/**
 * Creates a generic debug info container and associates it with the module.
 *
 * @returns IPRT status code.
 * @param   pMod        The module instance.
 * @param   cbSeg       The size of the initial segment. 0 if segments are to be
 *                      created manually later on.
 */
int rtDbgModContainerCreate(PRTDBGMODINT pMod, RTUINTPTR cbSeg)
{
    PRTDBGMODCTN pThis = (PRTDBGMODCTN)RTMemAlloc(sizeof(*pThis));
    if (!pThis)
        return VERR_NO_MEMORY;

    pThis->Names = NULL;
    pThis->AbsAddrTree = NULL;
    pThis->SymbolOrdinalTree = NULL;
    pThis->LineOrdinalTree = NULL;
    pThis->paSegs = NULL;
    pThis->cSegs = 0;
    pThis->cb = 0;
    pThis->iNextSymbolOrdinal = 0;
    pThis->iNextLineOrdinal = 0;

    pMod->pDbgVt = &g_rtDbgModVtDbgContainer;
    pMod->pvDbgPriv = pThis;

#ifdef RTDBGMODCNT_WITH_MEM_CACHE
    int rc = RTMemCacheCreate(&pThis->hLineNumAllocator, sizeof(RTDBGMODCTNLINE), sizeof(void *), UINT32_MAX,
                              NULL /*pfnCtor*/, NULL /*pfnDtor*/, NULL /*pvUser*/, 0 /*fFlags*/);
#else
    int rc = VINF_SUCCESS;
#endif
    if (RT_SUCCESS(rc))
    {
        /*
         * Add the initial segment.
         */
        if (cbSeg)
            rc = rtDbgModContainer_SegmentAdd(pMod, 0, cbSeg, "default", sizeof("default") - 1, 0, NULL);
        if (RT_SUCCESS(rc))
            return rc;

#ifdef RTDBGMODCNT_WITH_MEM_CACHE
        RTMemCacheDestroy(pThis->hLineNumAllocator);
#endif
    }

    RTMemFree(pThis);
    pMod->pDbgVt = NULL;
    pMod->pvDbgPriv = NULL;
    return rc;
}
예제 #6
0
/**
 * 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);
}