int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs) { PVBOXUHGSMI_BUFFER pBuf; int rc = pUhgsmi->pfnBufferCreate(pUhgsmi, cbBuf, VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT, NULL, &pBuf); AssertRC(rc); if (RT_SUCCESS(rc)) { uint64_t TimeMs = VBOXDISPPROFILE_GET_TIME_MILLI(); do { VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags; fFlags.Value = 0; fFlags.bLockEntire = 1; fFlags.bDiscard = 1; void *pvLock; rc = pBuf->pfnLock(pBuf, 0, cbBuf, fFlags, &pvLock); AssertRC(rc); if (!RT_SUCCESS(rc)) break; rc = pBuf->pfnUnlock(pBuf); AssertRC(rc); if (!RT_SUCCESS(rc)) break; VBOXUHGSMI_BUFFER_SUBMIT SubmitData; SubmitData.pBuf = pBuf; SubmitData.fFlags.Value = 0; SubmitData.fFlags.bDoNotRetire = 1; SubmitData.fFlags.bEntireBuffer = 1; rc = pUhgsmi->pfnBufferSubmitAsynch(pUhgsmi, &SubmitData, 1); AssertRC(rc); if (!RT_SUCCESS(rc)) break; DWORD dw = WaitForSingleObject(pBuf->hSynch, INFINITE); Assert(dw == WAIT_OBJECT_0); if (dw) break; } while (--cNumCals); TimeMs = VBOXDISPPROFILE_GET_TIME_MILLI() - TimeMs; *pTimeMs = TimeMs; pBuf->pfnDestroy(pBuf); } return rc; }
/* Same as crVBoxHGCMWriteExact, but combined with read of writeback data. * This halves the number of HGCM calls we do, * most likely crVBoxHGCMPollHost shouldn't be called at all now. */ static void _crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void *buf, uint32_t offBuffer, unsigned int len, bool bIsBuffer) { CRVBOXHGSMIWRITEREAD *parms = (CRVBOXHGSMIWRITEREAD*)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms)); int rc; VBOXUHGSMI_BUFFER_SUBMIT aSubmit[3]; PVBOXUHGSMI_BUFFER pBuf = NULL; VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags; // uint32_t cbBuffer; parms->hdr.result = VERR_WRONG_ORDER; parms->hdr.u32ClientID = conn->u32ClientID; parms->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ; // parms->hdr.u32Reserved = 0; parms->iBuffer = 1; CRASSERT(!conn->pBuffer); //make sure there's no data to process parms->iWriteback = 2; parms->cbWriteback = 0; _crVBoxHGSMICmdBufferUnlock(pClient); if (!bIsBuffer) { void *pvBuf; pBuf = _crVBoxHGSMIBufAlloc(pClient, len); Assert(pBuf); if (!pBuf) return; Assert(!offBuffer); offBuffer = 0; fFlags.Value = 0; fFlags.bDiscard = 1; fFlags.bWriteOnly = 1; rc = pBuf->pfnLock(pBuf, 0, len, fFlags, &pvBuf); AssertRC(rc); if (RT_SUCCESS(rc)) { memcpy(pvBuf, buf, len); rc = pBuf->pfnUnlock(pBuf); AssertRC(rc); CRASSERT(RT_SUCCESS(rc)); } else { _crVBoxHGSMIBufFree(pClient, pBuf); return; } } else { pBuf = (PVBOXUHGSMI_BUFFER)buf; } do { PVBOXUHGSMI_BUFFER pRecvBuffer = _crVBoxHGSMIRecvBufGet(pClient); Assert(pRecvBuffer); if (!pRecvBuffer) return; _crVBoxHGSMIFillCmd(&aSubmit[0], pClient, sizeof (*parms)); aSubmit[1].pBuf = pBuf; aSubmit[1].offData = offBuffer; aSubmit[1].cbData = len; aSubmit[1].fFlags.Value = 0; aSubmit[1].fFlags.bHostReadOnly = 1; aSubmit[2].pBuf = pRecvBuffer; aSubmit[2].offData = 0; aSubmit[2].cbData = pRecvBuffer->cbBuffer; aSubmit[2].fFlags.Value = 0; rc = pClient->pHgsmi->pfnBufferSubmitAsynch(pClient->pHgsmi, aSubmit, 3); AssertRC(rc); if (RT_FAILURE(rc)) { crWarning("pfnBufferSubmitAsynch failed with %d \n", rc); break; } _crVBoxHGSMIWaitCmd(pClient); parms = (CRVBOXHGSMIWRITEREAD *)_crVBoxHGSMICmdBufferLockRo(pClient, sizeof (*parms)); Assert(parms); if (parms) { uint32_t cbWriteback = parms->cbWriteback; rc = parms->hdr.result; _crVBoxHGSMICmdBufferUnlock(pClient); #ifdef DEBUG parms = NULL; #endif if (RT_SUCCESS(rc)) { if (cbWriteback) { void *pvData = _crVBoxHGSMIRecvBufData(pClient, cbWriteback); Assert(pvData); if (pvData) { conn->pBuffer = pvData; conn->cbBuffer = cbWriteback; _crVBoxHGSMIReceiveMessage(conn, pClient); } } } else if (VERR_BUFFER_OVERFLOW == rc) { PVBOXUHGSMI_BUFFER pOldBuf = pClient->pHGBuffer; Assert(!pClient->pvHGBuffer); CRASSERT(cbWriteback>pClient->pHGBuffer->cbBuffer); crDebug("Reallocating host buffer from %d to %d bytes", conn->cbHostBufferAllocated, cbWriteback); rc = pClient->pHgsmi->pfnBufferCreate(pClient->pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(cbWriteback), VBOXUHGSMI_SYNCHOBJECT_TYPE_NONE, NULL, &pClient->pHGBuffer); AssertRC(rc); CRASSERT(RT_SUCCESS(rc)); if (RT_SUCCESS(rc)) { rc = pOldBuf->pfnDestroy(pOldBuf); CRASSERT(RT_SUCCESS(rc)); _crVBoxHGSMIReadExact(conn, pClient/*, cbWriteback*/); } } else { crWarning("SHCRGL_GUEST_FN_WRITE_READ (%i) failed with %x \n", len, rc); } } else { crWarning("_crVBoxHGSMICmdBufferLockRo failed\n"); break; } } while (0); if (!bIsBuffer) _crVBoxHGSMIBufFree(pClient, pBuf); }