summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2017-01-09 09:08:37 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2017-01-09 09:08:37 (GMT)
commitda5d89d1b8d0d6c43f14f1993ad5e129cbd4ccef (patch)
treea1ca4c82103d6fb90b45c5d4bf51cc29ff8fc645
parent3367917da33d62c2c1a0818657d02082f4ec4302 (diff)
parentb901129d9617508943f0a9e70ae6de14b10c8fec (diff)
downloadtcl-da5d89d1b8d0d6c43f14f1993ad5e129cbd4ccef.zip
tcl-da5d89d1b8d0d6c43f14f1993ad5e129cbd4ccef.tar.gz
tcl-da5d89d1b8d0d6c43f14f1993ad5e129cbd4ccef.tar.bz2
Fix for [b87ad7e9146832d505f9a430d779c5313c440256|b87ad7e914], rebased to core-8-5-branch (who said fossil doesn't have 'rebase'...), and moved the definition of "struct _timeb t" to the top of the function.bug_b87ad7e914
This branch is ready to be merged to core-8-5-branch, it looks good to me. Thanks to sebres (Dipl. Ing. Sergey G. Brester)
-rw-r--r--unix/tclUnixTime.c2
-rw-r--r--win/tclWinTime.c60
2 files changed, 40 insertions, 22 deletions
diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c
index b98f2e1..11b0ecf 100644
--- a/unix/tclUnixTime.c
+++ b/unix/tclUnixTime.c
@@ -161,7 +161,7 @@ TclpGetWideClicks(void)
Tcl_Time time;
(*tclGetTimeProcPtr) (&time, tclTimeClientData);
- now = (Tcl_WideInt) (time.sec*1000000 + time.usec);
+ now = ((Tcl_WideInt)time.sec)*1000000 + time.usec;
} else {
#ifdef MAC_OSX_TCL
now = (Tcl_WideInt) (mach_absolute_time() & INT64_MAX);
diff --git a/win/tclWinTime.c b/win/tclWinTime.c
index 0163723..46e2cd2 100644
--- a/win/tclWinTime.c
+++ b/win/tclWinTime.c
@@ -310,8 +310,6 @@ NativeGetTime(
ClientData clientData)
{
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.
@@ -427,6 +425,10 @@ NativeGetTime(
* time.
*/
+ ULARGE_INTEGER fileTimeLastCall;
+ LARGE_INTEGER perfCounterLastCall, curCounterFreq;
+ /* Copy with current data of calibration cycle */
+
LARGE_INTEGER curCounter;
/* Current performance counter. */
Tcl_WideInt curFileTime;/* Current estimated time, expressed as 100-ns
@@ -440,9 +442,29 @@ NativeGetTime(
posixEpoch.LowPart = 0xD53E8000;
posixEpoch.HighPart = 0x019DB1DE;
+ QueryPerformanceCounter(&curCounter);
+
+ /*
+ * Hold time section locked as short as possible
+ */
EnterCriticalSection(&timeInfo.cs);
- QueryPerformanceCounter(&curCounter);
+ fileTimeLastCall.QuadPart = timeInfo.fileTimeLastCall.QuadPart;
+ perfCounterLastCall.QuadPart = timeInfo.perfCounterLastCall.QuadPart;
+ curCounterFreq.QuadPart = timeInfo.curCounterFreq.QuadPart;
+
+ LeaveCriticalSection(&timeInfo.cs);
+
+ /*
+ * If calibration cycle occurred after we get curCounter
+ */
+ if (curCounter.QuadPart <= perfCounterLastCall.QuadPart) {
+ usecSincePosixEpoch =
+ (fileTimeLastCall.QuadPart - posixEpoch.QuadPart) / 10;
+ timePtr->sec = (long) (usecSincePosixEpoch / 1000000);
+ timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000);
+ return;
+ }
/*
* If it appears to be more than 1.1 seconds since the last trip
@@ -454,31 +476,27 @@ NativeGetTime(
* loop should recover.
*/
- if (curCounter.QuadPart - timeInfo.perfCounterLastCall.QuadPart <
- 11 * timeInfo.curCounterFreq.QuadPart / 10) {
- curFileTime = timeInfo.fileTimeLastCall.QuadPart +
- ((curCounter.QuadPart - timeInfo.perfCounterLastCall.QuadPart)
- * 10000000 / timeInfo.curCounterFreq.QuadPart);
- timeInfo.fileTimeLastCall.QuadPart = curFileTime;
- timeInfo.perfCounterLastCall.QuadPart = curCounter.QuadPart;
+ if (curCounter.QuadPart - perfCounterLastCall.QuadPart <
+ 11 * curCounterFreq.QuadPart / 10
+ ) {
+ curFileTime = fileTimeLastCall.QuadPart +
+ ((curCounter.QuadPart - perfCounterLastCall.QuadPart)
+ * 10000000 / curCounterFreq.QuadPart);
+
usecSincePosixEpoch = (curFileTime - posixEpoch.QuadPart) / 10;
timePtr->sec = (long) (usecSincePosixEpoch / 1000000);
timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000);
- useFtime = 0;
+ return;
}
-
- LeaveCriticalSection(&timeInfo.cs);
}
- if (useFtime) {
- /*
- * High resolution timer is not available. Just use ftime.
- */
+ /*
+ * High resolution timer is not available. Just use ftime.
+ */
- _ftime(&t);
- timePtr->sec = (long)t.time;
- timePtr->usec = t.millitm * 1000;
- }
+ _ftime(&t);
+ timePtr->sec = (long)t.time;
+ timePtr->usec = t.millitm * 1000;
}
/*