VirtualBox

Ignore:
Timestamp:
Sep 23, 2010 11:22:32 PM (14 years ago)
Author:
vboxsync
Message:

tstRTR0Timer: some train code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstRTR0Timer.cpp

    r32736 r32742  
    2525 */
    2626
     27
    2728/*******************************************************************************
    2829*   Header Files                                                               *
     
    3334#include <iprt/cpuset.h>
    3435#include <iprt/err.h>
     36#include <iprt/mem.h>
    3537#include <iprt/mp.h>
    3638#include <iprt/param.h>
     
    5658    /** The RC of whatever operation performed in the handler. */
    5759    int volatile        rc;
     60    /** Set if it's a periodic test. */
     61    bool                fPeriodic;
    5862    /** Test specific stuff. */
    5963    union
     
    8387            bool                fFailed;
    8488        } Specific;
    85         struct
    86         {
    87             /** Per CPU ticks, indexed by the CPU set index. */
    88             uint32_t volatile * pacTickPerCpu;
    89         } Omni;
    9089    } u;
    9190} TSTRTR0TIMERS1;
    9291typedef TSTRTR0TIMERS1 *PTSTRTR0TIMERS1;
    9392
     93
     94/**
     95 * Per cpu state for an omni timer test.
     96 */
     97typedef struct TSTRTR0TIMEROMNI1
     98{
     99    /** When we started receiving timer callbacks on this CPU. */
     100    uint64_t            u64Start;
     101    /** When we received the last tick on this timer. */
     102    uint64_t            u64Last;
     103    /** The number of ticks received on this CPU. */
     104    uint32_t volatile   cTicks;
     105    uint32_t            u32Padding;
     106} TSTRTR0TIMEROMNI1;
     107typedef TSTRTR0TIMEROMNI1 *PTSTRTR0TIMEROMNI1;
     108
     109
     110/**
     111 * Callback which increments a 32-bit counter.
     112 *
     113 * @param   pTimer      The timer.
     114 * @param   iTick       The current tick.
     115 * @param   pvUser      The user argument.
     116 */
     117static DECLCALLBACK(void) tstRTR0TimerCallbackOmni(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
     118{
     119    PTSTRTR0TIMEROMNI1  paStates = (PTSTRTR0TIMEROMNI1)pvUser;
     120    RTCPUID             idCpu    = RTMpCpuId();
     121    uint32_t            iCpu     = RTMpCpuIdToSetIndex(idCpu);
     122
     123    RTR0TESTR0_CHECK_MSG(iCpu < RTCPUSET_MAX_CPUS, ("iCpu=%d idCpu=%u\n", iCpu, idCpu));
     124    if (iCpu < RTCPUSET_MAX_CPUS)
     125    {
     126        uint32_t iCountedTick = ASMAtomicIncU32(&paStates[iCpu].cTicks) - 1;
     127        RTR0TESTR0_CHECK_MSG(iCountedTick == iTick,
     128                             ("iCountedTick=%u iTick=%u iCpu=%d idCpu=%u\n", iCountedTick, iTick, iCpu, idCpu));
     129        paStates[iCpu].u64Last = RTTimeSystemNanoTS();
     130        if (paStates[iCpu].u64Start)
     131        {
     132            paStates[iCpu].u64Start = paStates[iCpu].u64Last;
     133            RTR0TESTR0_CHECK_MSG(iCountedTick == 0, ("iCountedTick=%u iCpu=%d idCpu=%u\n", iCountedTick, iCpu, idCpu));
     134        }
     135    }
     136}
    94137
    95138
     
    113156        pState->u.Specific.fFailed = true;
    114157    RTR0TESTR0_CHECK_MSG(pState->u.Specific.idCpu == idCpu, ("idCpu=%u, expected %u\n", idCpu, pState->u.Specific.idCpu));
     158
     159    if (pState->fPeriodic)
     160        RTR0TESTR0_CHECK_MSG(iShot == iTick, ("iShot=%u iTick=%u\n", iShot, iTick));
     161    else
     162        RTR0TESTR0_CHECK_MSG(iTick == 1, ("iShot=%u iTick=%u\n", iShot, iTick));
    115163}
    116164
     
    133181    if (iShot < RT_ELEMENTS(pState->aShotNsTSes))
    134182        pState->aShotNsTSes[iShot] = RTTimeSystemNanoTS();
     183    if (pState->fPeriodic)
     184        RTR0TESTR0_CHECK_MSG(iShot == iTick, ("iShot=%u iTick=%u\n", iShot, iTick));
     185    else
     186        RTR0TESTR0_CHECK_MSG(iTick == 1, ("iShot=%u iTick=%u\n", iShot, iTick));
    135187
    136188    if (!(iShot % pState->u.ChgInt.cStepsBetween))
     
    181233    if (iShot <= RT_ELEMENTS(pState->aShotNsTSes))
    182234        pState->aShotNsTSes[iShot - 1] = RTTimeSystemNanoTS();
     235    if (pState->fPeriodic)
     236        RTR0TESTR0_CHECK_MSG(iShot == iTick, ("iShot=%u iTick=%u\n", iShot, iTick));
     237    else
     238        RTR0TESTR0_CHECK_MSG(iTick == 1, ("iShot=%u iTick=%u\n", iShot, iTick));
    183239
    184240    if (iShot == pState->iActionShot + 1)
     
    201257    if (iShot <= RT_ELEMENTS(pState->aShotNsTSes))
    202258        pState->aShotNsTSes[iShot - 1] = RTTimeSystemNanoTS();
     259    if (pState->fPeriodic)
     260        RTR0TESTR0_CHECK_MSG(iShot == iTick, ("iShot=%u iTick=%u\n", iShot, iTick));
     261    else
     262        RTR0TESTR0_CHECK_MSG(iTick == 1, ("iShot=%u iTick=%u\n", iShot, iTick));
    203263
    204264    if (iShot == pState->iActionShot + 1)
     
    221281    if (iShot <= RT_ELEMENTS(pState->aShotNsTSes))
    222282        pState->aShotNsTSes[iShot - 1] = RTTimeSystemNanoTS();
     283    if (pState->fPeriodic)
     284        RTR0TESTR0_CHECK_MSG(iShot == iTick, ("iShot=%u iTick=%u\n", iShot, iTick));
     285    else
     286        RTR0TESTR0_CHECK_MSG(iTick == 1, ("iShot=%u iTick=%u\n", iShot, iTick));
    223287}
    224288
     
    486550            {
    487551                RT_ZERO(State);
     552                State.fPeriodic = true;
    488553                uint64_t uStartNsTS = RTTimeSystemNanoTS();
    489554                RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, u10HzAsNs), VINF_SUCCESS);
     
    513578                {
    514579                    RT_ZERO(State);
     580                    State.fPeriodic = true;
    515581                    RTR0TESTR0_CHECK_RC_BREAK(RTTimerStart(pTimer, i < 20 ? 0 : cNsSysHz), VINF_SUCCESS);
    516582                    for (uint32_t k = 0; k < 1000 && ASMAtomicUoReadU32(&State.cShots) < 2; k++)
     
    531597            State.rc            = VERR_IPE_UNINITIALIZED_STATUS;
    532598            State.iActionShot   = 42;
     599            State.fPeriodic     = true;
    533600            State.u.ChgInt.fDirection     = !!(u64Arg & 1);
    534601            if (uOperation == TSTRTR0TIMER_PERIODIC_CHANGE_INTERVAL_HIRES)
     
    589656                    State.iActionShot       = 0;
    590657                    State.rc                = VINF_SUCCESS;
     658                    State.fPeriodic         = true;
    591659                    State.u.Specific.idCpu  = RTMpCpuIdFromSetIndex(iCpu);
    592660
     
    628696        }
    629697
    630 
    631698        case TSTRTR0TIMER_PERIODIC_OMNI:
    632699        case TSTRTR0TIMER_PERIODIC_OMNI_HIRES:
    633700        {
    634 #if 0 /* To be continued... */
    635701            /* Create a periodic timer running at max host frequency, but no more than 1000 Hz. */
    636702            uint32_t        cNsInterval = cNsSysHz;
    637703            while (cNsInterval < UINT32_C(1000000))
    638704                cNsInterval *= 2;
    639             State.u.Omni.pacTickPerCpu = RTMemAllocZ(sizeof(State.u.Omni.pacTickPerCpu[0]) * RTCPUSET_MAX_CPUS);
    640             RTR0TESTR0_CHECK_MSG_BREAK(State.u.Omni.pacTickPerCpu, ("%d\n", RTCPUSET_MAX_CPUS));
     705            PTSTRTR0TIMEROMNI1 paStates = (PTSTRTR0TIMEROMNI1)RTMemAllocZ(sizeof(paStates[0]) * RTCPUSET_MAX_CPUS);
     706            RTR0TESTR0_CHECK_MSG_BREAK(paStates, ("%d\n", RTCPUSET_MAX_CPUS));
    641707
    642708            PRTTIMER        pTimer;
    643709            uint32_t        fFlags = TSTRTR0TIMER_IS_HIRES(uOperation) ? RTTIMER_FLAGS_HIGH_RES : 0;
    644             RTR0TESTR0_CHECK_RC_BREAK(RTTimerCreateEx(&pTimer, cNsInterval, fFlags, tstRTR0TimerCallbackOmni, &State),
     710            RTR0TESTR0_CHECK_RC_BREAK(RTTimerCreateEx(&pTimer, cNsInterval, fFlags, tstRTR0TimerCallbackOmni, paStates),
    645711                                      VINF_SUCCESS);
    646712
    647             do /* break loop */
    648             {
     713            for (uint32_t iTest = 0; iTest < 3 && !RTR0TestR0HaveErrors(); iTest++)
     714            {
     715                /* reset the state */
     716                for (uint32_t iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
     717                    ASMAtomicWriteU32(&paStates[iCpu].cTicks, 0);
     718
    649719                /* run it for 1 second. */
    650720                RTCPUSET OnlineSet;
     
    658728                RTR0TESTR0_CHECK_RC_BREAK(RTTimerStop(pTimer), VINF_SUCCESS);
    659729
     730                /* Do a min/max on the start and stop times and calculate the test period. */
     731                uint64_t  u64MinStart = UINT64_MAX;
     732                uint64_t  u64MaxStop  = 0;
    660733                for (uint32_t iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
    661                     if ()
     734                {
     735                    if (paStates[iCpu].u64Start)
    662736                    {
     737                        if (paStates[iCpu].u64Start < u64MinStart)
     738                            u64MinStart = paStates[iCpu].u64Start;
     739                        if (paStates[iCpu].u64Last  > u64MaxStop)
     740                            u64MaxStop  = paStates[iCpu].u64Last;
    663741                    }
    664 
    665 
    666             } while (0);
    667 
     742                }
     743                RTR0TESTR0_CHECK_MSG(u64MinStart < u64MaxStop, ("%llu, %llu", u64MinStart, u64MaxStop));
     744                uint64_t cNsElapsed = u64MaxStop - u64MinStart;
     745                uint32_t cAvgTicks  = cNsElapsed / cNsInterval;
     746
     747                /* Check tick counts. ASSUMES no cpu on- or offlining.
     748                   This only catches really bad stuff. */
     749                uint32_t cMinTicks = cAvgTicks - cAvgTicks / 10;
     750                uint32_t cMaxTicks = cAvgTicks + cAvgTicks / 10 + 1;
     751                for (uint32_t iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
     752                    if (paStates[iCpu].cTicks)
     753                    {
     754                        RTR0TESTR0_CHECK_MSG(RTCpuSetIsMemberByIndex(&OnlineSet, iCpu), ("%d\n", iCpu));
     755                        RTR0TESTR0_CHECK_MSG(paStates[iCpu].cTicks >= cMinTicks,
     756                                             ("%u, min=%u, iCpu=%u\n", paStates[iCpu].cTicks, cMinTicks, iCpu));
     757                        RTR0TESTR0_CHECK_MSG(paStates[iCpu].cTicks <= cMaxTicks,
     758                                              ("%u, max=%u, iCpu=%u\n", paStates[iCpu].cTicks, cMaxTicks, iCpu));
     759                    }
     760                    else
     761                        RTR0TESTR0_CHECK_MSG(!RTCpuSetIsMemberByIndex(&OnlineSet, iCpu), ("%d\n", iCpu));
     762            }
    668763
    669764            RTR0TESTR0_CHECK_RC(RTTimerDestroy(pTimer), VINF_SUCCESS);
    670             RTMemFree(State.u.Omni.pacTickPerCpu);
    671 #endif
     765            RTMemFree(paStates);
    672766            break;
    673767        }
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