VirtualBox

Changeset 21900 in vbox


Ignore:
Timestamp:
Jul 30, 2009 5:31:36 PM (15 years ago)
Author:
vboxsync
Message:

SSM: Added the read ahead thread.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/SSM-new.cpp

    r21897 r21900  
    324324    /** The handle of the I/O thread. This is set to nil when not active. */
    325325    RTTHREAD                hIoThread;
     326    /** Where to seek to. */
     327    uint64_t                offNeedSeekTo;
    326328
    327329    /** The head of the consumer queue.
     
    750752static int                  ssmR3Register(PVM pVM, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, const char *pszBefore, PSSMUNIT *ppUnit);
    751753static int                  ssmR3StrmWriteBuffers(PSSMSTRM pStrm);
     754static int                  ssmR3StrmReadMore(PSSMSTRM pStrm);
    752755static int                  ssmR3CalcChecksum(RTFILE File, uint64_t cbFile, uint32_t *pu32CRC);
    753756static void                 ssmR3Progress(PSSMHANDLE pSSM, uint64_t cbAdvance);
     
    13691372    pStrm->rc           = VINF_SUCCESS;
    13701373    pStrm->hIoThread    = NIL_RTTHREAD;
     1374    pStrm->offNeedSeekTo= UINT64_MAX;
    13711375
    13721376    pStrm->pHead        = NULL;
     
    16551659            if (RT_FAILURE(pStrm->rc))
    16561660                return NULL;
     1661            if (    !pStrm->fWrite
     1662                &&  pStrm->hIoThread == NIL_RTTHREAD)
     1663            {
     1664                int rc = ssmR3StrmReadMore(pStrm);
     1665                if (RT_FAILURE(rc))
     1666                    return NULL;
     1667                continue;
     1668            }
     1669
    16571670            int rc = RTSemEventWaitNoResume(pStrm->hEvtHead, 30000);
    16581671            if (    rc == VERR_SEM_DESTROYED
     
    16871700                                                     cb - pStrm->offStreamCRC);
    16881701            pStrm->offCurStream += cb;
    1689             pStrm->off          = 0;
    1690             pStrm->offStreamCRC = 0;
     1702            pStrm->off           = 0;
     1703            pStrm->offStreamCRC  = 0;
    16911704
    16921705            ssmR3StrmPutBuf(pStrm, pBuf);
     
    17011714                                                     cb - pStrm->offStreamCRC);
    17021715            pStrm->offCurStream += cb;
    1703             pStrm->off          = 0;
    1704             pStrm->offStreamCRC = 0;
     1716            pStrm->off           = 0;
     1717            pStrm->offStreamCRC  = 0;
    17051718
    17061719            ssmR3StrmPutFreeBuf(pStrm, pBuf);
     
    17671780{
    17681781    /*
    1769      * Flush and close the stream.
     1782     * Flush, terminate the I/O thread, and close the stream.
    17701783     */
    17711784    if (pStrm->fWrite)
    17721785    {
    17731786        ssmR3StrmFlushCurBuf(pStrm);
    1774         ssmR3StrmWriteBuffers(pStrm);
    1775     }
     1787        if (pStrm->hIoThread == NIL_RTTHREAD)
     1788            ssmR3StrmWriteBuffers(pStrm);
     1789    }
     1790
     1791    if (pStrm->hIoThread != NIL_RTTHREAD)
     1792    {
     1793        ASMAtomicWriteBool(&pStrm->fTerminating, true);
     1794        int rc2 = RTSemEventSignal(pStrm->fWrite ? pStrm->hEvtHead : pStrm->hEvtFree); AssertLogRelRC(rc2);
     1795        int rc3 = RTThreadWait(pStrm->hIoThread, RT_INDEFINITE_WAIT, NULL);            AssertLogRelRC(rc3);
     1796        pStrm->hIoThread = NIL_RTTHREAD;
     1797    }
     1798
    17761799    int rc = RTFileClose(pStrm->hFile);
    17771800    if (RT_FAILURE(rc))
     
    19221945 * Read more from the stream.
    19231946 *
    1924  * @returns VBox status code. VERR_EOF is passed up.
     1947 * @returns VBox status code. VERR_EOF gets translated into VINF_EOF.
    19251948 * @param   pStrm       The stream handle.
    19261949 *
    1927  * @thread  The I/O thread when we get one.
     1950 * @thread  The I/O thread when we got one, otherwise the stream user.
    19281951 */
    19291952static int ssmR3StrmReadMore(PSSMSTRM pStrm)
    19301953{
    19311954    int rc;
     1955    Log6(("ssmR3StrmReadMore:\n"));
    19321956
    19331957    /*
     
    19361960    if (pStrm->fNeedSeek)
    19371961    {
    1938         rc = RTFileSeek(pStrm->hFile, pStrm->offCurStream + pStrm->off, RTFILE_SEEK_BEGIN, NULL);
     1962        rc = RTFileSeek(pStrm->hFile, pStrm->offNeedSeekTo, RTFILE_SEEK_BEGIN, NULL);
    19391963        if (RT_FAILURE(rc))
    19401964        {
    19411965            if (ssmR3StrmSetError(pStrm, rc))
    1942                 LogRel(("ssmR3StrmReadMore: RTFileSeek(,%#llx,) failed with rc=%Rrc\n", pStrm->offCurStream + pStrm->off, rc));
     1966                LogRel(("ssmR3StrmReadMore: RTFileSeek(,%#llx,) failed with rc=%Rrc\n", pStrm->offNeedSeekTo, rc));
    19431967            return rc;
    19441968        }
    1945 
     1969        pStrm->fNeedSeek     = false;
     1970        pStrm->offNeedSeekTo = UINT64_MAX;
    19461971    }
    19471972
     
    19531978        return pStrm->rc;
    19541979
    1955     pBuf->offStream = pStrm->offCurStream + pStrm->off;
    1956     Assert(pBuf->offStream == RTFileTell(pStrm->hFile));
     1980    pBuf->offStream = RTFileTell(pStrm->hFile);
    19571981    size_t cbRead   = sizeof(pBuf->abData);
    19581982    rc = RTFileRead(pStrm->hFile, &pBuf->abData[0], cbRead, &cbRead);
    1959     if (RT_SUCCESS(rc))
     1983    if (    RT_SUCCESS(rc)
     1984        &&  cbRead > 0)
    19601985    {
    19611986        pBuf->cb           = (uint32_t)cbRead;
    1962         pBuf->fEndOfStream = cbRead == 0; /** @todo Check out this EOF mess... */
     1987        pBuf->fEndOfStream = false;
     1988        Log6(("ssmR3StrmReadMore: %#010llx %#x\n", pBuf->offStream, pBuf->cb));
    19631989        ssmR3StrmPutBuf(pStrm, pBuf);
    19641990    }
    1965     else if (rc == VERR_EOF)
     1991    else if (   (   RT_SUCCESS_NP(rc)
     1992                 && cbRead == 0)
     1993             || rc == VERR_EOF)
    19661994    {
    19671995        pBuf->cb           = 0;
    19681996        pBuf->fEndOfStream = true;
     1997        Log6(("ssmR3StrmReadMore: %#010llx 0 EOF!\n", pBuf->offStream));
    19691998        ssmR3StrmPutBuf(pStrm, pBuf);
     1999        rc = VINF_EOF;
    19702000    }
    19712001    else
    19722002    {
     2003        Log6(("ssmR3StrmReadMore: %#010llx rc=%Rrc!\n", pBuf->offStream, rc));
    19732004        if (ssmR3StrmSetError(pStrm, rc))
    19742005            LogRel(("ssmR3StrmReadMore: RTFileRead(,,%#x,) -> %Rrc at offset %#llx\n",
     
    20372068         */
    20382069        ssmR3StrmFlushCurBuf(pStrm);
    2039         if (pStrm->hIoThread == NIL_RTTHREAD)
    2040         {
    2041             rc = ssmR3StrmReadMore(pStrm);
    2042             if (RT_FAILURE(rc))
    2043                 break;
    2044         }
    20452070        PSSMSTRMBUF pBuf = ssmR3StrmGetBuf(pStrm);
    20462071        if (!pBuf)
     
    21952220    {
    21962221        pStrm->fNeedSeek    = false;
     2222        pStrm->offNeedSeekTo= UINT64_MAX;
    21972223        pStrm->offCurStream = offStream;
    21982224        pStrm->off          = 0;
     
    22882314    AssertReturn(pStrm->hIoThread == NIL_RTTHREAD, VERR_WRONG_ORDER);
    22892315
    2290     pStrm->fNeedSeek = true;
     2316    if (!pStrm->fNeedSeek)
     2317    {
     2318        pStrm->fNeedSeek     = true;
     2319        pStrm->offNeedSeekTo = pStrm->offCurStream + (pStrm->pCur ? pStrm->pCur->cb : 0);
     2320    }
     2321
    22912322    int rc = RTFileSeek(pStrm->hFile, off, off >= 0 ? RTFILE_SEEK_BEGIN : RTFILE_SEEK_END, poff);
    22922323    if (RT_SUCCESS(rc))
     
    22942325
    22952326    return rc;
     2327}
     2328
     2329
     2330/**
     2331 * The I/O thread.
     2332 *
     2333 * @returns VINF_SUCCESS (ignored).
     2334 * @param   hSelf       The thread handle.
     2335 * @param   pvStrm      The stream handle.
     2336 */
     2337static DECLCALLBACK(int) ssmR3StrmIoThread(RTTHREAD hSelf, void *pvStrm)
     2338{
     2339    PSSMSTRM pStrm = (PSSMSTRM)pvStrm;
     2340    ASMAtomicWriteHandle(&pStrm->hIoThread, hSelf); /* paranoia */
     2341
     2342    Log(("ssmR3StrmIoThread: starts working\n"));
     2343    if (pStrm->fWrite)
     2344    {
     2345        /*
     2346         * Write until error or terminated.
     2347         */
     2348        for (;;)
     2349        {
     2350
     2351        }
     2352    }
     2353    else
     2354    {
     2355        /*
     2356         * Read until end of file, error or termination.
     2357         */
     2358        for (;;)
     2359        {
     2360            if (ASMAtomicReadBool(&pStrm->fTerminating))
     2361            {
     2362                Log(("ssmR3StrmIoThread: quitting reading because of pending termination.\n"));
     2363                break;
     2364            }
     2365
     2366            int rc = ssmR3StrmReadMore(pStrm);
     2367            if (    RT_FAILURE(rc)
     2368                ||  rc == VINF_EOF)
     2369            {
     2370                Log(("ssmR3StrmIoThread: quitting reading with rc=%Rrc\n", rc));
     2371                break;
     2372            }
     2373            if (RT_FAILURE(pStrm->rc))
     2374            {
     2375                Log(("ssmR3StrmIoThread: quitting reading with stream rc=%Rrc\n", pStrm->rc));
     2376                break;
     2377            }
     2378        }
     2379    }
     2380
     2381    return VINF_SUCCESS;
     2382}
     2383
     2384
     2385/**
     2386 * Starts the I/O thread for the specified stream.
     2387 *
     2388 * @param   pStrm       The stream handle.
     2389 */
     2390static void ssmR3StrmStartIoThread(PSSMSTRM pStrm)
     2391{
     2392    Assert(pStrm->hIoThread == NIL_RTTHREAD);
     2393
     2394    RTTHREAD hThread;
     2395    int rc = RTThreadCreate(&hThread, ssmR3StrmIoThread, pStrm, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SSM-IO");
     2396    AssertRCReturnVoid(rc);
     2397    ASMAtomicWriteHandle(&pStrm->hIoThread, hThread); /* paranoia */
    22962398}
    22972399
     
    35753677    if (RT_SUCCESS(rc))
    35763678    {
     3679        ssmR3StrmStartIoThread(&Handle.Strm);
     3680
    35773681        Handle.enmAfter     = enmAfter;
    35783682        Handle.pfnProgress  = pfnProgress;
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