summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/winTime.test25
-rw-r--r--win/tclWinTime.c42
2 files changed, 40 insertions, 27 deletions
diff --git a/tests/winTime.test b/tests/winTime.test
index a8dec89..4827d63 100644
--- a/tests/winTime.test
+++ b/tests/winTime.test
@@ -10,13 +10,15 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: winTime.test,v 1.6 2000/11/21 21:33:42 andreas_kupries Exp $
+# RCS: @(#) $Id: winTime.test,v 1.7 2003/02/14 22:16:27 kennykb Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
+testConstraint testwinclock [llength [info commands testwinclock]]
+
# The next two tests will crash on Windows if the check for negative
# clock values is not done properly.
@@ -37,27 +39,22 @@ test winTime-1.2 {TclpGetDate} {pcOnly} {
# with the Windows clock. 3000 iterations really isn't enough,
# but how many does a tester have patience for?
-test winTime-2.1 {Synchronization of Tcl and Windows clocks} {pcOnly} {
- set failed 0
- foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] {}
- set olddiff [expr { abs ( $tcl_sec - $sys_sec
- + 1.0e-6 * ( $tcl_usec - $sys_usec ) ) }]
+test winTime-2.1 {Synchronization of Tcl and Windows clocks} {testwinclock} {
+ set failed {}
set ok 1
for { set i 0 } { $i < 3000 } { incr i } {
foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] {}
- set diff [expr { abs ( $tcl_sec - $sys_sec
- + 1.0e-6 * ( $tcl_usec - $sys_usec ) ) }]
- if { ( $diff > $olddiff + 1000 )
- || ( $diff > 11000 ) } {
- set failed 1
+ set diff [expr { $tcl_sec - $sys_sec
+ + 1.0e-6 * ( $tcl_usec - $sys_usec ) }]
+ if { abs($diff) > 0.02 } {
+ set failed "Tcl clock differs from system clock by $diff sec"
break
} else {
- set olddiff $diff
- after 1
+ after 10
}
}
set failed
-} {0}
+} {}
# cleanup
::tcltest::cleanupTests
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;