diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-01-09 09:08:37 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-01-09 09:08:37 (GMT) |
commit | da5d89d1b8d0d6c43f14f1993ad5e129cbd4ccef (patch) | |
tree | a1ca4c82103d6fb90b45c5d4bf51cc29ff8fc645 /win | |
parent | 3367917da33d62c2c1a0818657d02082f4ec4302 (diff) | |
parent | b901129d9617508943f0a9e70ae6de14b10c8fec (diff) | |
download | tcl-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)
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinTime.c | 60 |
1 files changed, 39 insertions, 21 deletions
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; } /* |