VirtualBox

Changeset 59850 in vbox for trunk/src/VBox/Devices/Graphics


Ignore:
Timestamp:
Feb 26, 2016 2:45:10 PM (9 years ago)
Author:
vboxsync
Message:

VMSVGA: Replaced the fixed 50ms interval by adaptive polling/sleep interval, which when busy is only 16ms and slowly increases to 250ms when idle (takes about 16 seconds).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp

    r59849 r59850  
    23642364         * Insufficient, must wait for it to arrive.
    23652365         */
     2366/** @todo Should clear the busy flag here to maybe encourage the guest to wake us up. */
    23662367        STAM_REL_PROFILE_START(&pSVGAState->StatFifoStalls, Stall);
    23672368        for (uint32_t i = 0;; i++)
     
    24482449
    24492450    /*
    2450      * Signal the semaphore to make sure we don't wait for 250 after a
     2451     * Signal the semaphore to make sure we don't wait for 250ms after a
    24512452     * suspend & resume scenario (see vmsvgaFIFOGetCmdPayload).
    24522453     */
     
    24602461    AssertReturn(pbBounceBuf, VERR_NO_MEMORY);
    24612462
     2463    /*
     2464     * Polling/sleep interval config.
     2465     *
     2466     * We wait for an a short interval if the guest has recently given us work
     2467     * to do, but the interval increases the longer we're kept idle.  With the
     2468     * current parameters we'll be at a 64ms poll interval after 1 idle second,
     2469     * at 90ms after 2 seconds, and reach the max 250ms interval after about
     2470     * 16 seconds.
     2471     */
     2472    RTMSINTERVAL const  cMsMinSleep = 16;
     2473    RTMSINTERVAL const  cMsIncSleep = 2;
     2474    RTMSINTERVAL const  cMsMaxSleep = 250;
     2475    RTMSINTERVAL        cMsSleep    = cMsMaxSleep;
     2476
     2477    /*
     2478     * The FIFO loop.
     2479     */
    24622480    LogFlow(("vmsvgaFIFOLoop: started loop\n"));
     2481    bool fBadOrDisabledFifo = false;
    24632482    uint32_t volatile * const pFIFO = pThis->svga.pFIFOR3;
    24642483    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     
    24732492
    24742493        /*
    2475          * Wait for at most 50 ms to start polling.
     2494         * Unless there's already work pending, go to sleep for a short while.
     2495         * (See polling/sleep interval config above.)
    24762496         */
    2477         rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, 50);
    2478         AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED);
    2479         if (pThread->enmState != PDMTHREADSTATE_RUNNING)
    2480         {
    2481             LogFlow(("vmsvgaFIFOLoop: thread state %x\n", pThread->enmState));
    2482             break;
    2483         }
     2497        if (   fBadOrDisabledFifo
     2498            || pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
     2499        {
     2500            rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, cMsSleep);
     2501            AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED);
     2502            if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     2503            {
     2504                LogFlow(("vmsvgaFIFOLoop: thread state %x\n", pThread->enmState));
     2505                break;
     2506            }
     2507        }
     2508        else
     2509            rc = VINF_SUCCESS;
     2510        fBadOrDisabledFifo = false;
    24842511        if (rc == VERR_TIMEOUT)
    24852512        {
    24862513            if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
     2514            {
     2515                cMsSleep = RT_MIN(cMsSleep + cMsIncSleep, cMsMaxSleep);
    24872516                continue;
     2517            }
    24882518            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoTimeout);
    24892519
     
    24922522        else if (pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
    24932523            STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoWoken);
     2524        cMsSleep = cMsMinSleep;
    24942525
    24952526        Log(("vmsvgaFIFOLoop: enabled=%d configured=%d busy=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured, pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
     
    25132544        {
    25142545            vmsvgaFifoSetNotBusy(pThis, pSVGAState, pFIFO[SVGA_FIFO_MIN]);
     2546            fBadOrDisabledFifo = true;
    25152547            continue;
    25162548        }
     
    25362568            LogRelMax(8, ("vmsvgaFIFOLoop: Bad fifo: min=%#x stop=%#x max=%#x\n", offFifoMin, offCurrentCmd, offFifoMax));
    25372569            vmsvgaFifoSetNotBusy(pThis, pSVGAState, offFifoMin);
     2570            fBadOrDisabledFifo = true;
    25382571            continue;
    25392572        }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette