/** * Performs a simple unicast test. * * @param pThis The test instance. * @param fHeadGuard Whether to use a head or tail guard. */ static void doUnicastTest(PTSTSTATE pThis, bool fHeadGuard) { static uint16_t const s_au16Frame[7] = { /* dst:*/ 0x8086, 0, 0, /*src:*/0x8086, 0, 1, 0x0800 }; RTTESTI_CHECK_RC_RETV(tstIntNetSendBuf(&pThis->pBuf1->Send, pThis->hIf1, g_pSession, s_au16Frame, sizeof(s_au16Frame)), VINF_SUCCESS); /* No echo, please */ RTTESTI_CHECK_RC_RETV(IntNetR0IfWait(pThis->hIf1, g_pSession, 1), VERR_TIMEOUT); /* The other interface should see it though. But Wait should only return once, thank you. */ RTTESTI_CHECK_RC_RETV(IntNetR0IfWait(pThis->hIf0, g_pSession, 1), VINF_SUCCESS); RTTESTI_CHECK_RC_RETV(IntNetR0IfWait(pThis->hIf0, g_pSession, 0), VERR_TIMEOUT); /* Receive the data. */ const unsigned cbExpect = RT_ALIGN(sizeof(s_au16Frame) + sizeof(INTNETHDR), sizeof(INTNETHDR)); RTTESTI_CHECK_MSG(IntNetRingGetReadable(&pThis->pBuf0->Recv) == cbExpect, ("%#x vs. %#x\n", IntNetRingGetReadable(&pThis->pBuf0->Recv), cbExpect)); void *pvBuf; RTTESTI_CHECK_RC_OK_RETV(RTTestGuardedAlloc(g_hTest, sizeof(s_au16Frame), 1, fHeadGuard, &pvBuf)); uint32_t cb; RTTESTI_CHECK_MSG_RETV((cb = IntNetRingReadAndSkipFrame(&pThis->pBuf0->Recv, pvBuf)) == sizeof(s_au16Frame), ("%#x vs. %#x\n", cb, sizeof(s_au16Frame))); if (memcmp(pvBuf, &s_au16Frame, sizeof(s_au16Frame))) RTTestIFailed("Got invalid data!\n" "received: %.*Rhxs\n" "expected: %.*Rhxs\n", cb, pvBuf, sizeof(s_au16Frame), s_au16Frame); }
void tstFileAioTestReadWriteBasic(RTFILE File, bool fWrite, void *pvTestBuf, size_t cbTestBuf, size_t cbTestFile, uint32_t cMaxReqsInFlight) { /* Allocate request array. */ RTFILEAIOREQ *paReqs; paReqs = (PRTFILEAIOREQ)RTTestGuardedAllocHead(g_hTest, cMaxReqsInFlight * sizeof(RTFILEAIOREQ)); RTTESTI_CHECK_RETV(paReqs); RT_BZERO(paReqs, sizeof(cMaxReqsInFlight * sizeof(RTFILEAIOREQ))); /* Allocate array holding pointer to data buffers. */ void **papvBuf = (void **)RTTestGuardedAllocHead(g_hTest, cMaxReqsInFlight * sizeof(void *)); RTTESTI_CHECK_RETV(papvBuf); /* Allocate the buffers*/ for (unsigned i = 0; i < cMaxReqsInFlight; i++) { RTTESTI_CHECK_RC_OK_RETV(RTTestGuardedAlloc(g_hTest, cbTestBuf, PAGE_SIZE, true /*fHead*/, &papvBuf[i])); if (fWrite) memcpy(papvBuf[i], pvTestBuf, cbTestBuf); if (fWrite) memcpy(papvBuf[i], pvTestBuf, cbTestBuf); else RT_BZERO(papvBuf[i], cbTestBuf); } /* Allocate array holding completed requests. */ RTFILEAIOREQ *paReqsCompleted; paReqsCompleted = (PRTFILEAIOREQ)RTTestGuardedAllocHead(g_hTest, cMaxReqsInFlight * sizeof(RTFILEAIOREQ)); RTTESTI_CHECK_RETV(paReqsCompleted); RT_BZERO(paReqsCompleted, cMaxReqsInFlight * sizeof(RTFILEAIOREQ)); /* Create a context and associate the file handle with it. */ RTFILEAIOCTX hAioContext; RTTESTI_CHECK_RC_RETV(RTFileAioCtxCreate(&hAioContext, cMaxReqsInFlight, 0 /* fFlags */), VINF_SUCCESS); RTTESTI_CHECK_RC_RETV(RTFileAioCtxAssociateWithFile(hAioContext, File), VINF_SUCCESS); /* Initialize requests. */ for (unsigned i = 0; i < cMaxReqsInFlight; i++) RTFileAioReqCreate(&paReqs[i]); RTFOFF off = 0; int cRuns = 0; uint64_t NanoTS = RTTimeNanoTS(); size_t cbLeft = cbTestFile; while (cbLeft) { int rc; int cReqs = 0; for (unsigned i = 0; i < cMaxReqsInFlight; i++) { size_t cbTransfer = cbLeft < cbTestBuf ? cbLeft : cbTestBuf; if (!cbTransfer) break; if (fWrite) rc = RTFileAioReqPrepareWrite(paReqs[i], File, off, papvBuf[i], cbTransfer, papvBuf[i]); else rc = RTFileAioReqPrepareRead(paReqs[i], File, off, papvBuf[i], cbTransfer, papvBuf[i]); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); cbLeft -= cbTransfer; off += cbTransfer; cReqs++; } rc = RTFileAioCtxSubmit(hAioContext, paReqs, cReqs); RTTESTI_CHECK_MSG(rc == VINF_SUCCESS, ("Failed to submit tasks after %d runs. rc=%Rrc\n", cRuns, rc)); if (rc != VINF_SUCCESS) break; /* Wait */ uint32_t cCompleted = 0; RTTESTI_CHECK_RC(rc = RTFileAioCtxWait(hAioContext, cReqs, RT_INDEFINITE_WAIT, paReqsCompleted, cMaxReqsInFlight, &cCompleted), VINF_SUCCESS); if (rc != VINF_SUCCESS) break; if (!fWrite) { for (uint32_t i = 0; i < cCompleted; i++) { /* Compare that we read the right stuff. */ void *pvBuf = RTFileAioReqGetUser(paReqsCompleted[i]); RTTESTI_CHECK(pvBuf); size_t cbTransfered; RTTESTI_CHECK_RC(rc = RTFileAioReqGetRC(paReqsCompleted[i], &cbTransfered), VINF_SUCCESS); if (rc != VINF_SUCCESS) break; RTTESTI_CHECK_MSG(cbTransfered == cbTestBuf, ("cbTransfered=%zd\n", cbTransfered)); RTTESTI_CHECK_RC_OK(rc = (memcmp(pvBuf, pvTestBuf, cbTestBuf) == 0 ? VINF_SUCCESS : VERR_BAD_EXE_FORMAT)); if (rc != VINF_SUCCESS) break; memset(pvBuf, 0, cbTestBuf); } } cRuns++; if (RT_FAILURE(rc)) break; } NanoTS = RTTimeNanoTS() - NanoTS; uint64_t SpeedKBs = (uint64_t)(cbTestFile / (NanoTS / 1000000000.0) / 1024); RTTestValue(g_hTest, "Throughput", SpeedKBs, RTTESTUNIT_KILOBYTES_PER_SEC); /* cleanup */ for (unsigned i = 0; i < cMaxReqsInFlight; i++) RTTestGuardedFree(g_hTest, papvBuf[i]); RTTestGuardedFree(g_hTest, papvBuf); for (unsigned i = 0; i < cMaxReqsInFlight; i++) RTTESTI_CHECK_RC(RTFileAioReqDestroy(paReqs[i]), VINF_SUCCESS); RTTESTI_CHECK_RC(RTFileAioCtxDestroy(hAioContext), VINF_SUCCESS); RTTestGuardedFree(g_hTest, paReqs); }