VirtualBox

Changeset 21399 in vbox


Ignore:
Timestamp:
Jul 8, 2009 2:35:30 PM (16 years ago)
Author:
vboxsync
Message:

timerlr-generic.cpp,iprt/timer.h: Skip ticks if we're more than 60 ticks behind. See #3611.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/timer.h

    r20374 r21399  
    231231 * @param   pvUser      User argument.
    232232 * @param   iTick       The current timer tick. This is always 1 on the first
    233  *                      callback after the timer was started. For omni timers
    234  *                      this will be 1 when a cpu comes back online.
     233 *                      callback after the timer was started. Will jump if we've
     234 *                      skipped ticks when lagging behind.
    235235 */
    236236typedef DECLCALLBACK(void) FNRTTIMERLR(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
  • trunk/src/VBox/Runtime/generic/timerlr-generic.cpp

    r21337 r21399  
    261261        else
    262262        {
    263             const uint64_t u64NanoTS = RTTimeNanoTS();
     263            uint64_t        cNanoSeconds;
     264            const uint64_t  u64NanoTS = RTTimeNanoTS();
    264265            if (u64NanoTS >= pThis->u64NextTS)
    265266            {
     
    279280                }
    280281
    281                 /* calc the next time we should fire. */
     282                /*
     283                 * Calc the next time we should fire.
     284                 *
     285                 * If we're more than 60 intervals behind, just skip ahead. We
     286                 * don't want the timer thread running wild just because the
     287                 * clock changed in an unexpected way. As seen in #3611 this
     288                 * does happen during suspend/resume, but it may also happen
     289                 * if we're using a non-monotonic clock as time source.
     290                 */
    282291                pThis->u64NextTS = pThis->u64StartTS + pThis->iTick * pThis->u64NanoInterval;
    283                 if (pThis->u64NextTS < u64NanoTS)
    284 #ifdef IN_RING3 /* In ring-3 we'll catch up lost ticks immediately. */
    285                     pThis->u64NextTS = u64NanoTS + 1;
     292                if (RT_LIKELY(pThis->u64NextTS > u64NanoTS))
     293                    cNanoSeconds = pThis->u64NextTS - u64NanoTS;
     294                else
     295                {
     296                    uint64_t iActualTick = (u64NanoTS - pThis->u64StartTS) / pThis->u64NanoInterval;
     297                    if (iActualTick - pThis->iTick > 60)
     298                        pThis->iTick = iActualTick - 1;
     299#ifdef IN_RING0
     300                    cNanoSeconds = RTTimerGetSystemGranularity() / 2;
    286301#else
    287                     pThis->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2;
     302                    cNanoSeconds = 1000000; /* 1ms */
    288303#endif
     304                    pThis->u64NextTS = u64NanoTS + cNanoSeconds;
     305                }
    289306            }
     307            else
     308                cNanoSeconds = pThis->u64NextTS - u64NanoTS;
    290309
    291310            /* block. */
    292             uint64_t cNanoSeconds = pThis->u64NextTS - u64NanoTS;
    293 #ifdef IN_RING3 /* In ring-3 we'll catch up lost ticks immediately. */
    294             if (cNanoSeconds > 10)
    295 #endif
     311            int rc = RTSemEventWait(pThis->hEvent, cNanoSeconds < 1000000 ? 1 : cNanoSeconds / 1000000);
     312            if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED && rc != VERR_TIMEOUT)
    296313            {
    297                 int rc = RTSemEventWait(pThis->hEvent, cNanoSeconds < 1000000 ? 1 : cNanoSeconds / 1000000);
    298                 if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED && rc != VERR_TIMEOUT)
    299                 {
    300                     AssertRC(rc);
    301                     RTThreadSleep(1000); /* Don't cause trouble! */
    302                 }
     314                AssertRC(rc);
     315                RTThreadSleep(1000); /* Don't cause trouble! */
    303316            }
    304317        }
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