Пример #1
0
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;
}
Пример #2
0
/* 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);
}