VirtualBox

Changeset 9444 in vbox for trunk/src/VBox/Runtime/r0drv


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/Runtime/r0drv
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • 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;
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