Bug #64633 [Asn]: microtime regression - resolution reduced to 64 ticks per second
| From: | ab@php.net | Date: | Fri, 10 Jan 2014 08:24:19 +0000 |
| Subject: | Bug #64633 [Asn]: microtime regression - resolution reduced to 64 ticks per second | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-183686@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=64633&edit=1
ID: 64633
Updated by: ab@php.net
Reported by: phpbugs at musiclogistics dot net
Summary: microtime regression - resolution reduced to 64
ticks per second
Status: Assigned
Type: Bug
Package: Date/time related
Operating System: Windows 7
PHP Version: 5.4.14
Assigned To: pajoye
Block user comment: N
Private report: N
New Comment:
@louis, that's exactly what i'm talking about - with the current variant one would never
get time1 > time2, i bet with the old variant using performance counters it could easy happen in
your situation. Running chrome seems to be a catalyser for some instability in your case. In the
current implementation time1 = time2 is the worst case, earlier it could be casual time1 > time2,
or not. Now it's never time1 > time2, but with the trade off.
@yohgaki, i don't think the patch you've posted is responsible, but merely the exclusion
of the performance counters. On win8 one can profit from the new API call
GetSystemTimePreciseAsFileTime(), which is comparable to Linux. On earlier it's
GetSystemTimeAsFileTime(). The latter has poorer accuracy, but is stable and will never deliver
time1 > time2. That's the trade off, as i've said above. Earlier performance counters
was used instead of GetSystemTimeAsFileTime(), which led to even more confusing bugs, as in the bug
#64370 and related. Turning back the old code will turn back time1 > time2 on win8 ancestors, as
it's hardware+API dependent and is more random than now.
Previous Comments:
------------------------------------------------------------------------
[2014-01-08 14:13:19] louis at stovesonline dot co dot uk
Having the same issue with 5.5.7 on Windows Server 2008 R2.
Interestingly starting Google Chrome on the server increases the tick rate for a few seconds,
meaning I can briefly get accurate results from my timing functions!
------------------------------------------------------------------------
[2013-08-01 06:53:57] yohgaki@php.net
Anyone could verify that this wouldn't happen with Windows 8/Windows Server 2012?
It seems different API is used for these platforms.
------------------------------------------------------------------------
[2013-08-01 06:07:53] yohgaki@php.net
I guess this commit is the cause.
git show b022e54bd100a914417e216
commit b022e54bd100a914417e216d0872d3e67edecaf9
Author: Anatol Belski <ab@php.net>
Date: Sat Mar 23 17:40:06 2013 +0100
Fixed possible precision loss in microtime
This is related to the fix for bug #64370. MSVC natively supports __int64
type,
so calculating with 32 bit ints is neither necessary nor reliable. Therefore
an older piece of code is reused.
diff --git a/win32/time.c b/win32/time.c
index 77e4504..7553974 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -50,6 +50,7 @@ int getfilesystemtime(struct timeval *tv)
FILETIME ft;
unsigned __int64 ff = 0;
MyGetSystemTimeAsFileTime timefunc;
+ ULARGE_INTEGER fft;
timefunc = get_time_func();
if (timefunc) {
@@ -58,14 +59,20 @@ int getfilesystemtime(struct timeval *tv)
GetSystemTimeAsFileTime(&ft);
}
- ff |= ft.dwHighDateTime;
- ff <<= 32;
- ff |= ft.dwLowDateTime;
- ff /= 10; /* convert to microseconds */
+ /*
+ * Do not cast a pointer to a FILETIME structure to either a
+ * ULARGE_INTEGER* or __int64* value because it can cause alignment
faults on 64-bit Windows.
+ * via http://technet.microsoft.com/en-
us/library/ms724284(v=vs.85).aspx
+ */
+ fft.HighPart = ft.dwHighDateTime;
+ fft.LowPart = ft.dwLowDateTime;
+ ff = fft.QuadPart;
+
+ ff /= 10Ui64; /* convert to microseconds */
ff -= 11644473600000000Ui64; /* convert to unix epoch */
- tv->tv_sec = (long)(ff / 1000000UL);
- tv->tv_usec = (long)(ff % 1000000UL);
+ tv->tv_sec = (long)(ff / 1000000Ui64);
+ tv->tv_usec = (long)(ff % 1000000Ui64);
return 0;
}
------------------------------------------------------------------------
[2013-08-01 05:43:03] yohgaki@php.net
Just a note.
Linux does not have problem at all, it seems.
http://3v4l.org/nMBha
------------------------------------------------------------------------
[2013-08-01 05:04:57] yaro2000 at yandex dot ru
5.4.09 - OK, 5.4.10 - OK ... 5.4.14 - BUG, 5.4.15 - BUG
Why?
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=64633
--
Edit this bug report at https://bugs.php.net/bug.php?id=64633&edit=1