From: Anatol Belski Date: Mon, 11 Mar 2013 15:04:37 +0000 (+0100) Subject: Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']) X-Git-Tag: php-5.6.0alpha1~480^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8aaa09636a3efee7d6e92103dad1ae2c1d137e72;p=php Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']) --- diff --git a/NEWS b/NEWS index 4ef3a55bc1..291ec52e40 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ PHP NEWS . Added support for changing the process's title in CLI/CLI-Server SAPIs. The implementation is more robust that the proctitle PECL module. More details here: https://wiki.php.net/rfc/cli_process_title. (Keyur) + . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']). + (Anatol) 07 Mar 2013, PHP 5.5.0 Alpha 6 diff --git a/ext/standard/tests/bug64370_var1.phpt b/ext/standard/tests/bug64370_var1.phpt new file mode 100644 index 0000000000..3f25f534ba --- /dev/null +++ b/ext/standard/tests/bug64370_var1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test bug #64370 microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT'] +--FILE-- + +===DONE=== +--EXPECTF-- +$_SERVER['REQUEST_TIME']: %d +$_SERVER['REQUEST_TIME_FLOAT']: %f +time(): %d +microtime(true): %f +created in %f ms +===DONE=== diff --git a/ext/standard/tests/bug64370_var2.phpt b/ext/standard/tests/bug64370_var2.phpt new file mode 100644 index 0000000000..d0d3590ea7 --- /dev/null +++ b/ext/standard/tests/bug64370_var2.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test bug #64370 sequential microtime(true) calls +--FILE-- + $i++) { + $m0 = microtime(true); + $m1 = microtime(true); + $d = $m1 - $m0; + + /*echo "$d\n";*/ + + if ($d < 0) { + die("failed in {$i}th iteration"); + } +} +echo "ok\n"; +?> +===DONE=== +--EXPECT-- +ok +===DONE=== diff --git a/win32/globals.c b/win32/globals.c index 1bbb3b4481..b381cc1237 100644 --- a/win32/globals.c +++ b/win32/globals.c @@ -65,8 +65,6 @@ PHP_RSHUTDOWN_FUNCTION(win32_core_globals) ; closelog(); - wg->starttime.tv_sec = 0; - wg->lasttime = 0; return SUCCESS; } diff --git a/win32/php_win32_globals.h b/win32/php_win32_globals.h index 1686e5df63..b2b07f68e1 100644 --- a/win32/php_win32_globals.h +++ b/win32/php_win32_globals.h @@ -38,10 +38,6 @@ struct _php_win32_core_globals { char *log_header; HANDLE log_source; - /* time */ - struct timeval starttime; - __int64 lasttime, freq; - HKEY registry_key; HANDLE registry_event; HashTable *registry_directories; diff --git a/win32/time.c b/win32/time.c index 391a8a81e9..77e4504cd1 100644 --- a/win32/time.c +++ b/win32/time.c @@ -12,13 +12,6 @@ /* $Id$ */ - /** - * - * 04-Feb-2001 - * - Added patch by "Vanhanen, Reijo" - * Improves accuracy of msec - */ - /* Include stuff ************************************************************ */ #include @@ -32,98 +25,56 @@ #include #include "php_win32_globals.h" -int getfilesystemtime(struct timeval *time_Info) +typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); + +static MyGetSystemTimeAsFileTime get_time_func(void) { - FILETIME ft; - __int64 ff; - ULARGE_INTEGER convFromft; - - GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */ - /* resolution seems to be 0.01 sec */ - /* - * 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 - */ - convFromft.HighPart = ft.dwHighDateTime; - convFromft.LowPart = ft.dwLowDateTime; - ff = convFromft.QuadPart; - - time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600); - time_Info->tv_usec = (int)(ff % 10000000)/10; - return 0; + MyGetSystemTimeAsFileTime timefunc = NULL; + HMODULE hMod = LoadLibrary("kernel32.dll"); + + if (hMod) { + /* Max possible resolution <1us, win8/server2012 */ + timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); + + if(!timefunc) { + /* 100ns blocks since 01-Jan-1641 */ + timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime"); + } + } + + return timefunc; } - +int getfilesystemtime(struct timeval *tv) +{ + FILETIME ft; + unsigned __int64 ff = 0; + MyGetSystemTimeAsFileTime timefunc; + + timefunc = get_time_func(); + if (timefunc) { + timefunc(&ft); + } else { + GetSystemTimeAsFileTime(&ft); + } + + ff |= ft.dwHighDateTime; + ff <<= 32; + ff |= ft.dwLowDateTime; + ff /= 10; /* convert to microseconds */ + ff -= 11644473600000000Ui64; /* convert to unix epoch */ + + tv->tv_sec = (long)(ff / 1000000UL); + tv->tv_usec = (long)(ff % 1000000UL); + + return 0; +} PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) { - __int64 timer; - LARGE_INTEGER li; - BOOL b; - double dt; - TSRMLS_FETCH(); - /* Get the time, if they want it */ if (time_Info != NULL) { - if (PW32G(starttime).tv_sec == 0) { - b = QueryPerformanceFrequency(&li); - if (!b) { - PW32G(starttime).tv_sec = -1; - } - else { - PW32G(freq) = li.QuadPart; - b = QueryPerformanceCounter(&li); - if (!b) { - PW32G(starttime).tv_sec = -1; - } - else { - getfilesystemtime(&PW32G(starttime)); - timer = li.QuadPart; - dt = (double)timer/PW32G(freq); - PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000); - if (PW32G(starttime).tv_usec < 0) { - PW32G(starttime).tv_usec += 1000000; - --PW32G(starttime).tv_sec; - } - PW32G(starttime).tv_sec -= (int)dt; - } - } - } - if (PW32G(starttime).tv_sec > 0) { - b = QueryPerformanceCounter(&li); - if (!b) { - PW32G(starttime).tv_sec = -1; - } - else { - timer = li.QuadPart; - if (timer < PW32G(lasttime)) { - getfilesystemtime(time_Info); - dt = (double)timer/PW32G(freq); - PW32G(starttime) = *time_Info; - PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000); - if (PW32G(starttime).tv_usec < 0) { - PW32G(starttime).tv_usec += 1000000; - --PW32G(starttime).tv_sec; - } - PW32G(starttime).tv_sec -= (int)dt; - } - else { - PW32G(lasttime) = timer; - dt = (double)timer/PW32G(freq); - time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt; - time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000); - if (time_Info->tv_usec >= 1000000) { - time_Info->tv_usec -= 1000000; - ++time_Info->tv_sec; - } - } - } - } - if (PW32G(starttime).tv_sec < 0) { - getfilesystemtime(time_Info); - } - + getfilesystemtime(time_Info); } /* Get the timezone, if they want it */ if (timezone_Info != NULL) {