VirtualBox

Changeset 19538 in vbox for trunk


Ignore:
Timestamp:
May 8, 2009 6:12:33 PM (16 years ago)
Author:
vboxsync
Message:

TM: Moved TMR3TimerDestroy from TMAll.cpp to TM.cpp.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/TM.cpp

    r19537 r19538  
    13271327
    13281328    return NULL;
     1329}
     1330
     1331
     1332/**
     1333 * Destroy a timer
     1334 *
     1335 * @returns VBox status.
     1336 * @param   pTimer          Timer handle as returned by one of the create functions.
     1337 */
     1338VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer)
     1339{
     1340    /*
     1341     * Be extra careful here.
     1342     */
     1343    if (!pTimer)
     1344        return VINF_SUCCESS;
     1345    AssertPtr(pTimer);
     1346    Assert((unsigned)pTimer->enmClock < (unsigned)TMCLOCK_MAX);
     1347
     1348    PVM             pVM      = pTimer->CTX_SUFF(pVM);
     1349    PTMTIMERQUEUE   pQueue   = &pVM->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock];
     1350    bool            fActive  = false;
     1351    bool            fPending = false;
     1352
     1353    /*
     1354     * The rest of the game happens behind the lock, just
     1355     * like create does. All the work is done here.
     1356     */
     1357    tmLock(pVM);
     1358    for (int cRetries = 1000;; cRetries--)
     1359    {
     1360        /*
     1361         * Change to the DESTROY state.
     1362         */
     1363        TMTIMERSTATE enmState    = pTimer->enmState;
     1364        TMTIMERSTATE enmNewState = enmState;
     1365        Log2(("TMTimerDestroy: %p:{.enmState=%s, .pszDesc='%s'} cRetries=%d\n",
     1366              pTimer, tmTimerState(enmState), R3STRING(pTimer->pszDesc), cRetries));
     1367        switch (enmState)
     1368        {
     1369            case TMTIMERSTATE_STOPPED:
     1370            case TMTIMERSTATE_EXPIRED:
     1371                break;
     1372
     1373            case TMTIMERSTATE_ACTIVE:
     1374                fActive     = true;
     1375                break;
     1376
     1377            case TMTIMERSTATE_PENDING_STOP:
     1378            case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
     1379            case TMTIMERSTATE_PENDING_RESCHEDULE:
     1380                fActive     = true;
     1381                fPending    = true;
     1382                break;
     1383
     1384            case TMTIMERSTATE_PENDING_SCHEDULE:
     1385                fPending    = true;
     1386                break;
     1387
     1388            /*
     1389             * This shouldn't happen as the caller should make sure there are no races.
     1390             */
     1391            case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
     1392            case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
     1393                AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
     1394                tmUnlock(pVM);
     1395                if (!RTThreadYield())
     1396                    RTThreadSleep(1);
     1397                AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
     1398                                VERR_TM_UNSTABLE_STATE);
     1399                tmLock(pVM);
     1400                continue;
     1401
     1402            /*
     1403             * Invalid states.
     1404             */
     1405            case TMTIMERSTATE_FREE:
     1406            case TMTIMERSTATE_DESTROY:
     1407                tmUnlock(pVM);
     1408                AssertLogRelMsgFailedReturn(("pTimer=%p %s\n", pTimer, tmTimerState(enmState)), VERR_TM_INVALID_STATE);
     1409
     1410            default:
     1411                AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
     1412                tmUnlock(pVM);
     1413                return VERR_TM_UNKNOWN_STATE;
     1414        }
     1415
     1416        /*
     1417         * Try switch to the destroy state.
     1418         * This should always succeed as the caller should make sure there are no race.
     1419         */
     1420        bool fRc;
     1421        TM_TRY_SET_STATE(pTimer, TMTIMERSTATE_DESTROY, enmState, fRc);
     1422        if (fRc)
     1423            break;
     1424        AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
     1425        tmUnlock(pVM);
     1426        AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
     1427                        VERR_TM_UNSTABLE_STATE);
     1428        tmLock(pVM);
     1429    }
     1430
     1431    /*
     1432     * Unlink from the active list.
     1433     */
     1434    if (fActive)
     1435    {
     1436        const PTMTIMER pPrev = TMTIMER_GET_PREV(pTimer);
     1437        const PTMTIMER pNext = TMTIMER_GET_NEXT(pTimer);
     1438        if (pPrev)
     1439            TMTIMER_SET_NEXT(pPrev, pNext);
     1440        else
     1441        {
     1442            TMTIMER_SET_HEAD(pQueue, pNext);
     1443            pQueue->u64Expire = pNext ? pNext->u64Expire : INT64_MAX;
     1444        }
     1445        if (pNext)
     1446            TMTIMER_SET_PREV(pNext, pPrev);
     1447        pTimer->offNext = 0;
     1448        pTimer->offPrev = 0;
     1449    }
     1450
     1451    /*
     1452     * Unlink from the schedule list by running it.
     1453     */
     1454    if (fPending)
     1455    {
     1456        Log3(("TMR3TimerDestroy: tmTimerQueueSchedule\n"));
     1457        STAM_PROFILE_START(&pVM->tm.s.CTXALLSUFF(StatScheduleOne), a);
     1458        Assert(pQueue->offSchedule);
     1459        tmTimerQueueSchedule(pVM, pQueue);
     1460    }
     1461
     1462    /*
     1463     * Read to move the timer from the created list and onto the free list.
     1464     */
     1465    Assert(!pTimer->offNext); Assert(!pTimer->offPrev); Assert(!pTimer->offScheduleNext);
     1466
     1467    /* unlink from created list */
     1468    if (pTimer->pBigPrev)
     1469        pTimer->pBigPrev->pBigNext = pTimer->pBigNext;
     1470    else
     1471        pVM->tm.s.pCreated         = pTimer->pBigNext;
     1472    if (pTimer->pBigNext)
     1473        pTimer->pBigNext->pBigPrev = pTimer->pBigPrev;
     1474    pTimer->pBigNext = 0;
     1475    pTimer->pBigPrev = 0;
     1476
     1477    /* free */
     1478    Log2(("TM: Inserting %p into the free list ahead of %p!\n", pTimer, pVM->tm.s.pFree));
     1479    TM_SET_STATE(pTimer, TMTIMERSTATE_FREE);
     1480    pTimer->pBigNext = pVM->tm.s.pFree;
     1481    pVM->tm.s.pFree = pTimer;
     1482
     1483#ifdef VBOX_STRICT
     1484    tmTimerQueuesSanityChecks(pVM, "TMR3TimerDestroy");
     1485#endif
     1486    tmUnlock(pVM);
     1487    return VINF_SUCCESS;
    13291488}
    13301489
  • trunk/src/VBox/VMM/VMMAll/TMAll.cpp

    r19537 r19538  
    535535    return (PTMTIMERRC)MMHyperCCToRC(pTimer->CTX_SUFF(pVM), pTimer);
    536536}
    537 
    538 
    539 #ifdef IN_RING3 /* Kept here until properly cleaned up to not use any of the local functions. */
    540 /**
    541  * Destroy a timer
    542  *
    543  * @returns VBox status.
    544  * @param   pTimer          Timer handle as returned by one of the create functions.
    545  */
    546 VMMR3DECL(int) TMR3TimerDestroy(TMTIMER *pTimer)
    547 {
    548     /*
    549      * Be extra careful here.
    550      */
    551     if (!pTimer)
    552         return VINF_SUCCESS;
    553     AssertPtr(pTimer);
    554     Assert((unsigned)pTimer->enmClock < (unsigned)TMCLOCK_MAX);
    555 
    556     PVM             pVM      = pTimer->CTX_SUFF(pVM);
    557     PTMTIMERQUEUE   pQueue   = &pVM->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock];
    558     bool            fActive  = false;
    559     bool            fPending = false;
    560 
    561     /*
    562      * The rest of the game happens behind the lock, just
    563      * like create does. All the work is done here.
    564      */
    565     tmLock(pVM);
    566     for (int cRetries = 1000;; cRetries--)
    567     {
    568         /*
    569          * Change to the DESTROY state.
    570          */
    571         TMTIMERSTATE enmState    = pTimer->enmState;
    572         TMTIMERSTATE enmNewState = enmState;
    573         Log2(("TMTimerDestroy: %p:{.enmState=%s, .pszDesc='%s'} cRetries=%d\n",
    574               pTimer, tmTimerState(enmState), R3STRING(pTimer->pszDesc), cRetries));
    575         switch (enmState)
    576         {
    577             case TMTIMERSTATE_STOPPED:
    578             case TMTIMERSTATE_EXPIRED:
    579                 break;
    580 
    581             case TMTIMERSTATE_ACTIVE:
    582                 fActive     = true;
    583                 break;
    584 
    585             case TMTIMERSTATE_PENDING_STOP:
    586             case TMTIMERSTATE_PENDING_STOP_SCHEDULE:
    587             case TMTIMERSTATE_PENDING_RESCHEDULE:
    588                 fActive     = true;
    589                 fPending    = true;
    590                 break;
    591 
    592             case TMTIMERSTATE_PENDING_SCHEDULE:
    593                 fPending    = true;
    594                 break;
    595 
    596             /*
    597              * This shouldn't happen as the caller should make sure there are no races.
    598              */
    599             case TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE:
    600             case TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE:
    601                 AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
    602                 tmUnlock(pVM);
    603                 if (!RTThreadYield())
    604                     RTThreadSleep(1);
    605                 AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
    606                                 VERR_TM_UNSTABLE_STATE);
    607                 tmLock(pVM);
    608                 continue;
    609 
    610             /*
    611              * Invalid states.
    612              */
    613             case TMTIMERSTATE_FREE:
    614             case TMTIMERSTATE_DESTROY:
    615                 tmUnlock(pVM);
    616                 AssertLogRelMsgFailedReturn(("pTimer=%p %s\n", pTimer, tmTimerState(enmState)), VERR_TM_INVALID_STATE);
    617 
    618             default:
    619                 AssertMsgFailed(("Unknown timer state %d (%s)\n", enmState, R3STRING(pTimer->pszDesc)));
    620                 tmUnlock(pVM);
    621                 return VERR_TM_UNKNOWN_STATE;
    622         }
    623 
    624         /*
    625          * Try switch to the destroy state.
    626          * This should always succeed as the caller should make sure there are no race.
    627          */
    628         if (tmTimerTry(pTimer, TMTIMERSTATE_DESTROY, enmState))
    629             break;
    630         AssertMsgFailed(("%p:.enmState=%s %s\n", pTimer, tmTimerState(enmState), pTimer->pszDesc));
    631         tmUnlock(pVM);
    632         AssertMsgReturn(cRetries > 0, ("Failed waiting for stable state. state=%d (%s)\n", pTimer->enmState, pTimer->pszDesc),
    633                         VERR_TM_UNSTABLE_STATE);
    634         tmLock(pVM);
    635     }
    636 
    637     /*
    638      * Unlink from the active list.
    639      */
    640     if (fActive)
    641     {
    642         const PTMTIMER pPrev = TMTIMER_GET_PREV(pTimer);
    643         const PTMTIMER pNext = TMTIMER_GET_NEXT(pTimer);
    644         if (pPrev)
    645             TMTIMER_SET_NEXT(pPrev, pNext);
    646         else
    647         {
    648             TMTIMER_SET_HEAD(pQueue, pNext);
    649             pQueue->u64Expire = pNext ? pNext->u64Expire : INT64_MAX;
    650         }
    651         if (pNext)
    652             TMTIMER_SET_PREV(pNext, pPrev);
    653         pTimer->offNext = 0;
    654         pTimer->offPrev = 0;
    655     }
    656 
    657     /*
    658      * Unlink from the schedule list by running it.
    659      */
    660     if (fPending)
    661     {
    662         Log3(("TMR3TimerDestroy: tmTimerQueueSchedule\n"));
    663         STAM_PROFILE_START(&pVM->tm.s.CTXALLSUFF(StatScheduleOne), a);
    664         Assert(pQueue->offSchedule);
    665         tmTimerQueueSchedule(pVM, pQueue);
    666     }
    667 
    668     /*
    669      * Read to move the timer from the created list and onto the free list.
    670      */
    671     Assert(!pTimer->offNext); Assert(!pTimer->offPrev); Assert(!pTimer->offScheduleNext);
    672 
    673     /* unlink from created list */
    674     if (pTimer->pBigPrev)
    675         pTimer->pBigPrev->pBigNext = pTimer->pBigNext;
    676     else
    677         pVM->tm.s.pCreated         = pTimer->pBigNext;
    678     if (pTimer->pBigNext)
    679         pTimer->pBigNext->pBigPrev = pTimer->pBigPrev;
    680     pTimer->pBigNext = 0;
    681     pTimer->pBigPrev = 0;
    682 
    683     /* free */
    684     Log2(("TM: Inserting %p into the free list ahead of %p!\n", pTimer, pVM->tm.s.pFree));
    685     TM_SET_STATE(pTimer, TMTIMERSTATE_FREE);
    686     pTimer->pBigNext = pVM->tm.s.pFree;
    687     pVM->tm.s.pFree = pTimer;
    688 
    689 #ifdef VBOX_STRICT
    690     tmTimerQueuesSanityChecks(pVM, "TMR3TimerDestroy");
    691 #endif
    692     tmUnlock(pVM);
    693     return VINF_SUCCESS;
    694 }
    695 #endif /* IN_RING3 */
    696537
    697538
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