VirtualBox

Changeset 9444 in vbox for trunk/src


Ignore:
Timestamp:
Jun 5, 2008 6:08:17 PM (17 years ago)
Author:
vboxsync
Message:

Added iTick to FNTIMER (the timer callback).

Location:
trunk/src/VBox
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c

    r9429 r9444  
    253253static int      supdrvGipCreate(PSUPDRVDEVEXT pDevExt);
    254254static void     supdrvGipDestroy(PSUPDRVDEVEXT pDevExt);
    255 static DECLCALLBACK(void) supdrvGipTimer(PRTTIMER pTimer, void *pvUser);
     255static DECLCALLBACK(void) supdrvGipTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
    256256#endif
    257257
     
    38253825 * @param   pTimer      The timer.
    38263826 * @param   pvUser      The device extension.
    3827  */
    3828 static DECLCALLBACK(void) supdrvGipTimer(PRTTIMER pTimer, void *pvUser)
     3827 * @param   iTick       The current tick.
     3828 */
     3829static DECLCALLBACK(void) supdrvGipTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
    38293830{
    38303831    PSUPDRVDEVEXT pDevExt  = (PSUPDRVDEVEXT)pvUser;
    38313832    supdrvGipUpdate(pDevExt->pGip, RTTimeSystemNanoTS());
     3833    NOREF(iTick);
    38323834}
    38333835#endif /* USE_NEW_OS_INTERFACE_FOR_GIP */
  • trunk/src/VBox/Main/xpcom/server.cpp

    r9332 r9444  
    435435    };
    436436
    437     static void ShutdownTimer (PRTTIMER pTimer, void *pvUser)
     437    static void ShutdownTimer (PRTTIMER pTimer, void *pvUser, uint64_t /*iTick*/)
    438438    {
    439439        NOREF (pTimer);
  • trunk/src/VBox/Runtime/generic/timer-generic.cpp

    r9416 r9444  
    249249            {
    250250                pTimer->iTick++;
    251                 pTimer->pfnTimer(pTimer, pTimer->pvUser);
     251                pTimer->pfnTimer(pTimer, pTimer->pvUser, pTimer->iTick);
    252252
    253253                /* status changed? */
  • trunk/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c

    r9352 r9444  
    9797     * Validate flags.
    9898     */
    99     if (!RTTIMER_FLAGS_IS_VALID(fFlags))
     99    if (!RTTIMER_FLAGS_ARE_VALID(fFlags))
    100100        return VERR_INVALID_PARAMETER;
    101101    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
     
    214214    if (    pTimer->iCpu == RTTIMER_FLAGS_CPU_MASK
    215215        ||  (u_int)pTimer->iCpu == curcpu)
    216         pTimer->pfnTimer(pTimer, pTimer->pvUser);
     216        pTimer->pfnTimer(pTimer, pTimer->pvUser, pTimer->iTick);
    217217}
    218218
     
    223223
    224224    /* calculate and set the next timeout */
     225    pTimer->iTick++;
    225226    if (!pTimer->u64NanoInterval)
    226227    {
     
    232233        struct timeval tv;
    233234        const uint64_t u64NanoTS = RTTimeNanoTS();
    234         pTimer->iTick++;
    235235        pTimer->u64NextTS = pTimer->u64StartTS + pTimer->iTick * pTimer->u64NanoInterval;
    236236        if (pTimer->u64NextTS < u64NanoTS)
     
    245245    if (    !pTimer->fSpecificCpu
    246246        ||  pTimer->iCpu == curcpu)
    247         pTimer->pfnTimer(pTimer, pTimer->pvUser);
     247        pTimer->pfnTimer(pTimer, pTimer->pvUser, pTimer->iTick);
    248248    else
    249249        smp_rendezvous(NULL, rtTimerFreeBSDIpiAction, NULL, pvTimer);
  • trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c

    r9372 r9444  
    4646#include "internal/magics.h"
    4747
    48 #if !defined(RT_USE_LINUX_HRTIMER) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) /* ?? */
     48#if !defined(RT_USE_LINUX_HRTIMER) \
     49    && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) \
     50    && 0 /* disabled because it somehow sucks. */
    4951# define RT_USE_LINUX_HRTIMER
    5052#endif
     
    193195
    194196
     197#ifndef RT_USE_LINUX_HRTIMER
     198/**
     199 * Converts a nano second interval to jiffies.
     200 *
     201 * @returns Jiffies.
     202 * @param   cNanoSecs   Nanoseconds.
     203 */
     204DECLINLINE(unsigned long) rtTimerLnxNanoToJiffies(uint64_t cNanoSecs)
     205{
     206    /* this can be made even better... */
     207    if (cNanoSecs > (uint64_t)TICK_NSEC * MAX_JIFFY_OFFSET)
     208        return MAX_JIFFY_OFFSET;
     209#if ARCH_BITS == 32
     210    if (RT_LIKELY(cNanoSecs <= UINT32_MAX))
     211        return ((uint32_t)cNanoSecs + (TICK_NSEC-1)) / TICK_NSEC;
     212#endif
     213    return (cNanoSecs + (TICK_NSEC-1)) / TICK_NSEC;
     214}
     215#endif
     216
     217
    195218/**
    196219 * Starts a sub-timer (RTTimerStart).
     
    206229     */
    207230    uint64_t u64NextTS = u64Now + u64First;
    208     pSubTimer->u64StartTS = u64Now;
     231    pSubTimer->u64StartTS = u64NextTS;
    209232    pSubTimer->u64NextTS = u64NextTS;
     233    pSubTimer->iTick = 0;
    210234
    211235#ifdef RT_USE_LINUX_HRTIMER
     
    221245#else
    222246    {
    223         uint64_t cJiffies = !u64First ? 0 : u64First / TICK_NSEC;
    224         if (cJiffies > MAX_JIFFY_OFFSET)
    225             cJiffies = MAX_JIFFY_OFFSET;
     247        unsigned long cJiffies = !u64First ? 0 : rtTimerLnxNanoToJiffies(u64First);
    226248        mod_timer(&pSubTimer->LnxTimer, jiffies + cJiffies);
    227249    }
     
    280302     * For the specific cpu case, we're just ignoring timer migration for now... (bad)
    281303     */
    282     if (    pTimer->fSuspended
     304    if (    ASMAtomicUoReadBool(&pTimer->fSuspended)
    283305#ifdef CONFIG_SMP
    284306        ||  (   pTimer->fAllCpus
     
    306328#endif
    307329
    308         pTimer->pfnTimer(pTimer, pTimer->pvUser);
     330        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
    309331    }
    310332    else
     
    318340         */
    319341        const uint64_t u64NanoTS = RTTimeNanoTS();
    320 #if 0 /* this needs to be tested before it's enabled. */
    321         if (    pSubTimer->iTick == 0
    322             &&  pTimer->u64NanoInterval < u64NanoTS)
    323             pSubTimer->u64StartTS = pSubTimer->u64FirstTS = u64NanoTS - 1000; /* ugly */
    324 #endif
    325         pSubTimer->iTick++;
     342        const uint64_t iTick = ++pSubTimer->iTick;
     343#ifdef RT_USE_LINUX_HRTIMER
     344        if (iTick == 1)
     345            pSubTimer->u64StartTS = u64NanoTS;
     346#endif
    326347        pSubTimer->u64NextTS = pSubTimer->u64StartTS
    327                              + pSubTimer->iTick * pTimer->u64NanoInterval;
     348                             + iTick * pTimer->u64NanoInterval;
    328349        if (pSubTimer->u64NextTS < u64NanoTS)
    329350            pSubTimer->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2;
     
    341362        {
    342363            uint64_t offDelta = pSubTimer->u64NextTS - u64NanoTS;
    343             uint64_t cJiffies = offDelta / TICK_NSEC; /* (We end up doing 64-bit div here which ever way we go.) */
    344             if (cJiffies > MAX_JIFFY_OFFSET)
    345                 cJiffies = MAX_JIFFY_OFFSET;
    346             else if (cJiffies == 0)
    347                 cJiffies = 1;
     364            unsigned long cJiffies = rtTimerLnxNanoToJiffies(offDelta);
    348365            mod_timer(&pSubTimer->LnxTimer, jiffies + cJiffies);
    349366        }
     
    353370         * Run the timer.
    354371         */
    355         pTimer->pfnTimer(pTimer, pTimer->pvUser);
     372        pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
    356373    }
    357374
     
    512529
    513530    /*
    514      * We have to be kind of careful here as we might RTTimerStop (and RTTimerDestroy),
    515      * thus the paranoia.
     531     * We have to be kind of careful here as we might be racing RTTimerStop
     532     * (and/or RTTimerDestroy, thus the paranoia.
    516533     */
    517534    hSpinlock = pTimer->hSpinlock;
     
    522539        RTSpinlockAcquire(hSpinlock, &Tmp);
    523540
    524         if (    !pTimer->fSuspended
     541        if (    !ASMAtomicUoReadBool(&pTimer->fSuspended)
    525542            &&  pTimer->u32Magic == RTTIMER_MAGIC)
    526543        {
     
    564581
    565582    /* Is it active? */
    566     if (    !pTimer->fSuspended
    567         &&  !pTimer->u32Magic == RTTIMER_MAGIC)
     583    if (    !ASMAtomicUoReadBool(&pTimer->fSuspended)
     584        &&  pTimer->u32Magic == RTTIMER_MAGIC)
    568585    {
    569586        switch (enmEvent)
     
    578595                    RTTIMERLINUXSTARTONCPUARGS Args;
    579596                    Args.u64Now = RTTimeNanoTS();
    580                     Args.u64First = pTimer->u64NanoInterval;
     597                    Args.u64First = 0;
    581598
    582599                    if (RTMpCpuId() == idCpu)
     
    644661    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
    645662
    646     if (!pTimer->fSuspended)
     663    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
    647664        return VERR_TIMER_ACTIVE;
    648665
    649666    Args.u64First = u64First;
    650667#ifdef CONFIG_SMP
     668    /*
     669     * Omnit timer?
     670     */
    651671    if (pTimer->fAllCpus)
    652672        return rtTimerLnxStartAll(pTimer, &Args);
     
    654674
    655675    /*
    656      * This is pretty straight forwards.
     676     * Simple timer - Pretty straight forward.
    657677     */
    658678    Args.u64Now = RTTimeNanoTS();
     
    686706    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
    687707
    688     if (pTimer->fSuspended)
     708    if (ASMAtomicUoReadBool(&pTimer->fSuspended))
    689709        return VERR_TIMER_SUSPENDED;
    690710
    691711#ifdef CONFIG_SMP
     712    /*
     713     * Omni timer?
     714     */
    692715    if (pTimer->fAllCpus)
    693716        return rtTimerLnxStopAll(pTimer);
     
    695718
    696719    /*
    697      * Cancel the timer.
    698      */
    699     ASMAtomicWriteBool(&pTimer->fSuspended, true); /* just to be on the safe side. */
     720     * Simple timer.
     721     */
     722    ASMAtomicWriteBool(&pTimer->fSuspended, true);
    700723    rtTimerLnxSetState(&pTimer->aSubTimers[0].enmState, RTTIMERLNXSTATE_STOPPING);
    701724    rtTimerLnxStopSubTimer(&pTimer->aSubTimers[0]);
     
    732755     * Stop the timer if it's running.
    733756     */
    734     if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) /* serious paranoia */
     757    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
    735758        RTTimerStop(pTimer);
    736759
     
    759782     * Validate flags.
    760783     */
    761     if (!RTTIMER_FLAGS_IS_VALID(fFlags))
     784    if (!RTTIMER_FLAGS_ARE_VALID(fFlags))
    762785        return VERR_INVALID_PARAMETER;
    763786    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
     
    811834#else
    812835        init_timer(&pTimer->aSubTimers[iCpu].LnxTimer);
    813         pTimer->aSubTimers[iCpu].LnxTimer.data     = (unsigned long)pTimer;
     836        pTimer->aSubTimers[iCpu].LnxTimer.data     = (unsigned long)&pTimer->aSubTimers[iCpu];
    814837        pTimer->aSubTimers[iCpu].LnxTimer.function = rtTimerLinuxCallback;
    815838        pTimer->aSubTimers[iCpu].LnxTimer.expires  = jiffies;
  • trunk/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp

    r9416 r9444  
    319319        {
    320320            pTimer->fDone = true;
     321            pTimer->iTick++;
    321322
    322323            /* calculate the next timeout */
     
    334335            void       *pvUser   = pTimer->pvUser;
    335336            RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);
    336             pfnTimer(pTimer, pvUser);
     337            pfnTimer(pTimer, pvUser, pTimer->iTick);
    337338
    338339            RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);
  • trunk/src/VBox/Runtime/r0drv/solaris/timer-r0drv-solaris.c

    r8245 r9444  
    6464    /** The CPU it must run on if fSpecificCpu is set. */
    6565    uint8_t                 iCpu;
     66    /** The current timer tick (since last timer start). */
     67    uint64_t                iTick;
    6668    /** The Solaris cyclic structure. */
    6769    cyc_handler_t           CyclicInfo;
     
    9193     * Validate flags.
    9294     */
    93     if (!RTTIMER_FLAGS_IS_VALID(fFlags))
     95    if (!RTTIMER_FLAGS_ARE_VALID(fFlags))
    9496        return VERR_INVALID_PARAMETER;
    9597    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
    9698        /** @todo implement &&  (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL*/)
    9799        return VERR_NOT_SUPPORTED;
    98    
     100
    99101    /*
    100102     * Allocate and initialize the timer handle.
     
    108110    pTimer->fSpecificCpu = !!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC);
    109111    pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
     112    pTimer->iTick = 0;
    110113    pTimer->CyclicInfo.cyh_func = rtTimerSolarisCallback;
    111114    pTimer->CyclicInfo.cyh_level = CY_LOCK_LEVEL;
     
    167170
    168171    pTimer->fSuspended = false;
     172    pTimer->iTick = 0;
    169173    timerSpec.cyt_when = u64First;
    170174    timerSpec.cyt_interval = pTimer->u64NanoInterval == 0 ? u64First : pTimer->u64NanoInterval;
    171    
     175
    172176    mutex_enter(&cpu_lock);
    173177    pTimer->CyclicID = cyclic_add(&pTimer->CyclicInfo, &timerSpec);
     
    190194    pTimer->fSuspended = true;
    191195    rtTimerSolarisStop(pTimer);
    192    
     196
    193197    return VINF_SUCCESS;
    194198}
     
    209213
    210214    /* Callback user defined callback function */
    211     pTimer->pfnTimer(pTimer, pTimer->pvUser);
     215    pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->iTick);
    212216}
    213217
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c

    r9176 r9444  
    6565    uint8_t                 iCpu;
    6666    /** The Solaris timer handle. */
    67     void                    *handle;
     67    void                   *handle;
     68    /** The user callback. */
     69    PFNRTTIMER              pfnTimer;
     70    /** The current tick count. */
     71    uint64_t                iTick;
     72
    6873} RTTIMER;
    6974
    7075
     76/**
     77 * Callback wrapper for adding the new iTick argument.
     78 *
     79 * @param   pTimer  The timer.
     80 * @param   pvUser  The user argument.
     81 */
     82static void rtTimerSolarisCallbackWrapper(PRTTIMER pTimer, void *pvUser)
     83{
     84    pTimer->pfnTimer(pTimer, pvUser, ++pTimer->iTick);
     85}
     86
     87
     88
     89
    7190RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    7291{
     
    7695     * Validate flags.
    7796     */
    78     if (!RTTIMER_FLAGS_IS_VALID(fFlags))
     97    if (!RTTIMER_FLAGS_ARE_VALID(fFlags))
    7998        return VERR_INVALID_PARAMETER;
    8099    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
     
    93112    pTimer->fSpecificCpu = !!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC);
    94113    pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
    95     pTimer->handle = vbi_timer_create(pfnTimer, pTimer, pvUser, u64NanoInterval);
     114    pTimer->handle = vbi_timer_create(rtTimerSolarisCallbackWrapper, pTimer, pvUser, u64NanoInterval);
     115    pTimer->pfnTimer = pfnTimer;
     116    pTimer->iTick = 0;
    96117
    97118    *ppTimer = pTimer;
  • trunk/src/VBox/Runtime/r3/posix/timer-posix.cpp

    r9416 r9444  
    8686    /** The first shot interval. 0 if ASAP. */
    8787    uint64_t volatile       u64NanoFirst;
     88    /** The current timer tick. */
     89    uint64_t volatile       iTick;
    8890    /** The error/status of the timer.
    8991     * Initially -1, set to 0 when the timer have been successfully started, and
     
    239241                        break;
    240242
    241                     pTimer->pfnTimer(pTimer, pTimer->pvUser);
     243                    pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->iTick);
    242244
    243245                    /* auto suspend one-shot timers. */
     
    372374        pTimer->u64NanoInterval = u64NanoInterval;
    373375        pTimer->u64NanoFirst = 0;
     376        pTimer->iTick       = 0;
    374377        pTimer->iError      = 0;
    375378        rc = RTSemEventCreate(&pTimer->Event);
     
    474477     */
    475478    RTThreadUserReset(pTimer->Thread);
    476     ASMAtomicXchgU64(&pTimer->u64NanoFirst, u64First);
    477     ASMAtomicXchgU8(&pTimer->fSuspended, false);
     479    ASMAtomicUoWriteU64(&pTimer->u64NanoFirst, u64First);
     480    ASMAtomicUoWriteU64(&pTimer->iTick, 0);
     481    ASMAtomicWriteU8(&pTimer->fSuspended, false);
    478482    int rc = RTSemEventSignal(pTimer->Event);
    479483    if (RT_SUCCESS(rc))
  • trunk/src/VBox/Runtime/r3/win/timer-win.cpp

    r8245 r9444  
    9898    /** Callback. */
    9999    PFNRTTIMER              pfnTimer;
     100    /** The current tick. */
     101    uint64_t                iTick;
    100102    /** The interval. */
    101103    unsigned                uMilliesInterval;
     
    106108    /** Time handle. */
    107109    HANDLE                  hTimer;
    108 #ifdef USE_APC
     110# ifdef USE_APC
    109111    /** Handle to wait on. */
    110112    HANDLE                  hevWait;
    111 #endif
     113# endif
    112114    /** USE_CATCH_UP: ns time of the next tick.
    113115     * !USE_CATCH_UP: -uMilliesInterval * 10000 */
     
    132134    PRTTIMER pTimer = (PRTTIMER)(void *)dwUser;
    133135    Assert(pTimer->TimerId == uTimerID);
    134     pTimer->pfnTimer(pTimer, pTimer->pvUser);
     136    pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->iTick);
    135137    NOREF(uMsg); NOREF(dw1); NOREF(dw2); NOREF(uTimerID);
    136138}
     
    156158     * Callback the handler.
    157159     */
    158     pTimer->pfnTimer(pTimer, pTimer->pvUser);
     160    pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->iTick);
    159161
    160162    /*
     
    240242             * Callback the handler.
    241243             */
    242             pTimer->pfnTimer(pTimer, pTimer->pvUser);
     244            pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->iTick);
    243245
    244246            /*
     
    321323        pTimer->pvUser      = pvUser;
    322324        pTimer->pfnTimer    = pfnTimer;
     325        pTimer->iTick       = 0;
    323326        pTimer->uMilliesInterval = uMilliesInterval;
    324327#ifdef USE_WINMM
  • trunk/src/VBox/Runtime/testcase/tstTimer.cpp

    r8245 r9444  
    4949static volatile uint64_t gu64Prev;
    5050
    51 static DECLCALLBACK(void) TimerCallback(PRTTIMER pTimer, void *pvUser)
     51static DECLCALLBACK(void) TimerCallback(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
    5252{
    5353    gcTicks++;
  • trunk/src/VBox/VMM/TM.cpp

    r9354 r9444  
    13081308 *          So, we'll just raise the timer FF and force any REM execution to exit.
    13091309 */
    1310 static DECLCALLBACK(void) tmR3TimerCallback(PRTTIMER pTimer, void *pvUser)
     1310static DECLCALLBACK(void) tmR3TimerCallback(PRTTIMER pTimer, void *pvUser, uint64_t /*iTick*/)
    13111311{
    13121312    PVM pVM = (PVM)pvUser;
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