|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2013-04-11 16:52 UTC] phpbugs at musiclogistics dot net
Description: ------------ Probably caused by recent patch for bug #64370: Since v 5.4.14 microtime() only moves forward in 15,6 ms (1/64 sec) increments on Win7. Same for CLI and Apache 2.2 SAPI. Build: VC9 x86 Thread Safe (2013-Apr-10 22:55:28) from windows.php.net. Behaviour normal after downgrade to 5.4.13. This also breaks usleep() (only sleeping for multiples of 15,6 ms now) and uniqid() (returning the same value for 15,6 ms with $more_entropy = false). Test script: --------------- for ($startTimeMs = currentTimeMs(), $i = 0; $i < 10000; $i++) { //usleep(1); echo (currentTimeMs() - $startTimeMs) . ' '; } function currentTimeMs() { return round(microtime(true) * 1000000); } Expected result: ---------------- [what PHP 5.4.13 prints on the same machine:] 13 28 35 41 48 54 61 67 74 80 86 92 99 105 112 118 124 131 137 143 149 155 162 168 174 181 187 193 200 206 212 218 224 [...and so on] Actual result: -------------- 0 0 0 0 0 0 0 0 0 [many more zeroes] 15600 15600 15600 15600 [...] 31200 31200 31200 31200 31200 [...] 46800 46800 46800 46800 46800 [...and so on] PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 05 16:00:01 2025 UTC |
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; }