tstTimerLR.cpp revision a7d199151f468f894181e8d50d3e202c2a010702
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive/* $Id$ */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive/** @file
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive * IPRT Testcase - Low Resolution Timers.
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive/*
5a58787efeb02a1c3f06569d019ad81fd2efa06end * Copyright (C) 2006-2008 Oracle Corporation
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc *
5a58787efeb02a1c3f06569d019ad81fd2efa06end * This file is part of VirtualBox Open Source Edition (OSE), as
5a58787efeb02a1c3f06569d019ad81fd2efa06end * available from http://www.virtualbox.org. This file is free software;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * you can redistribute it and/or modify it under the terms of the GNU
2e545ce2450a9953665f701bb05350f0d3f26275nd * General Public License (GPL) as published by the Free Software
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * Foundation, in version 2 as it comes in the "COPYING" file of the
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5a58787efeb02a1c3f06569d019ad81fd2efa06end * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5a58787efeb02a1c3f06569d019ad81fd2efa06end *
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * The contents of this file may alternatively be used under the terms
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * of the Common Development and Distribution License Version 1.0
5a58787efeb02a1c3f06569d019ad81fd2efa06end * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
5a58787efeb02a1c3f06569d019ad81fd2efa06end * VirtualBox OSE distribution, in which case the provisions of the
5a58787efeb02a1c3f06569d019ad81fd2efa06end * CDDL are applicable instead of those of the GPL.
3f08db06526d6901aa08c110b5bc7dde6bc39905nd *
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd * You may elect to license modified versions of this file under the
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * terms and conditions of either the GPL or the CDDL or both.
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi */
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd/*******************************************************************************
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd* Header Files *
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive*******************************************************************************/
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive#include <iprt/timer.h>
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive#include <iprt/time.h>
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive#include <iprt/thread.h>
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive#include <iprt/initterm.h>
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive#include <iprt/message.h>
9bcfc3697a91b5215893a7d0206865b13fc72148nd#include <iprt/stream.h>
5e7fa9795c20ab86177469e40e0fab9069d4f2d0erikabele#include <iprt/err.h>
5e7fa9795c20ab86177469e40e0fab9069d4f2d0erikabele
5a58787efeb02a1c3f06569d019ad81fd2efa06end
5a58787efeb02a1c3f06569d019ad81fd2efa06end
5a58787efeb02a1c3f06569d019ad81fd2efa06end/*******************************************************************************
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh* Global Variables *
5a58787efeb02a1c3f06569d019ad81fd2efa06end*******************************************************************************/
5a58787efeb02a1c3f06569d019ad81fd2efa06endstatic volatile unsigned gcTicks;
5a58787efeb02a1c3f06569d019ad81fd2efa06endstatic volatile uint64_t gu64Min;
18b044262d499eb4255fb75026564a3e33b961eandstatic volatile uint64_t gu64Max;
18b044262d499eb4255fb75026564a3e33b961eandstatic volatile uint64_t gu64Prev;
18b044262d499eb4255fb75026564a3e33b961eand
18b044262d499eb4255fb75026564a3e33b961eandstatic DECLCALLBACK(void) TimerLRCallback(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
18b044262d499eb4255fb75026564a3e33b961eand{
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf gcTicks++;
144c96f1a9d2f0c8bfccafea655dae120f7470d2colm
18b044262d499eb4255fb75026564a3e33b961eand const uint64_t u64Now = RTTimeNanoTS();
18b044262d499eb4255fb75026564a3e33b961eand if (gu64Prev)
40e40f077674affa1a871ec20cdbaf07aa583dcbnd {
25202c3d4d19f5cfe897977f7b901ed9f106d145covener const uint64_t u64Delta = u64Now - gu64Prev;
25202c3d4d19f5cfe897977f7b901ed9f106d145covener if (u64Delta < gu64Min)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive gu64Min = u64Delta;
5e7fa9795c20ab86177469e40e0fab9069d4f2d0erikabele if (u64Delta > gu64Max)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive gu64Max = u64Delta;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
18b044262d499eb4255fb75026564a3e33b961eand gu64Prev = u64Now;
18b044262d499eb4255fb75026564a3e33b961eand}
18b044262d499eb4255fb75026564a3e33b961eand
5a58787efeb02a1c3f06569d019ad81fd2efa06end
5a58787efeb02a1c3f06569d019ad81fd2efa06endint main()
5a58787efeb02a1c3f06569d019ad81fd2efa06end{
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /*
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive * Init runtime
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive unsigned cErrors = 0;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive int rc = RTR3InitExeNoArguments(0);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive if (RT_FAILURE(rc))
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive return RTMsgInitFailure(rc);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /*
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive * Check that the clock is reliable.
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: TESTING - RTTimeNanoTS() for 2sec\n");
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uint64_t uTSMillies = RTTimeMilliTS();
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uint64_t uTSBegin = RTTimeNanoTS();
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uint64_t uTSLast = uTSBegin;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uint64_t uTSDiff;
144c96f1a9d2f0c8bfccafea655dae120f7470d2colm uint64_t cIterations = 0;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
e5d4de6aed1e3ca56b48d45f628cf1f4adadf33drbowen do
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uint64_t uTS = RTTimeNanoTS();
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive if (uTS < uTSLast)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. uTS=%RU64 uTSLast=%RU64\n", uTS, uTSLast);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive cErrors++;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive if (++cIterations > (2*1000*1000*1000))
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. cIterations=%RU64 uTS=%RU64 uTSBegin=%RU64\n", cIterations, uTS, uTSBegin);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive return 1;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uTSLast = uTS;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uTSDiff = uTSLast - uTSBegin;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive } while (uTSDiff < (2*1000*1000*1000));
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uTSMillies = RTTimeMilliTS() - uTSMillies;
2af5ae0ec81f8ed0b61785ef4e1320b37cf58af1slive if (uTSMillies >= 2500 || uTSMillies <= 1500)
2af5ae0ec81f8ed0b61785ef4e1320b37cf58af1slive {
2af5ae0ec81f8ed0b61785ef4e1320b37cf58af1slive RTPrintf("tstTimer: FAILURE - uTSMillies=%RI64 uTSBegin=%RU64 uTSLast=%RU64 uTSDiff=%RU64\n",
2af5ae0ec81f8ed0b61785ef4e1320b37cf58af1slive uTSMillies, uTSBegin, uTSLast, uTSDiff);
2af5ae0ec81f8ed0b61785ef4e1320b37cf58af1slive cErrors++;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive if (!cErrors)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: OK - RTTimeNanoTS()\n");
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /*
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive * Tests.
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive static struct
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive unsigned uMilliesInterval;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive unsigned uMilliesWait;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive unsigned cLower;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive unsigned cUpper;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive } aTests[] =
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive { 1000, 2500, 3, 3 }, /* (keep in mind the immediate first tick) */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive { 250, 2000, 6, 10 },
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive { 100, 2000, 17, 23 },
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive };
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive unsigned i = 0;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive for (i = 0; i < RT_ELEMENTS(aTests); i++)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive //aTests[i].cLower = (aTests[i].uMilliesWait - aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
77c77cf89621f21c8e2bbad63058b5eaa5f88d4ajim //aTests[i].cUpper = (aTests[i].uMilliesWait + aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
77c77cf89621f21c8e2bbad63058b5eaa5f88d4ajim
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("\n"
62f707ed6864c9606c51b6cf4eddead74d5a1b16kess "tstTimer: TESTING - %d ms interval, %d ms wait, expects %d-%d ticks.\n",
62f707ed6864c9606c51b6cf4eddead74d5a1b16kess aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper);
62f707ed6864c9606c51b6cf4eddead74d5a1b16kess
62f707ed6864c9606c51b6cf4eddead74d5a1b16kess /*
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive * Start timer which ticks every 10ms.
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive gcTicks = 0;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTTIMERLR hTimerLR;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive gu64Max = 0;
b7aab8eefaa913af1b29d2f41d5c7ecbef9e32a4rbowen gu64Min = UINT64_MAX;
29d1295999773b9df63c15a1895bc5972ed55199takashi gu64Prev = 0;
29d1295999773b9df63c15a1895bc5972ed55199takashi rc = RTTimerLRCreateEx(&hTimerLR, aTests[i].uMilliesInterval * (uint64_t)1000000, 0, TimerLRCallback, NULL);
29d1295999773b9df63c15a1895bc5972ed55199takashi if (RT_FAILURE(rc))
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("RTTimerLRCreateEX(,%u*1M,,,) -> %d\n", aTests[i].uMilliesInterval, rc);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive cErrors++;
8ba890719035fe67c295c9124693138f9c5aa933kess continue;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
62f707ed6864c9606c51b6cf4eddead74d5a1b16kess /*
f4cbda69df0490c6deaacb8d04f103d200ddd183nd * Start the timer an actively wait for it for the period requested.
f4cbda69df0490c6deaacb8d04f103d200ddd183nd */
f4cbda69df0490c6deaacb8d04f103d200ddd183nd uTSBegin = RTTimeNanoTS();
f4cbda69df0490c6deaacb8d04f103d200ddd183nd rc = RTTimerLRStart(hTimerLR, 0);
f4cbda69df0490c6deaacb8d04f103d200ddd183nd if (RT_FAILURE(rc))
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: FAILURE - RTTimerLRStart() -> %Rrc\n", rc);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive cErrors++;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /* nothing */;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /* don't stop it, destroy it because there are potential races in destroying an active timer. */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive rc = RTTimerLRDestroy(hTimerLR);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive if (RT_FAILURE(rc))
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive cErrors++;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive uint64_t uTSEnd = RTTimeNanoTS();
5e7fa9795c20ab86177469e40e0fab9069d4f2d0erikabele uTSDiff = uTSEnd - uTSBegin;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /* Check that it really stopped. */
18b044262d499eb4255fb75026564a3e33b961eand unsigned cTicks = gcTicks;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTThreadSleep(aTests[i].uMilliesInterval * 2);
c548d82288fe9cbef5be32928f313b31ac33f1adrbowen if (gcTicks != cTicks)
c548d82288fe9cbef5be32928f313b31ac33f1adrbowen {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive cErrors++;
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive continue;
c548d82288fe9cbef5be32928f313b31ac33f1adrbowen }
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive /*
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive * Check the number of ticks.
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf */
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive if (gcTicks < aTests[i].cLower)
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive {
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower);
d4db54bec4e64c8bc78d59d9f6dd6e4cff8a3559slive cErrors++;
5a58787efeb02a1c3f06569d019ad81fd2efa06end }
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd else if (gcTicks > aTests[i].cUpper)
a78048ccbdb6256da15e6b0e7e95355e480c2301nd {
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower);
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung cErrors++;
727872d18412fc021f03969b8641810d8896820bhumbedooh }
0d0ba3a410038e179b695446bb149cce6264e0abnd else
727872d18412fc021f03969b8641810d8896820bhumbedooh RTPrintf("tstTimer: OK - gcTicks=%d", gcTicks);
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max);
0d0ba3a410038e179b695446bb149cce6264e0abnd }
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh
727872d18412fc021f03969b8641810d8896820bhumbedooh /*
0d0ba3a410038e179b695446bb149cce6264e0abnd * Test changing the interval dynamically
0d0ba3a410038e179b695446bb149cce6264e0abnd */
0d0ba3a410038e179b695446bb149cce6264e0abnd RTPrintf("\n"
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh "tstTimer: Testing dynamic changes of timer interval...\n");
0d0ba3a410038e179b695446bb149cce6264e0abnd do
0d0ba3a410038e179b695446bb149cce6264e0abnd {
0d0ba3a410038e179b695446bb149cce6264e0abnd RTTIMERLR hTimerLR;
727872d18412fc021f03969b8641810d8896820bhumbedooh rc = RTTimerLRCreateEx(&hTimerLR, aTests[0].uMilliesInterval * (uint64_t)1000000, 0, TimerLRCallback, NULL);
0d0ba3a410038e179b695446bb149cce6264e0abnd if (RT_FAILURE(rc))
0d0ba3a410038e179b695446bb149cce6264e0abnd {
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh RTPrintf("RTTimerLRCreateEX(,%u*1M,,,) -> %d\n", aTests[i].uMilliesInterval, rc);
205f749042ed530040a4f0080dbcb47ceae8a374rjung cErrors++;
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen continue;
0d0ba3a410038e179b695446bb149cce6264e0abnd }
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd for (i = 0; i < RT_ELEMENTS(aTests); i++)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd {
5a58787efeb02a1c3f06569d019ad81fd2efa06end RTPrintf("\n"
"tstTimer: TESTING - %d ms interval, %d ms wait, expects %d-%d ticks.\n",
aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper);
gcTicks = 0;
gu64Max = 0;
gu64Min = UINT64_MAX;
gu64Prev = 0;
/*
* Start the timer an actively wait for it for the period requested.
*/
uTSBegin = RTTimeNanoTS();
if (i == 0)
{
rc = RTTimerLRStart(hTimerLR, 0);
if (RT_FAILURE(rc))
{
RTPrintf("tstTimer: FAILURE - RTTimerLRStart() -> %Rrc\n", rc);
cErrors++;
}
}
else
{
rc = RTTimerLRChangeInterval(hTimerLR, aTests[i].uMilliesInterval * (uint64_t)1000000);
if (RT_FAILURE(rc))
{
RTPrintf("tstTimer: FAILURE - RTTimerLRChangeInterval() -> %d gcTicks=%d\n", rc, gcTicks);
cErrors++;
}
}
while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)
/* nothing */;
uint64_t uTSEnd = RTTimeNanoTS();
uTSDiff = uTSEnd - uTSBegin;
RTPrintf("uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd);
/*
* Check the number of ticks.
*/
if (gcTicks < aTests[i].cLower)
{
RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)\n", gcTicks, aTests[i].cUpper, aTests[i].cLower);
cErrors++;
}
else if (gcTicks > aTests[i].cUpper)
{
RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)\n", gcTicks, aTests[i].cUpper, aTests[i].cLower);
cErrors++;
}
else
RTPrintf("tstTimer: OK - gcTicks=%d\n", gcTicks);
// RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max);
}
/* don't stop it, destroy it because there are potential races in destroying an active timer. */
rc = RTTimerLRDestroy(hTimerLR);
if (RT_FAILURE(rc))
{
RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
cErrors++;
}
} while (0);
/*
* Test multiple timers running at once.
*/
/** @todo multiple LR timer testcase. */
/*
* Summary.
*/
if (!cErrors)
RTPrintf("tstTimer: SUCCESS\n");
else
RTPrintf("tstTimer: FAILURE %d errors\n", cErrors);
return !!cErrors;
}