diff options
author | Kevin B Kenny <kennykb@acm.org> | 2003-02-14 22:16:27 (GMT) |
---|---|---|
committer | Kevin B Kenny <kennykb@acm.org> | 2003-02-14 22:16:27 (GMT) |
commit | c92dca4e09cb0da0cb6417cecb0562d2cb9c5987 (patch) | |
tree | d6c0ee649d8237dae19a412ca1405f271573d795 /win | |
parent | bd6ef46ac1eac8105c432e3ae7fb7addd1efdc07 (diff) | |
download | tcl-c92dca4e09cb0da0cb6417cecb0562d2cb9c5987.zip tcl-c92dca4e09cb0da0cb6417cecb0562d2cb9c5987.tar.gz tcl-c92dca4e09cb0da0cb6417cecb0562d2cb9c5987.tar.bz2 |
* win/tclWinTime.c: Added code to test and compensate for forward
leaps of the performance counter. See the MSDN Knowledge Base article
Q274323 for the hardware problem that makes this necessary on certain
machines.
* tests/winTime.test: Revised winTime-2.1 - it had a tolerance of
thousands of seconds, rather than milliseconds. (What's six orders of
magnitude among friends?
Both the above changes are triggered by a problem reported at
http://aspn.activestate.com/ASPN/Mail/Message/ActiveTcl/1536811
although the developers find it difficult to believe that it accounts
for the observed behavior and suspect a fault in the RTC chip.
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinTime.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 70ab93d..63da982 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinTime.c,v 1.13 2003/01/27 02:19:57 mdejong Exp $ + * RCS: @(#) $Id: tclWinTime.c,v 1.14 2003/02/14 22:16:27 kennykb Exp $ */ #include "tclWinInt.h" @@ -252,6 +252,10 @@ Tcl_GetTime(timePtr) struct timeb t; + int useFtime = 1; /* Flag == TRUE if we need to fall back + * on ftime rather than using the perf + * counter */ + /* Initialize static storage on the first trip through. */ /* @@ -360,22 +364,34 @@ Tcl_GetTime(timePtr) EnterCriticalSection( &timeInfo.cs ); QueryPerformanceCounter( &curCounter ); - curFileTime = timeInfo.lastFileTime.QuadPart - + ( ( curCounter.QuadPart - timeInfo.lastCounter.QuadPart ) - * 10000000 / timeInfo.curCounterFreq.QuadPart ); - timeInfo.lastFileTime.QuadPart = curFileTime; - timeInfo.lastCounter.QuadPart = curCounter.QuadPart; - usecSincePosixEpoch = ( curFileTime - posixEpoch.QuadPart ) / 10; - timePtr->sec = (time_t) ( usecSincePosixEpoch / 1000000 ); - timePtr->usec = (unsigned long ) ( usecSincePosixEpoch % 1000000 ); - - LeaveCriticalSection( &timeInfo.cs ); + /* + * If it appears to be more than 1.1 seconds since the last trip + * through the calibration loop, the performance counter may + * have jumped. Discard it. See MSDN Knowledge Base article + * Q274323 for a description of the hardware problem that makes + * this test necessary. + */ + if ( curCounter.QuadPart - timeInfo.lastPerfCounter + < 11 * timeInfo.estPerfCounterFreq / 10 ) { + + curFileTime = timeInfo.lastFileTime.QuadPart + + ( ( curCounter.QuadPart - timeInfo.lastCounter.QuadPart ) + * 10000000 / timeInfo.curCounterFreq.QuadPart ); + timeInfo.lastFileTime.QuadPart = curFileTime; + timeInfo.lastCounter.QuadPart = curCounter.QuadPart; + usecSincePosixEpoch = ( curFileTime - posixEpoch.QuadPart ) / 10; + timePtr->sec = (time_t) ( usecSincePosixEpoch / 1000000 ); + timePtr->usec = (unsigned long ) ( usecSincePosixEpoch % 1000000 ); + useFtime = 0; + } + LeaveCriticalSection( &timeInfo.cs ); + } - } else { + if ( useFtime ) { /* High resolution timer is not available. Just use ftime */ - + ftime(&t); timePtr->sec = t.time; timePtr->usec = t.millitm * 1000; |