VirtualBox

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


Ignore:
Timestamp:
Jul 29, 2008 6:08:58 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
33809
Message:

iprt: RTTimerLR - low resolution timer API (< 10 Hz).

Location:
trunk/src/VBox/Runtime
Files:
3 edited
3 copied

Legend:

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

    r10940 r10944  
    240240        generic/RTLogWriteStdOut-generic.cpp \
    241241        generic/RTLogWriteUser-generic.cpp \
     242        generic/RTTimerLRCreate-generic.cpp \
    242243        generic/semfastmutex-generic.cpp \
    243244        generic/spinlock-generic.cpp \
     245        generic/timerlr-generic.cpp \
    244246        r3/alloc-ef.cpp \
    245247        r3/alloc.cpp \
  • trunk/src/VBox/Runtime/generic/RTTimerLRCreate-generic.cpp

    r10934 r10944  
    11/** $Id$ */
    22/** @file
    3  * IPRT - Timers, Generic RTTimerCreate() Implementation.
     3 * IPRT - Low Resolution Timers, Generic RTTimerLRCreate() Implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3838
    3939
    40 RTDECL(int) RTTimerCreate(PRTTIMER *ppTimer, unsigned uMilliesInterval, PFNRTTIMER pfnTimer, void *pvUser)
     40RTDECL(int) RTTimerLRCreate(PRTTIMERLR phTimerLR, uint32_t uMilliesInterval, PFNRTTIMERLR pfnTimer, void *pvUser)
    4141{
    42     int rc = RTTimerCreateEx(ppTimer, uMilliesInterval * UINT64_C(1000000), 0, pfnTimer, pvUser);
     42    int rc = RTTimerLRCreateEx(phTimerLR, uMilliesInterval * UINT64_C(1000000), 0, pfnTimer, pvUser);
    4343    if (RT_SUCCESS(rc))
    4444    {
    45         rc = RTTimerStart(*ppTimer, 0);
     45        rc = RTTimerLRStart(*phTimerLR, 0);
    4646        if (RT_SUCCESS(rc))
    4747            return rc;
    48         int rc2 = RTTimerDestroy(*ppTimer); AssertRC(rc2);
    49         *ppTimer = NULL;
     48        int rc2 = RTTimerLRDestroy(*phTimerLR); AssertRC(rc2);
     49        *phTimerLR = NIL_RTTIMERLR;
    5050    }
    5151    return rc;
  • trunk/src/VBox/Runtime/generic/timerlr-generic.cpp

    r10934 r10944  
    11/** $Id$ */
    22/** @file
    3  * IPRT - Timers, Generic.
     3 * IPRT - Low Resolution Timers, Generic.
     4 *
     5 * This code is more or less identicial to timer-generic.cpp, so
     6 * bugfixes goes into both files.
    47 */
    58
    69/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     10 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    811 *
    912 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4548
    4649
    47 
    4850/*******************************************************************************
    4951*   Structures and Typedefs                                                    *
     
    5254 * The internal representation of a timer handle.
    5355 */
    54 typedef struct RTTIMER
     56typedef struct RTTIMERLRINT
    5557{
    5658    /** Magic.
    57      * This is RTTIMER_MAGIC, but changes to something else before the timer
     59     * This is RTTIMERRT_MAGIC, but changes to something else before the timer
    5860     * is destroyed to indicate clearly that thread should exit. */
    5961    uint32_t volatile       u32Magic;
    6062    /** Flag indicating the the timer is suspended. */
    61     uint8_t volatile        fSuspended;
     63    bool volatile           fSuspended;
    6264    /** Flag indicating that the timer has been destroyed. */
    63     uint8_t volatile        fDestroyed;
     65    bool volatile           fDestroyed;
    6466    /** Callback. */
    65     PFNRTTIMER              pfnTimer;
     67    PFNRTTIMERLR            pfnTimer;
    6668    /** User argument. */
    6769    void                   *pvUser;
    6870    /** The timer thread. */
    69     RTTHREAD                Thread;
     71    RTTHREAD                hThread;
    7072    /** Event semaphore on which the thread is blocked. */
    71     RTSEMEVENT              Event;
     73    RTSEMEVENT              hEvent;
    7274    /** The timer interval. 0 if one-shot. */
    7375    uint64_t                u64NanoInterval;
     
    8082    /** The current tick number (since u64StartTS). */
    8183    uint64_t volatile       iTick;
    82 } RTTIMER;
     84} RTTIMERLRINT;
     85typedef RTTIMERLRINT *PRTTIMERLRINT;
    8386
    8487
     
    8689*   Internal Functions                                                         *
    8790*******************************************************************************/
    88 static DECLCALLBACK(int) rtTimerThread(RTTHREAD Thread, void *pvUser);
    89 
    90 
    91 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, unsigned fFlags, PFNRTTIMER pfnTimer, void *pvUser)
    92 {
    93     *ppTimer = NULL;
    94 
    95     /*
    96      * We don't support the fancy MP features.
     91static DECLCALLBACK(int) rtTimerLRThread(RTTHREAD hThread, void *pvUser);
     92
     93
     94RTDECL(int) RTTimerLRCreateEx(RTTIMERLR *phTimerLR, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMERLR pfnTimer, void *pvUser)
     95{
     96    AssertPtr(phTimerLR);
     97    *phTimerLR = NIL_RTTIMERLR;
     98
     99    /*
     100     * We don't support the fancy MP features, nor intervals lower than 100 ms.
    97101     */
    98102    if (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC)
    99103        return VERR_NOT_SUPPORTED;
     104    if (u64NanoInterval < 100*1000*1000)
     105        return VERR_INVALID_PARAMETER;
    100106
    101107    /*
    102108     * Allocate and initialize the timer handle.
    103109     */
    104     PRTTIMER pTimer = (PRTTIMER)RTMemAlloc(sizeof(*pTimer));
    105     if (!pTimer)
     110    PRTTIMERLRINT pThis = (PRTTIMERLRINT)RTMemAlloc(sizeof(*pThis));
     111    if (!pThis)
    106112        return VERR_NO_MEMORY;
    107113
    108     pTimer->u32Magic = RTTIMER_MAGIC;
    109     pTimer->fSuspended = true;
    110     pTimer->fDestroyed = false;
    111     pTimer->pfnTimer = pfnTimer;
    112     pTimer->pvUser = pvUser;
    113     pTimer->Thread = NIL_RTTHREAD;
    114     pTimer->Event = NIL_RTSEMEVENT;
    115     pTimer->u64NanoInterval = u64NanoInterval;
    116     pTimer->u64StartTS = 0;
    117 
    118     int rc = RTSemEventCreate(&pTimer->Event);
     114    pThis->u32Magic = RTTIMERLR_MAGIC;
     115    pThis->fSuspended = true;
     116    pThis->fDestroyed = false;
     117    pThis->pfnTimer = pfnTimer;
     118    pThis->pvUser = pvUser;
     119    pThis->hThread = NIL_RTTHREAD;
     120    pThis->hEvent = NIL_RTSEMEVENT;
     121    pThis->u64NanoInterval = u64NanoInterval;
     122    pThis->u64StartTS = 0;
     123
     124    int rc = RTSemEventCreate(&pThis->hEvent);
    119125    if (RT_SUCCESS(rc))
    120126    {
    121         rc = RTThreadCreate(&pTimer->Thread, rtTimerThread, pTimer, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "TIMER");
     127        rc = RTThreadCreate(&pThis->hThread, rtTimerLRThread, pThis, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "TIMER");
    122128        if (RT_SUCCESS(rc))
    123129        {
    124             *ppTimer = pTimer;
     130            *phTimerLR = pThis;
    125131            return VINF_SUCCESS;
    126132        }
    127133
    128         pTimer->u32Magic = 0;
    129         RTSemEventDestroy(pTimer->Event);
    130         pTimer->Event = NIL_RTSEMEVENT;
     134        pThis->u32Magic = 0;
     135        RTSemEventDestroy(pThis->hEvent);
     136        pThis->hEvent = NIL_RTSEMEVENT;
    131137    }
    132     RTMemFree(pTimer);
     138    RTMemFree(pThis);
    133139
    134140    return rc;
     
    136142
    137143
    138 /**
    139  * Validates the timer handle.
    140  *
    141  * @returns true if valid, false if invalid.
    142  * @param   pTimer  The handle.
    143  */
    144 DECLINLINE(bool) rtTimerIsValid(PRTTIMER pTimer)
    145 {
    146     AssertReturn(VALID_PTR(pTimer), false);
    147     AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, false);
    148     AssertReturn(!pTimer->fDestroyed, false);
    149     return true;
    150 }
    151 
    152 
    153 RTDECL(int) RTTimerDestroy(PRTTIMER pTimer)
    154 {
    155     /* It's ok to pass NULL pointer. */
    156     if (pTimer == /*NIL_RTTIMER*/ NULL)
     144RTDECL(int) RTTimerLRDestroy(RTTIMERLR hTimerLR)
     145{
     146    /*
     147     * Validate input, NIL is fine though.
     148     */
     149    if (hTimerLR == NIL_RTTIMERLR)
    157150        return VINF_SUCCESS;
    158     if (!rtTimerIsValid(pTimer))
    159         return VERR_INVALID_HANDLE;
     151    PRTTIMERLRINT pThis = hTimerLR;
     152    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     153    AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE);
     154    AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE);
    160155
    161156    /*
     
    163158     * If it's suspended we can safely set the destroy flag and signal it.
    164159     */
    165     RTTHREAD Thread = pTimer->Thread;
    166     if (!pTimer->fSuspended)
     160    RTTHREAD hThread = pThis->hThread;
     161    if (!pThis->fSuspended)
    167162    {
    168         ASMAtomicXchgU8(&pTimer->fSuspended, true);
    169         ASMAtomicXchgU8(&pTimer->fDestroyed, true);
     163        ASMAtomicWriteBool(&pThis->fSuspended, true);
     164        ASMAtomicWriteBool(&pThis->fDestroyed, true);
    170165    }
    171166    else
    172167    {
    173         ASMAtomicXchgU8(&pTimer->fDestroyed, true);
    174         int rc = RTSemEventSignal(pTimer->Event);
     168        ASMAtomicWriteBool(&pThis->fDestroyed, true);
     169        int rc = RTSemEventSignal(pThis->hEvent);
    175170        if (rc == VERR_ALREADY_POSTED)
    176171            rc = VINF_SUCCESS;
     
    178173    }
    179174
    180     RTThreadWait(Thread, 250, NULL);
     175    RTThreadWait(hThread, 250, NULL);
    181176    return VINF_SUCCESS;
    182177}
    183178
    184179
    185 RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
    186 {
    187     if (!rtTimerIsValid(pTimer))
    188         return VERR_INVALID_HANDLE;
    189     if (!pTimer->fSuspended)
     180RTDECL(int) RTTimerLRStart(RTTIMERLR hTimerLR, uint64_t u64First)
     181{
     182    /*
     183     * Validate input.
     184     */
     185    PRTTIMERLRINT pThis = hTimerLR;
     186    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     187    AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE);
     188    AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE);
     189
     190    if (u64First && u64First < 100*1000*1000)
     191        return VERR_INVALID_PARAMETER;
     192
     193    if (!pThis->fSuspended)
    190194        return VERR_TIMER_ACTIVE;
    191195
     
    194198     */
    195199    u64First += RTTimeNanoTS();
    196     ASMAtomicXchgU64(&pTimer->iTick, 0);
    197     ASMAtomicXchgU64(&pTimer->u64StartTS, u64First);
    198     ASMAtomicXchgU64(&pTimer->u64NextTS, u64First);
    199     ASMAtomicXchgU8(&pTimer->fSuspended, false);
    200     int rc = RTSemEventSignal(pTimer->Event);
     200    ASMAtomicWriteU64(&pThis->iTick, 0);
     201    ASMAtomicWriteU64(&pThis->u64StartTS, u64First);
     202    ASMAtomicWriteU64(&pThis->u64NextTS, u64First);
     203    ASMAtomicWriteBool(&pThis->fSuspended, false);
     204    int rc = RTSemEventSignal(pThis->hEvent);
    201205    if (rc == VERR_ALREADY_POSTED)
    202206        rc = VINF_SUCCESS;
     
    206210
    207211
    208 RTDECL(int) RTTimerStop(PRTTIMER pTimer)
    209 {
    210     if (!rtTimerIsValid(pTimer))
    211         return VERR_INVALID_HANDLE;
    212     if (pTimer->fSuspended)
     212RTDECL(int) RTTimerLRStop(RTTIMERLR hTimerLR)
     213{
     214    /*
     215     * Validate input.
     216     */
     217    PRTTIMERLRINT pThis = hTimerLR;
     218    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     219    AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE);
     220    AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE);
     221
     222    if (pThis->fSuspended)
    213223        return VERR_TIMER_SUSPENDED;
    214224
     
    216226     * Mark it as suspended and kick the thread.
    217227     */
    218     ASMAtomicXchgU8(&pTimer->fSuspended, true);
    219     int rc = RTSemEventSignal(pTimer->Event);
     228    ASMAtomicWriteBool(&pThis->fSuspended, true);
     229    int rc = RTSemEventSignal(pThis->hEvent);
    220230    if (rc == VERR_ALREADY_POSTED)
    221231        rc = VINF_SUCCESS;
     
    225235
    226236
    227 static DECLCALLBACK(int) rtTimerThread(RTTHREAD Thread, void *pvUser)
    228 {
    229     PRTTIMER pTimer = (PRTTIMER)pvUser;
     237static DECLCALLBACK(int) rtTimerLRThread(RTTHREAD hThread, void *pvUser)
     238{
     239    PRTTIMERLRINT pThis = (PRTTIMERLRINT)pvUser;
    230240
    231241    /*
    232242     * The loop.
    233243     */
    234     while (!pTimer->fDestroyed)
     244    while (!ASMAtomicUoReadBool(&pThis->fDestroyed))
    235245    {
    236         if (pTimer->fSuspended)
     246        if (ASMAtomicUoReadBool(&pThis->fSuspended))
    237247        {
    238             int rc = RTSemEventWait(pTimer->Event, RT_INDEFINITE_WAIT);
     248            int rc = RTSemEventWait(pThis->hEvent, RT_INDEFINITE_WAIT);
    239249            if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED)
    240250            {
     
    246256        {
    247257            const uint64_t u64NanoTS = RTTimeNanoTS();
    248             if (u64NanoTS >= pTimer->u64NextTS)
     258            if (u64NanoTS >= pThis->u64NextTS)
    249259            {
    250                 pTimer->iTick++;
    251                 pTimer->pfnTimer(pTimer, pTimer->pvUser, pTimer->iTick);
     260                pThis->iTick++;
     261                pThis->pfnTimer(pThis, pThis->pvUser, pThis->iTick);
    252262
    253263                /* status changed? */
    254                 if (pTimer->fSuspended || pTimer->fDestroyed)
     264                if (    ASMAtomicUoReadBool(&pThis->fSuspended)
     265                    ||  ASMAtomicUoReadBool(&pThis->fDestroyed))
    255266                    continue;
    256267
    257268                /* one shot? */
    258                 if (!pTimer->u64NanoInterval)
     269                if (!pThis->u64NanoInterval)
    259270                {
    260                     ASMAtomicXchgU8(&pTimer->fSuspended, true);
     271                    ASMAtomicWriteBool(&pThis->fSuspended, true);
    261272                    continue;
    262273                }
    263274
    264275                /* calc the next time we should fire. */
    265                 pTimer->u64NextTS = pTimer->u64StartTS + pTimer->iTick * pTimer->u64NanoInterval;
    266                 if (pTimer->u64NextTS < u64NanoTS)
     276                pThis->u64NextTS = pThis->u64StartTS + pThis->iTick * pThis->u64NanoInterval;
     277                if (pThis->u64NextTS < u64NanoTS)
    267278#ifdef IN_RING3 /* In ring-3 we'll catch up lost ticks immediately. */
    268                     pTimer->u64NextTS = u64NanoTS + 1;
     279                    pThis->u64NextTS = u64NanoTS + 1;
    269280#else
    270                     pTimer->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2;
     281                    pThis->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2;
    271282#endif
    272283            }
    273284
    274285            /* block. */
    275             uint64_t cNanoSeconds = pTimer->u64NextTS - u64NanoTS;
     286            uint64_t cNanoSeconds = pThis->u64NextTS - u64NanoTS;
    276287#ifdef IN_RING3 /* In ring-3 we'll catch up lost ticks immediately. */
    277288            if (cNanoSeconds > 10)
    278289#endif
    279290            {
    280                 int rc = RTSemEventWait(pTimer->Event, cNanoSeconds < 1000000 ? 1 : cNanoSeconds / 1000000);
     291                int rc = RTSemEventWait(pThis->hEvent, cNanoSeconds < 1000000 ? 1 : cNanoSeconds / 1000000);
    281292                if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED && rc != VERR_TIMEOUT)
    282293                {
     
    291302     * Release the timer resources.
    292303     */
    293     ASMAtomicIncU32(&pTimer->u32Magic); /* make the handle invalid. */
    294     int rc = RTSemEventDestroy(pTimer->Event); AssertRC(rc);
    295     pTimer->Event = NIL_RTSEMEVENT;
    296     pTimer->Thread = NIL_RTTHREAD;
    297     RTMemFree(pTimer);
     304    ASMAtomicWriteU32(&pThis->u32Magic, ~RTTIMERLR_MAGIC); /* make the handle invalid. */
     305    int rc = RTSemEventDestroy(pThis->hEvent); AssertRC(rc);
     306    pThis->hEvent = NIL_RTSEMEVENT;
     307    pThis->hThread = NIL_RTTHREAD;
     308    RTMemFree(pThis);
    298309
    299310    return VINF_SUCCESS;
    300311}
    301312
    302 
    303 
    304 
    305 RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
    306 {
    307     return 10000000; /* 10ms */
    308 }
    309 
    310 
    311 RTDECL(int) RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted)
    312 {
    313     return VERR_NOT_SUPPORTED;
    314 }
    315 
    316 
    317 RTDECL(int) RTTimerReleaseSystemGranularity(uint32_t u32Granted)
    318 {
    319     return VERR_NOT_SUPPORTED;
    320 }
    321 
  • trunk/src/VBox/Runtime/include/internal/magics.h

    r10767 r10944  
    7979/** Magic number for timer handles. (Jared Mason Diamond) */
    8080#define RTTIMER_MAGIC               0x19370910
     81/** Magic number for timer low resolution handles. (Saki Hiwatari) */
     82#define RTTIMERLR_MAGIC             0x19610715
    8183
    8284/** @} */
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r10940 r10944  
    8787        tstTime-4 \
    8888        tstTimer \
     89        tstTimerLR \
    8990        tstTimeSpec \
    9091        tstTSC \
     
    297298tstTimer_SOURCES = tstTimer.cpp
    298299
     300tstTimerLR_SOURCES = tstTimerLR.cpp
     301
    299302tstTimeSpec_SOURCES = tstTimeSpec.cpp
    300303
  • trunk/src/VBox/Runtime/testcase/tstTimerLR.cpp

    r10941 r10944  
    11/* $Id$ */
    22/** @file
    3  * IPRT Testcase - Timers.
     3 * IPRT Testcase - Low Resolution Timers.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4949static volatile uint64_t gu64Prev;
    5050
    51 static DECLCALLBACK(void) TimerCallback(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
     51static DECLCALLBACK(void) TimerLRCallback(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
    5252{
    5353    gcTicks++;
     
    126126    } aTests[] =
    127127    {
    128         { 32, 2000, 0, 0 },
    129         { 20, 2000, 0, 0 },
    130         { 10, 2000, 0, 0 },
    131         { 8,  2000, 0, 0 },
    132         { 2,  2000, 0, 0 },
    133         { 1,  2000, 0, 0 }
     128        { 1000, 2500, 3,   3 }, /* (keep in mind the immediate first tick) */
     129        {  250, 2000, 6,  10 },
     130        {  100, 2000, 17, 23 },
    134131    };
    135132
     
    137134    for (i = 0; i < ELEMENTS(aTests); i++)
    138135    {
    139         aTests[i].cLower = (aTests[i].uMilliesWait - aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
    140         aTests[i].cUpper = (aTests[i].uMilliesWait + aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
     136        //aTests[i].cLower = (aTests[i].uMilliesWait - aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
     137        //aTests[i].cUpper = (aTests[i].uMilliesWait + aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
    141138
    142139        RTPrintf("\n"
     
    148145         */
    149146        gcTicks = 0;
    150         PRTTIMER pTimer;
     147        RTTIMERLR hTimerLR;
    151148        gu64Max = 0;
    152149        gu64Min = UINT64_MAX;
    153150        gu64Prev = 0;
    154         rc = RTTimerCreate(&pTimer, aTests[i].uMilliesInterval, TimerCallback, NULL);
     151        rc = RTTimerLRCreateEx(&hTimerLR, aTests[i].uMilliesInterval * (uint64_t)1000000, 0, TimerLRCallback, NULL);
    155152        if (RT_FAILURE(rc))
    156153        {
    157             RTPrintf("RTTimerCreate(,%d,) -> %d\n", aTests[i].uMilliesInterval, rc);
     154            RTPrintf("RTTimerLRCreateEX(,%u*1M,,,) -> %d\n", aTests[i].uMilliesInterval, rc);
    158155            cErrors++;
    159156            continue;
     
    161158
    162159        /*
    163          * Active waiting for 2 seconds and then destroy it.
     160         * Start the timer an actively wait for it for the period requested.
    164161         */
    165162        uint64_t uTSBegin = RTTimeNanoTS();
     163        rc = RTTimerLRStart(hTimerLR, 0);
     164        if (RT_FAILURE(rc))
     165        {
     166            RTPrintf("tstTimer: FAILURE - RTTimerLRStart() -> %Rrc\n", rc);
     167            cErrors++;
     168        }
     169
    166170        while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)
    167171            /* nothing */;
     172
     173        /* don't stop it, destroy it because there are potential races in destroying an active timer. */
     174        rc = RTTimerLRDestroy(hTimerLR);
     175        if (RT_FAILURE(rc))
     176        {
     177            RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
     178            cErrors++;
     179        }
     180
    168181        uint64_t uTSEnd = RTTimeNanoTS();
    169182        uint64_t uTSDiff = uTSEnd - uTSBegin;
    170183        RTPrintf("uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd);
    171         if (RT_FAILURE(rc))
    172             RTPrintf("warning: RTThreadSleep ended prematurely with %d\n", rc);
    173         rc = RTTimerDestroy(pTimer);
    174         if (RT_FAILURE(rc))
    175         {
    176             RTPrintf("tstTimer: FAILURE - RTTimerDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
    177             cErrors++;
    178             continue;
    179         }
     184
     185        /* Check that it really stopped. */
    180186        unsigned cTicks = gcTicks;
    181         RTThreadSleep(100);
     187        RTThreadSleep(aTests[i].uMilliesInterval * 2);
    182188        if (gcTicks != cTicks)
    183189        {
    184             RTPrintf("tstTimer: FAILURE - RTTimerDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks);
     190            RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks);
    185191            cErrors++;
    186192            continue;
     
    204210        RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max);
    205211    }
     212
     213    /*
     214     * Test multiple timers running at once.
     215     */
     216    /** @todo multiple LR timer testcase. */
    206217
    207218    /*
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