VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstTimer.cpp@ 31329

Last change on this file since 31329 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.0 KB
Line 
1/* $Id: tstTimer.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Timers.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <iprt/timer.h>
31#include <iprt/time.h>
32#include <iprt/thread.h>
33#include <iprt/initterm.h>
34#include <iprt/stream.h>
35#include <iprt/err.h>
36
37
38
39/*******************************************************************************
40* Global Variables *
41*******************************************************************************/
42static volatile unsigned gcTicks;
43static volatile uint64_t gu64Min;
44static volatile uint64_t gu64Max;
45static volatile uint64_t gu64Prev;
46
47static DECLCALLBACK(void) TimerCallback(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
48{
49 gcTicks++;
50
51 const uint64_t u64Now = RTTimeNanoTS();
52 if (gu64Prev)
53 {
54 const uint64_t u64Delta = u64Now - gu64Prev;
55 if (u64Delta < gu64Min)
56 gu64Min = u64Delta;
57 if (u64Delta > gu64Max)
58 gu64Max = u64Delta;
59 }
60 gu64Prev = u64Now;
61}
62
63
64int main()
65{
66 /*
67 * Init runtime
68 */
69 unsigned cErrors = 0;
70 int rc = RTR3Init();
71 if (RT_FAILURE(rc))
72 {
73 RTPrintf("tstTimer: RTR3Init() -> %d\n", rc);
74 return 1;
75 }
76
77 /*
78 * Check that the clock is reliable.
79 */
80 RTPrintf("tstTimer: TESTING - RTTimeNanoTS() for 2sec\n");
81 uint64_t uTSMillies = RTTimeMilliTS();
82 uint64_t uTSBegin = RTTimeNanoTS();
83 uint64_t uTSLast = uTSBegin;
84 uint64_t uTSDiff;
85 uint64_t cIterations = 0;
86
87 do
88 {
89 uint64_t uTS = RTTimeNanoTS();
90 if (uTS < uTSLast)
91 {
92 RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. uTS=%RU64 uTSLast=%RU64\n", uTS, uTSLast);
93 cErrors++;
94 }
95 if (++cIterations > (2*1000*1000*1000))
96 {
97 RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. cIterations=%RU64 uTS=%RU64 uTSBegin=%RU64\n", cIterations, uTS, uTSBegin);
98 return 1;
99 }
100 uTSLast = uTS;
101 uTSDiff = uTSLast - uTSBegin;
102 } while (uTSDiff < (2*1000*1000*1000));
103 uTSMillies = RTTimeMilliTS() - uTSMillies;
104 if (uTSMillies >= 2500 || uTSMillies <= 1500)
105 {
106 RTPrintf("tstTimer: FAILURE - uTSMillies=%RI64 uTSBegin=%RU64 uTSLast=%RU64 uTSDiff=%RU64\n",
107 uTSMillies, uTSBegin, uTSLast, uTSDiff);
108 cErrors++;
109 }
110 if (!cErrors)
111 RTPrintf("tstTimer: OK - RTTimeNanoTS()\n");
112
113 /*
114 * Tests.
115 */
116 static struct
117 {
118 unsigned uMilliesInterval;
119 unsigned uMilliesWait;
120 unsigned cLower;
121 unsigned cUpper;
122 } aTests[] =
123 {
124 { 32, 2000, 0, 0 },
125 { 20, 2000, 0, 0 },
126 { 10, 2000, 0, 0 },
127 { 8, 2000, 0, 0 },
128 { 2, 2000, 0, 0 },
129 { 1, 2000, 0, 0 }
130 };
131
132 unsigned i = 0;
133 for (i = 0; i < RT_ELEMENTS(aTests); i++)
134 {
135 aTests[i].cLower = (aTests[i].uMilliesWait - aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
136 aTests[i].cUpper = (aTests[i].uMilliesWait + aTests[i].uMilliesWait / 10) / aTests[i].uMilliesInterval;
137
138 RTPrintf("\n"
139 "tstTimer: TESTING - %d ms interval, %d ms wait, expects %d-%d ticks.\n",
140 aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper);
141
142 /*
143 * Start timer which ticks every 10ms.
144 */
145 gcTicks = 0;
146 PRTTIMER pTimer;
147 gu64Max = 0;
148 gu64Min = UINT64_MAX;
149 gu64Prev = 0;
150#ifdef RT_OS_WINDOWS
151 rc = RTTimerCreate(&pTimer, aTests[i].uMilliesInterval, TimerCallback, NULL);
152#else
153 rc = RTTimerCreateEx(&pTimer, aTests[i].uMilliesInterval * (uint64_t)1000000, 0, TimerCallback, NULL);
154#endif
155 if (RT_FAILURE(rc))
156 {
157 RTPrintf("tstTimer: FAILURE - RTTimerCreateEx(,%u*1M,,,) -> %Rrc\n", aTests[i].uMilliesInterval, rc);
158 cErrors++;
159 continue;
160 }
161
162 /*
163 * Start the timer and active waiting for the requested test period.
164 */
165 uTSBegin = RTTimeNanoTS();
166#ifndef RT_OS_WINDOWS
167 rc = RTTimerStart(pTimer, 0);
168 if (RT_FAILURE(rc))
169 {
170 RTPrintf("tstTimer: FAILURE - RTTimerStart(,0) -> %Rrc\n", aTests[i].uMilliesInterval, rc);
171 cErrors++;
172 }
173#endif
174
175 while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)
176 /* nothing */;
177
178 /* destroy the timer */
179 uint64_t uTSEnd = RTTimeNanoTS();
180 uTSDiff = uTSEnd - uTSBegin;
181 rc = RTTimerDestroy(pTimer);
182 if (RT_FAILURE(rc))
183 {
184 RTPrintf("tstTimer: FAILURE - RTTimerDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
185 cErrors++;
186 }
187
188 RTPrintf("tstTimer: uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd);
189 unsigned cTicks = gcTicks;
190 RTThreadSleep(aTests[i].uMilliesInterval * 3);
191 if (gcTicks != cTicks)
192 {
193 RTPrintf("tstTimer: FAILURE - RTTimerDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks);
194 cErrors++;
195 continue;
196 }
197
198 /*
199 * Check the number of ticks.
200 */
201 if (gcTicks < aTests[i].cLower)
202 {
203 RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower);
204 cErrors++;
205 }
206 else if (gcTicks > aTests[i].cUpper)
207 {
208 RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower);
209 cErrors++;
210 }
211 else
212 RTPrintf("tstTimer: OK - gcTicks=%d", gcTicks);
213 RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max);
214 }
215
216 /*
217 * Summary.
218 */
219 if (!cErrors)
220 RTPrintf("tstTimer: SUCCESS\n");
221 else
222 RTPrintf("tstTimer: FAILURE %d errors\n", cErrors);
223 return !!cErrors;
224}
225
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette