VirtualBox

Ignore:
Timestamp:
Jun 6, 2008 11:44:27 AM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
31723
Message:

Fixes and optimizations. The HRTIMER code is still unusable, though. :-/

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c

    r9444 r9466  
    108108    /** Pointer to the parent timer. */
    109109    PRTTIMER                pParent;
     110#ifndef RT_USE_LINUX_HRTIMER
     111    /** The u64NextTS in jiffies. */
     112    unsigned long           ulNextJiffies;
     113#endif
    110114    /** The current sub-timer state. */
    111115    RTTIMERLNXSTATE volatile enmState;
     
    146150    /** The timer interval. 0 if one-shot. */
    147151    uint64_t                u64NanoInterval;
     152#ifndef RT_USE_LINUX_HRTIMER
     153    /** This is set to the number of jiffies between ticks if the interval is
     154     * an exact number of jiffies. */
     155    unsigned long           cJiffies;
     156#endif
    148157    /** Sub-timers.
    149158     * Normally there is just one, but for RTTIMER_FLAGS_CPU_ALL this will contain
     
    195204
    196205
    197 #ifndef RT_USE_LINUX_HRTIMER
     206#ifdef RT_USE_LINUX_HRTIMER
     207/**
     208 * Converts a nano second time stamp to ktime_t.
     209 *
     210 * ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts().
     211 *
     212 * @returns ktime_t.
     213 * @param   cNanoSecs   Nanoseconds.
     214 */
     215DECLINLINE(ktime_t) rtTimerLnxNanoToKt(uint64_t cNanoSecs)
     216{
     217    /* With some luck the compiler optimizes the division out of this... (Bet it doesn't.) */
     218    return ktime_set(cNanoSecs / 1000000000, cNanoSecs % 1000000000);
     219}
     220
     221/**
     222 * Converts ktime_t to a nano second time stamp.
     223 *
     224 * ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts().
     225 *
     226 * @returns nano second time stamp.
     227 * @param   Kt          ktime_t.
     228 */
     229DECLINLINE(uint64_t) rtTimerLnxKtToNano(ktime_t Kt)
     230{
     231    return ktime_to_ns(Kt);
     232}
     233
     234#else /* ! RT_USE_LINUX_HRTIMER */
     235
    198236/**
    199237 * Converts a nano second interval to jiffies.
     
    234272
    235273#ifdef RT_USE_LINUX_HRTIMER
    236     {
    237         /* ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts(). */
    238         struct timespec Ts;
    239         ktime_t Kt;
    240         Ts.tv_sec  = u64NextTS / 1000000000;
    241         Ts.tv_nsec = u64NextTS % 1000000000;
    242         Kt = timespec_to_ktime(Ts);
    243         hrtimer_start(&pSubTimer->LnxTimer, Kt, HRTIMER_MODE_ABS);
    244     }
     274    hrtimer_start(&pSubTimer->LnxTimer, rtTimerLnxNanoToKt(u64NextTS), HRTIMER_MODE_ABS);
    245275#else
    246276    {
    247277        unsigned long cJiffies = !u64First ? 0 : rtTimerLnxNanoToJiffies(u64First);
    248         mod_timer(&pSubTimer->LnxTimer, jiffies + cJiffies);
     278        pSubTimer->ulNextJiffies = jiffies + cJiffies;
     279        mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies);
    249280    }
    250281#endif
     
    341372        const uint64_t u64NanoTS = RTTimeNanoTS();
    342373        const uint64_t iTick = ++pSubTimer->iTick;
    343 #ifdef RT_USE_LINUX_HRTIMER
    344         if (iTick == 1)
    345             pSubTimer->u64StartTS = u64NanoTS;
    346 #endif
    347         pSubTimer->u64NextTS = pSubTimer->u64StartTS
    348                              + iTick * pTimer->u64NanoInterval;
    349         if (pSubTimer->u64NextTS < u64NanoTS)
    350             pSubTimer->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2;
    351 
    352 #ifdef RT_USE_LINUX_HRTIMER
     374
     375        if (RT_UNLIKELY(iTick == 1))
    353376        {
    354             /* ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts(). */
    355             struct timespec Ts;
    356             Ts.tv_sec  = pSubTimer->u64NextTS / 1000000000;
    357             Ts.tv_nsec = pSubTimer->u64NextTS % 1000000000;
    358             pSubTimer->LnxTimer.expires = timespec_to_ktime(Ts);
    359             rc = HRTIMER_RESTART;
     377#ifdef RT_USE_LINUX_HRTIMER
     378            pSubTimer->u64StartTS = pSubTimer->u64NextTS = u64NanoTS;//rtTimerLnxKtToNano(pSubTimer->LnxTimer.base->softirq_time);
     379#else
     380            pSubTimer->u64StartTS = pSubTimer->u64NextTS = u64NanoTS;
     381            pSubTimer->ulNextJiffies = jiffies;
     382#endif
    360383        }
    361 #else
     384
     385        pSubTimer->u64NextTS += pTimer->u64NanoInterval;
     386
     387#ifdef RT_USE_LINUX_HRTIMER
     388        while (pSubTimer->u64NextTS < u64NanoTS)
     389            pSubTimer->u64NextTS += pTimer->u64NanoInterval;
     390
     391        pSubTimer->LnxTimer.expires = rtTimerLnxNanoToKt(pSubTimer->u64NextTS);
     392        rc = HRTIMER_RESTART;
     393#else
     394        if (pTimer->cJiffies)
    362395        {
    363             uint64_t offDelta = pSubTimer->u64NextTS - u64NanoTS;
    364             unsigned long cJiffies = rtTimerLnxNanoToJiffies(offDelta);
    365             mod_timer(&pSubTimer->LnxTimer, jiffies + cJiffies);
     396            pSubTimer->ulNextJiffies += pTimer->cJiffies;
     397            while (pSubTimer->ulNextJiffies < jiffies)
     398            {
     399                pSubTimer->ulNextJiffies += pTimer->cJiffies;
     400                pSubTimer->u64NextTS += pTimer->u64NanoInterval;
     401            }
    366402        }
     403        else
     404        {
     405            while (pSubTimer->u64NextTS < u64NanoTS)
     406                pSubTimer->u64NextTS += pTimer->u64NanoInterval;
     407            pSubTimer->ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u64NextTS - u64NanoTS);
     408        }
     409
     410        mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies);
    367411#endif
    368412
     
    826870    pTimer->pvUser = pvUser;
    827871    pTimer->u64NanoInterval = u64NanoInterval;
     872#ifndef RT_USE_LINUX_HRTIMER
     873    pTimer->cJiffies = u64NanoInterval / RTTimerGetSystemGranularity();
     874    if (pTimer->cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval)
     875        pTimer->cJiffies = 0;
     876#endif
    828877
    829878    for (iCpu = 0; iCpu < cCpus; iCpu++)
     
    875924{
    876925#ifdef RT_USE_LINUX_HRTIMER
    877     /** @todo later... */
     926    struct timespec Ts;
     927    int rc = hrtimer_get_res(CLOCK_MONOTONIC, &Ts);
     928    if (!rc)
     929    {
     930        Assert(!Ts.tv_sec);
     931        return Ts.tv_nsec;
     932    }
    878933    return 1000000000 / HZ; /* ns */
    879934#else
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