VirtualBox

Changeset 32572 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Sep 16, 2010 4:18:12 PM (14 years ago)
Author:
vboxsync
Message:

VMM,SUPDrv,IPRT: More changes for related to the priodic preemption timer. (still disabled)

Location:
trunk/src/VBox/Runtime
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r32529 r32572  
    13901390        generic/RTLogWriteStdErr-stub-generic.cpp \
    13911391        generic/RTLogWriteUser-generic.cpp \
     1392        generic/RTMpGetArraySize-generic.cpp \
    13921393        generic/RTRandAdvCreateSystemFaster-generic.cpp \
    13931394        generic/uuid-generic.cpp \
  • trunk/src/VBox/Runtime/generic/timer-generic.cpp

    r32504 r32572  
    8787
    8888
    89 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     89RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    9090{
    9191    *ppTimer = NULL;
     
    225225}
    226226RT_EXPORT_SYMBOL(RTTimerStop);
     227
     228
     229RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     230{
     231    if (!rtTimerIsValid(pTimer))
     232        return VERR_INVALID_HANDLE;
     233    return VERR_NOT_SUPPORTED;
     234}
     235RT_EXPORT_SYMBOL(RTTimerChangeInterval);
    227236
    228237
  • trunk/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c

    r32504 r32572  
    9090
    9191
    92 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     92RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    9393{
    9494    *ppTimer = NULL;
     
    102102        &&  (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL
    103103        &&  (fFlags & RTTIMER_FLAGS_CPU_MASK) > mp_maxid)
    104         return VERR_INVALID_PARAMETER;
     104        return VERR_CPU_NOT_FOUND;
    105105
    106106    /*
     
    166166    if (!pTimer->fSuspended)
    167167        return VERR_TIMER_ACTIVE;
     168    if (   pTimer->fSpecificCpu
     169        && !RTMpIsCpuOnline(pTimer->idCpu))
     170        return VERR_CPU_OFFLINE;
    168171
    169172    /*
     
    199202
    200203    return VINF_SUCCESS;
     204}
     205
     206
     207RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     208{
     209    if (!rtTimerIsValid(pTimer))
     210        return VERR_INVALID_HANDLE;
     211    return VERR_NOT_SUPPORTED;
    201212}
    202213
  • trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c

    r32504 r32572  
    55
    66/*
    7  * Copyright (C) 2006-2008 Oracle Corporation
     7 * Copyright (C) 2006-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4444#include "internal/magics.h"
    4545
    46 /* We use the API of Linux 2.6.28+ (hrtimer_add_expires_ns()) */
    47 #if !defined(RT_USE_LINUX_HRTIMER) \
    48     && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) \
     46/** @def RTTIMER_LINUX_HAVE_HRTIMER
     47 * Whether the kernel support high resolution timers (Linux kernel versions
     48 * 2.6.28 and later (hrtimer_add_expires_ns()). */
     49#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
     50# define RTTIMER_LINUX_HAVE_HRTIMER
     51#endif
     52
     53/** @def RTTIMER_LINUX_ONLY_HRTIMER
     54 * Whether to use high resolution timers for everything or not.  Implies
     55 * RTTIMER_LINUX_WITH_HRTIMER. */
     56#if !defined(RTTIMER_LINUX_ONLY_HRTIMER) \
     57    && defined(RTTIMER_LINUX_HAVE_HRTIMER) \
    4958    && 0 /* currently disabled */
    50 # define RT_USE_LINUX_HRTIMER
     59# define RTTIMER_LINUX_ONLY_HRTIMER
    5160#endif
    5261
    5362/* This check must match the ktime usage in rtTimeGetSystemNanoTS() / time-r0drv-linux.c. */
    54 #if defined(RT_USE_LINUX_HRTIMER) \
    55  && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
    56 # error "RT_USE_LINUX_HRTIMER requires 2.6.28 or later, sorry."
     63#if defined(RTTIMER_LINUX_ONLY_HRTIMER) \
     64 && !defined(RTTIMER_LINUX_HAVE_HRTIMER)
     65# error "RTTIMER_LINUX_ONLY_HRTIMER requires 2.6.28 or later, sorry."
     66#endif
     67
     68/** @def RTTIMER_LINUX_WITH_HRTIMER
     69 * Whether to use high resolution timers.  */
     70#if !defined(RTTIMER_LINUX_WITH_HRTIMER) \
     71    && defined(RTTIMER_LINUX_HAVE_HRTIMER)
     72# define RTTIMER_LINUX_WITH_HRTIMER
    5773#endif
    5874
     
    96112typedef struct RTTIMERLNXSUBTIMER
    97113{
    98     /** The linux timer structure. */
    99 #ifdef RT_USE_LINUX_HRTIMER
    100     struct hrtimer          LnxTimer;
    101 #else
    102     struct timer_list       LnxTimer;
    103     /** The start of the current run (ns).
    104      * This is used to calculate when the timer ought to fire the next time. */
    105     uint64_t                u64StartTS;
    106     /** The start of the current run (ns).
    107      * This is used to calculate when the timer ought to fire the next time. */
    108     uint64_t                u64NextTS;
    109 #endif
    110     /** The current tick number (since u64StartTS). */
     114    /** Timer specific data.  */
     115    union
     116    {
     117#if defined(RTTIMER_LINUX_WITH_HRTIMER)
     118        /** High resolution timer. */
     119        struct
     120        {
     121            /** The linux timer structure. */
     122            struct hrtimer          LnxTimer;
     123        } Hr;
     124#endif
     125#ifndef RTTIMER_LINUX_ONLY_HRTIMER
     126        /** Standard timer. */
     127        struct
     128        {
     129            /** The linux timer structure. */
     130            struct timer_list       LnxTimer;
     131            /** The start of the current run (ns).
     132             * This is used to calculate when the timer ought to fire the next time. */
     133            uint64_t                u64StartTS;
     134            /** The start of the current run (ns).
     135             * This is used to calculate when the timer ought to fire the next time. */
     136            uint64_t                u64NextTS;
     137            /** The u64NextTS in jiffies. */
     138            unsigned long           ulNextJiffies;
     139        } Std;
     140#endif
     141    } u;
     142    /** The current tick number (since u.Std.u64StartTS). */
    111143    uint64_t                iTick;
    112144    /** Pointer to the parent timer. */
    113145    PRTTIMER                pParent;
    114 #ifndef RT_USE_LINUX_HRTIMER
    115     /** The u64NextTS in jiffies. */
    116     unsigned long           ulNextJiffies;
    117 #endif
    118146    /** The current sub-timer state. */
    119147    RTTIMERLNXSTATE volatile enmState;
     
    121149/** Pointer to a linux sub-timer. */
    122150typedef RTTIMERLNXSUBTIMER *PRTTIMERLNXSUBTIMER;
    123 AssertCompileMemberOffset(RTTIMERLNXSUBTIMER, LnxTimer, 0);
    124151
    125152
     
    144171    bool                    fAllCpus;
    145172#endif /* else: All -> specific on non-SMP kernels */
    146     /** The CPU it must run on if fSpecificCpu is set. */
     173    /** Whether it is a high resolution timer or a standard one. */
     174    bool                    fHighRes;
     175    /** The id of the CPU it must run on if fSpecificCpu is set. */
    147176    RTCPUID                 idCpu;
    148177    /** The number of CPUs this timer should run on. */
     
    153182    void                   *pvUser;
    154183    /** The timer interval. 0 if one-shot. */
    155     uint64_t                u64NanoInterval;
    156 #ifndef RT_USE_LINUX_HRTIMER
     184    uint64_t volatile       u64NanoInterval;
     185#ifndef RTTIMER_LINUX_ONLY_HRTIMER
    157186    /** This is set to the number of jiffies between ticks if the interval is
    158187     * an exact number of jiffies. */
     
    210239}
    211240
    212 
    213 #ifdef RT_USE_LINUX_HRTIMER
     241#ifdef RTTIMER_LINUX_WITH_HRTIMER
     242
    214243/**
    215244 * Converts a nano second time stamp to ktime_t.
     
    239268}
    240269
    241 #else /* ! RT_USE_LINUX_HRTIMER */
    242 
     270#endif /* RTTIMER_LINUX_WITH_HRTIMER */
     271
     272#ifndef RTTIMER_LINUX_ONLY_HRTIMER
    243273/**
    244274 * Converts a nano second interval to jiffies.
     
    258288    return (cNanoSecs + (TICK_NSEC-1)) / TICK_NSEC;
    259289}
    260 #endif /* ! RT_USE_LINUX_HRTIMER */
     290#endif /* !RTTIMER_LINUX_ONLY_HRTIMER */
    261291
    262292
     
    269299 * @param   fPinned     true = timer pinned to a specific CPU,
    270300 *                      false = timer can migrate between CPUs
    271  */
    272 static void rtTimerLnxStartSubTimer(PRTTIMERLNXSUBTIMER pSubTimer, uint64_t u64Now, uint64_t u64First, bool fPinned)
     301 * @param   fHighRes    Whether the user requested a high resolution timer or not.
     302 */
     303static void rtTimerLnxStartSubTimer(PRTTIMERLNXSUBTIMER pSubTimer, uint64_t u64Now, uint64_t u64First,
     304                                    bool fPinned, bool fHighRes)
    273305{
    274306    /*
     
    276308     */
    277309    uint64_t u64NextTS = u64Now + u64First;
    278 #ifndef RT_USE_LINUX_HRTIMER
    279     pSubTimer->u64StartTS = u64NextTS;
    280     pSubTimer->u64NextTS = u64NextTS;
     310#ifndef RTTIMER_LINUX_ONLY_HRTIMER
     311    if (fHighRes)
     312    {
     313        pSubTimer->u.Std.u64StartTS = u64NextTS;
     314        pSubTimer->u.Std.u64NextTS  = u64NextTS;
     315    }
    281316#endif
    282317
    283318    pSubTimer->iTick = 0;
    284319
    285 #ifdef RT_USE_LINUX_HRTIMER
    286     hrtimer_start(&pSubTimer->LnxTimer, rtTimerLnxNanoToKt(u64NextTS),
    287                   fPinned ? HRTIMER_MODE_ABS_PINNED : HRTIMER_MODE_ABS);
    288 #else
     320#ifdef RTTIMER_LINUX_WITH_HRTIMER
     321# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     322    if (fHighRes)
     323# endif
     324        hrtimer_start(&pSubTimer->u.Hr.LnxTimer, rtTimerLnxNanoToKt(u64NextTS),
     325                      fPinned ? HRTIMER_MODE_ABS_PINNED : HRTIMER_MODE_ABS);
     326# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     327    else
     328# endif
     329#endif
     330#ifndef RTTIMER_LINUX_ONLY_HRTIMER
    289331    {
    290332        unsigned long cJiffies = !u64First ? 0 : rtTimerLnxNanoToJiffies(u64First);
    291         pSubTimer->ulNextJiffies = jiffies + cJiffies;
     333        pSubTimer->u.Std.ulNextJiffies = jiffies + cJiffies;
    292334# ifdef CONFIG_SMP
    293335        if (fPinned)
    294             mod_timer_pinned(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies);
     336            mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
    295337        else
    296338# endif
    297             mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies);
     339            mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
    298340    }
    299341#endif
     
    310352static void rtTimerLnxStopSubTimer(PRTTIMERLNXSUBTIMER pSubTimer)
    311353{
    312 #ifdef RT_USE_LINUX_HRTIMER
    313     hrtimer_cancel(&pSubTimer->LnxTimer);
    314 #else
    315     if (timer_pending(&pSubTimer->LnxTimer))
    316         del_timer_sync(&pSubTimer->LnxTimer);
     354#ifdef RTTIMER_LINUX_WITH_HRTIMER
     355# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     356    if (pSubTimer->pParent->fHighRes)
     357# endif
     358        hrtimer_cancel(&pSubTimer->u.Hr.LnxTimer);
     359# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     360    else
     361# endif
     362#endif
     363# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     364    {
     365        if (timer_pending(&pSubTimer->u.Std.LnxTimer))
     366            del_timer_sync(&pSubTimer->u.Std.LnxTimer);
     367    }
    317368#endif
    318369
     
    321372
    322373
    323 #ifdef RT_USE_LINUX_HRTIMER
    324 /**
    325  * Timer callback function.
    326  * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a one-shot or interval timer.
     374#ifdef RTTIMER_LINUX_WITH_HRTIMER
     375/**
     376 * Timer callback function for high resolution timers.
     377 *
     378 * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a
     379 *          one-shot or interval timer.
    327380 * @param   pHrTimer    Pointer to the sub-timer structure.
    328381 */
    329 static enum hrtimer_restart rtTimerLinuxCallback(struct hrtimer *pHrTimer)
    330 #else
    331 /**
    332  * Timer callback function.
    333  * @param   ulUser      Address of the sub-timer structure.
    334  */
    335 static void rtTimerLinuxCallback(unsigned long ulUser)
    336 #endif
    337 {
    338 #ifdef RT_USE_LINUX_HRTIMER
    339     enum hrtimer_restart rc;
    340     PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)pHrTimer;
    341 #else
    342     PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)ulUser;
    343 #endif
    344     PRTTIMER pTimer = pSubTimer->pParent;
     382static enum hrtimer_restart rtTimerLinuxHrCallback(struct hrtimer *pHrTimer)
     383{
     384    PRTTIMERLNXSUBTIMER     pSubTimer = RT_FROM_MEMBER(pHrTimer, RTTIMERLNXSUBTIMER, u.Hr.LnxTimer);
     385    PRTTIMER                pTimer    = pSubTimer->pParent;
     386    enum hrtimer_restart    rc;
    345387
    346388    /*
     
    359401    {
    360402        rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE);
    361 # ifdef RT_USE_LINUX_HRTIMER
    362403        rc = HRTIMER_NORESTART;
    363 # endif
    364404    }
    365405    else if (!pTimer->u64NanoInterval)
     
    371411            ASMAtomicWriteBool(&pTimer->fSuspended, true);
    372412        rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE);
    373 #ifdef RT_USE_LINUX_HRTIMER
    374413        rc = HRTIMER_NORESTART;
    375 #else
    376         /* detached before we're called, nothing to do for this case. */
    377 #endif
    378 
    379414        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
    380415    }
    381416    else
    382417    {
     418        /*
     419         * Run the timer.  Update the timer after calling the method.
     420         */
    383421        const uint64_t iTick = ++pSubTimer->iTick;
    384 
    385 #ifdef RT_USE_LINUX_HRTIMER
    386         hrtimer_add_expires_ns(&pSubTimer->LnxTimer, pTimer->u64NanoInterval);
    387         rc = HRTIMER_RESTART;
    388 #else
    389         const uint64_t u64NanoTS = RTTimeNanoTS();
    390 
     422        pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
     423
     424        /** @todo Check reference counting wrt. RTTimerDestroy from the
     425         *        callback? */
     426        if (   pSubTimer->enmState == RTTIMERLNXSTATE_ACTIVE
     427            || pSubTimer->enmState == RTTIMERLNXSTATE_MP_STARTING)
     428        {
     429            hrtimer_add_expires_ns(&pSubTimer->u.Hr.LnxTimer, ASMAtomicReadU64(&pTimer->u64NanoInterval));
     430            rc = HRTIMER_RESTART;
     431        }
     432        else
     433            rc = HRTIMER_NORESTART;
     434    }
     435
     436    return rc;
     437}
     438#endif /* RTTIMER_LINUX_ONLY_HRTIMER */
     439
     440
     441#ifndef RTTIMER_LINUX_ONLY_HRTIMER
     442/**
     443 * Timer callback function for standard timers.
     444 *
     445 * @param   ulUser      Address of the sub-timer structure.
     446 */
     447static void rtTimerLinuxStdCallback(unsigned long ulUser)
     448{
     449    PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)ulUser;
     450    PRTTIMER            pTimer    = pSubTimer->pParent;
     451
     452    /*
     453     * Don't call the handler if the timer has been suspended.
     454     * Also, when running on all CPUS, make sure we don't call out twice
     455     * on a CPU because of timer migration.
     456     *
     457     * For the specific cpu case, we're just ignoring timer migration for now... (bad)
     458     */
     459    if (    ASMAtomicUoReadBool(&pTimer->fSuspended)
     460#ifdef CONFIG_SMP
     461        ||  (   pTimer->fAllCpus
     462             && (RTCPUID)(pSubTimer - &pTimer->aSubTimers[0]) != RTMpCpuId())
     463#endif
     464       )
     465        rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE);
     466    else if (!pTimer->u64NanoInterval)
     467    {
     468        /*
     469         * One shot timer, stop it before dispatching it.
     470         */
     471        if (pTimer->cCpus == 1)
     472            ASMAtomicWriteBool(&pTimer->fSuspended, true);
     473        rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE);
     474        pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
     475    }
     476    else
     477    {
    391478        /*
    392479         * Interval timer, calculate the next timeout and re-arm it.
    393480         *
    394          * The first time around, we'll re-adjust the u64StartTS to
     481         * The first time around, we'll re-adjust the u.Std.u64StartTS to
    395482         * try prevent some jittering if we were started at a bad time.
    396483         * This may of course backfire with highres timers...
     484         *
     485         * Note! u64NanoInterval won't change for standard timers.
    397486         */
     487        const uint64_t iTick            = ++pSubTimer->iTick;
     488        const uint64_t u64NanoInterval  = pTimer->u64NanoInterval;
     489        const uint64_t u64NanoTS        = RTTimeNanoTS();
     490
    398491        if (RT_UNLIKELY(iTick == 1))
    399492        {
    400             pSubTimer->u64StartTS = pSubTimer->u64NextTS = u64NanoTS;
    401             pSubTimer->ulNextJiffies = jiffies;
     493            pSubTimer->u.Std.u64StartTS    = u64NanoTS;
     494            pSubTimer->u.Std.u64NextTS     = u64NanoTS;
     495            pSubTimer->u.Std.ulNextJiffies = jiffies;
    402496        }
    403497
    404         pSubTimer->u64NextTS += pTimer->u64NanoInterval;
     498        pSubTimer->u.Std.u64NextTS += u64NanoInterval;
    405499        if (pTimer->cJiffies)
    406500        {
    407             pSubTimer->ulNextJiffies += pTimer->cJiffies;
     501            pSubTimer->u.Std.ulNextJiffies += pTimer->cJiffies;
    408502            /* Prevent overflows when the jiffies counter wraps around.
    409503             * Special thanks to Ken Preslan for helping debugging! */
    410             while (time_before(pSubTimer->ulNextJiffies, jiffies))
     504            while (time_before(pSubTimer->u.Std.ulNextJiffies, jiffies))
    411505            {
    412                 pSubTimer->ulNextJiffies += pTimer->cJiffies;
    413                 pSubTimer->u64NextTS += pTimer->u64NanoInterval;
     506                pSubTimer->u.Std.ulNextJiffies += pTimer->cJiffies;
     507                pSubTimer->u.Std.u64NextTS += u64NanoInterval;
    414508            }
    415509        }
    416510        else
    417511        {
    418             while (pSubTimer->u64NextTS < u64NanoTS)
    419                 pSubTimer->u64NextTS += pTimer->u64NanoInterval;
    420             pSubTimer->ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u64NextTS - u64NanoTS);
     512            while (pSubTimer->u.Std.u64NextTS < u64NanoTS)
     513                pSubTimer->u.Std.u64NextTS += u64NanoInterval;
     514            pSubTimer->u.Std.ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u.Std.u64NextTS - u64NanoTS);
    421515        }
    422516
    423517# ifdef CONFIG_SMP
    424518        if (pTimer->fSpecificCpu || pTimer->fAllCpus)
    425             mod_timer_pinned(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies);
     519            mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
    426520        else
    427521# endif
    428             mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies);
    429 #endif
     522            mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies);
    430523
    431524        /*
     
    434527        pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
    435528    }
    436 
    437 #ifdef RT_USE_LINUX_HRTIMER
    438     return rc;
    439 #endif
    440 }
     529}
     530#endif /* !RTTIMER_LINUX_ONLY_HRTIMER */
     531
    441532
    442533
     
    455546    PRTTIMER pTimer = (PRTTIMER)pvUser1;
    456547    Assert(idCpu < pTimer->cCpus);
    457     rtTimerLnxStartSubTimer(&pTimer->aSubTimers[idCpu], pArgs->u64Now, pArgs->u64First, true /*fPinned*/);
     548    rtTimerLnxStartSubTimer(&pTimer->aSubTimers[idCpu], pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes);
    458549}
    459550
     
    607698            PRTTIMERLNXSUBTIMER pSubTimer = &pTimer->aSubTimers[idCpu];
    608699            if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_MP_STARTING, RTTIMERLNXSTATE_STOPPED))
    609                 rtTimerLnxStartSubTimer(pSubTimer, pArgs->u64Now, pArgs->u64First, true /*fPinned*/);
     700                rtTimerLnxStartSubTimer(pSubTimer, pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes);
    610701        }
    611702
     
    660751
    661752                    if (RTMpCpuId() == idCpu)
    662                         rtTimerLnxStartSubTimer(pSubTimer, Args.u64Now, Args.u64First, true /*fPinned*/);
     753                        rtTimerLnxStartSubTimer(pSubTimer, Args.u64Now, Args.u64First, true /*fPinned*/, pTimer->fHighRes);
    663754                    else
    664755                    {
     
    708799    PRTTIMERLINUXSTARTONCPUARGS pArgs = (PRTTIMERLINUXSTARTONCPUARGS)pvUser2;
    709800    PRTTIMER pTimer = (PRTTIMER)pvUser1;
    710     rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], pArgs->u64Now, pArgs->u64First, true /*fPinned*/);
     801    rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes);
    711802}
    712803
     
    742833    ASMAtomicWriteBool(&pTimer->fSuspended, false);
    743834    if (!pTimer->fSpecificCpu)
    744         rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], Args.u64Now, Args.u64First, false /*fPinned*/);
     835    {
     836        rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], Args.u64Now, Args.u64First, false /*fPinned*/, pTimer->fHighRes);
     837    }
    745838    else
    746839    {
     
    792885
    793886
     887RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     888{
     889    int rc = VINF_SUCCESS;
     890
     891    /*
     892     * Validate.
     893     */
     894    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
     895    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
     896    AssertReturn(u64NanoInterval, VERR_INVALID_PARAMETER);
     897
     898    /*
     899     * Make the change.
     900     */
     901#ifdef RTTIMER_LINUX_WITH_HRTIMER
     902# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     903    if (pTimer->fHighRes)
     904# endif
     905        ASMAtomicWriteU64(&pTimer->u64NanoInterval, u64NanoInterval);
     906# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     907    else
     908# endif
     909#endif
     910#ifndef RTTIMER_LINUX_ONLY_HRTIMER
     911        rc = VERR_NOT_SUPPORTED; /** @todo Implement this if needed. */
     912#endif
     913
     914    return rc;
     915}
     916RT_EXPORT_SYMBOL(RTTimerChangeInterval);
     917
     918
    794919RTDECL(int) RTTimerDestroy(PRTTIMER pTimer)
    795920{
     
    836961
    837962
    838 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    839 {
    840     PRTTIMER pTimer;
    841     RTCPUID  iCpu;
    842     unsigned cCpus;
     963RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     964{
     965    PRTTIMER    pTimer;
     966    RTCPUID     iCpu;
     967    unsigned    cCpus;
    843968
    844969    *ppTimer = NULL;
     
    851976    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
    852977        &&  (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL
    853         &&  !RTMpIsCpuOnline(fFlags & RTTIMER_FLAGS_CPU_MASK))
    854         return (fFlags & RTTIMER_FLAGS_CPU_MASK) > RTMpGetMaxCpuId()
    855              ? VERR_CPU_NOT_FOUND
    856              : VERR_CPU_OFFLINE;
     978        &&  !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK)))
     979        return VERR_CPU_NOT_FOUND;
    857980
    858981    /*
     
    8791002    pTimer->hSpinlock = NIL_RTSPINLOCK;
    8801003    pTimer->fSuspended = true;
     1004    pTimer->fHighRes = !!(fFlags & RTTIMER_FLAGS_HIGH_RES);
    8811005#ifdef CONFIG_SMP
    8821006    pTimer->fSpecificCpu = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL;
    8831007    pTimer->fAllCpus = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL;
    884     pTimer->idCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
     1008    pTimer->idCpu = pTimer->fSpecificCpu ? RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK) : NIL_RTCPUID;
    8851009#else
    8861010    pTimer->fSpecificCpu = !!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC);
     
    8911015    pTimer->pvUser = pvUser;
    8921016    pTimer->u64NanoInterval = u64NanoInterval;
    893 #ifndef RT_USE_LINUX_HRTIMER
     1017#ifndef RTTIMER_LINUX_ONLY_HRTIMER
    8941018    pTimer->cJiffies = u64NanoInterval / RTTimerGetSystemGranularity();
    8951019    if (pTimer->cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval)
     
    8991023    for (iCpu = 0; iCpu < cCpus; iCpu++)
    9001024    {
    901 #ifdef RT_USE_LINUX_HRTIMER
    902         hrtimer_init(&pTimer->aSubTimers[iCpu].LnxTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
    903         pTimer->aSubTimers[iCpu].LnxTimer.function = rtTimerLinuxCallback;
    904 #else
    905         init_timer(&pTimer->aSubTimers[iCpu].LnxTimer);
    906         pTimer->aSubTimers[iCpu].LnxTimer.data     = (unsigned long)&pTimer->aSubTimers[iCpu];
    907         pTimer->aSubTimers[iCpu].LnxTimer.function = rtTimerLinuxCallback;
    908         pTimer->aSubTimers[iCpu].LnxTimer.expires  = jiffies;
    909         pTimer->aSubTimers[iCpu].u64StartTS = 0;
    910         pTimer->aSubTimers[iCpu].u64NextTS = 0;
     1025#ifdef RTTIMER_LINUX_WITH_HRTIMER
     1026# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     1027        if (pTimer->fHighRes)
     1028# endif
     1029        {
     1030            hrtimer_init(&pTimer->aSubTimers[iCpu].u.Hr.LnxTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
     1031            pTimer->aSubTimers[iCpu].u.Hr.LnxTimer.function = rtTimerLinuxHrCallback;
     1032        }
     1033# ifndef RTTIMER_LINUX_ONLY_HRTIMER
     1034        else
     1035# endif
     1036#endif
     1037#ifndef RTTIMER_LINUX_ONLY_HRTIMER
     1038        {
     1039            init_timer(&pTimer->aSubTimers[iCpu].u.Std.LnxTimer);
     1040            pTimer->aSubTimers[iCpu].u.Std.LnxTimer.data     = (unsigned long)&pTimer->aSubTimers[iCpu];
     1041            pTimer->aSubTimers[iCpu].u.Std.LnxTimer.function = rtTimerLinuxStdCallback;
     1042            pTimer->aSubTimers[iCpu].u.Std.LnxTimer.expires  = jiffies;
     1043            pTimer->aSubTimers[iCpu].u.Std.u64StartTS = 0;
     1044            pTimer->aSubTimers[iCpu].u.Std.u64NextTS = 0;
     1045        }
    9111046#endif
    9121047        pTimer->aSubTimers[iCpu].iTick = 0;
     
    9451080RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
    9461081{
    947 #ifdef RT_USE_LINUX_HRTIMER
     1082#ifdef RTTIMER_LINUX_ONLY_HRTIMER
     1083    /** @todo Not sure if this is what we want or not... Add new API for
     1084     *        querying the resolution of the high res timers? */
    9481085    struct timespec Ts;
    9491086    int rc = hrtimer_get_res(CLOCK_MONOTONIC, &Ts);
     
    9751112RTDECL(bool) RTTimerCanDoHighResolution(void)
    9761113{
    977 #ifdef RT_USE_LINUX_HRTIMER
     1114#ifdef RTTIMER_LINUX_WITH_HRTIMER
    9781115    return true;
    9791116#else
  • trunk/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp

    r32504 r32572  
    218218    if (!ASMAtomicUoReadBool(&pTimer->fSuspended))
    219219        return VERR_TIMER_ACTIVE;
     220    if (   pTimer->fSpecificCpu
     221        && !RTMpIsCpuOnline(pTimer->idCpu))
     222        return VERR_CPU_OFFLINE;
    220223
    221224    /*
     
    291294
    292295
     296RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     297{
     298    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
     299    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE);
     300
     301    return VERR_NOT_SUPPORTED;
     302}
     303
     304
    293305RTDECL(int) RTTimerDestroy(PRTTIMER pTimer)
    294306{
     
    300312
    301313    /*
    302      * Invalidate the timer, stop it if it's running and finally                   .
     314     * Invalidate the timer, stop it if it's running and finally
    303315     * free up the memory.
    304316     */
     
    312324
    313325
    314 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     326RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    315327{
    316328    *ppTimer = NULL;
     
    323335    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
    324336        &&  (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL
    325         &&  !RTMpIsCpuOnline(fFlags & RTTIMER_FLAGS_CPU_MASK))
    326         return (fFlags & RTTIMER_FLAGS_CPU_MASK) > RTMpGetMaxCpuId()
    327              ? VERR_CPU_NOT_FOUND
    328              : VERR_CPU_OFFLINE;
     337        &&  !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK)))
     338        return VERR_CPU_NOT_FOUND;
    329339
    330340    /*
     
    349359    pTimer->fSpecificCpu = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL;
    350360    pTimer->fOmniTimer = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL;
    351     pTimer->idCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
     361    pTimer->idCpu = pTimer->fSpecificCpu ? RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK) : NIL_RTCPUID;
    352362    pTimer->cSubTimers = cSubTimers;
    353363    pTimer->pfnTimer = pfnTimer;
     
    362372         * ASSUMES that no cpus will ever go offline.
    363373         */
    364         pTimer->idCpu = NIL_RTCPUID; /* */
     374        pTimer->idCpu = NIL_RTCPUID;
    365375        for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++)
    366376        {
  • trunk/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp

    r32504 r32572  
    109109
    110110
    111 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     111RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    112112{
    113113    *ppTimer = NULL;
     
    289289
    290290
     291RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     292{
     293    if (!rtTimerIsValid(pTimer))
     294        return VERR_INVALID_HANDLE;
     295
     296    return VERR_NOT_SUPPORTED;
     297}
     298
     299
    291300DECLASM(void) rtTimerOs2Tick(void)
    292301{
  • trunk/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c

    r32504 r32572  
    103103
    104104
    105 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     105RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    106106{
    107107    RT_ASSERT_PREEMPTIBLE();
     
    118118    if (    (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
    119119        &&  (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL
    120         &&  !RTMpIsCpuPossible((fFlags & RTTIMER_FLAGS_CPU_MASK)))
     120        &&  !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK)))
    121121        return VERR_CPU_NOT_FOUND;
    122122
     
    143143        pTimer->fAllCpu = false;
    144144        pTimer->fSpecificCpu = true;
    145         pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
     145        pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK; /* ASSUMES: index == cpuid */
    146146    }
    147147    else
     
    237237
    238238
     239RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     240{
     241    RTTIMER_ASSERT_VALID_RET(pTimer);
     242
     243    /** @todo implement me! */
     244
     245    return VERR_NOT_SUPPORTED;
     246}
     247
     248
    239249RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
    240250{
     
    257267RTDECL(bool) RTTimerCanDoHighResolution(void)
    258268{
    259     return true;
    260 }
    261 
     269    /** @todo return true; - when missing bits have been implemented and tested*/
     270    return false;
     271}
     272
  • trunk/src/VBox/Runtime/r3/posix/timer-posix.cpp

    r28800 r32572  
    397397
    398398
    399 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
     399RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    400400{
    401401    /*
     
    811811}
    812812
     813
     814RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval)
     815{
     816    AssertPtrReturn(pTimer, VERR_INVALID_POINTER);
     817    AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_MAGIC);
     818    return VERR_NOT_SUPPORTED;
     819}
     820
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