version 1.1.1.2, 2012/05/29 12:34:34
|
version 1.1.1.3, 2013/07/22 01:32:15
|
Line 1
|
Line 1
|
|
|
/***************************************************************************** |
/***************************************************************************** |
* * |
* * |
* DH_TIME.C * |
* DH_TIME.C * |
Line 13
|
Line 12
|
|
|
/* $Id$ */ |
/* $Id$ */ |
|
|
/** |
|
* |
|
* 04-Feb-2001 |
|
* - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi> |
|
* Improves accuracy of msec |
|
*/ |
|
|
|
/* Include stuff ************************************************************ */ |
/* Include stuff ************************************************************ */ |
|
|
#include <config.w32.h> |
#include <config.w32.h> |
Line 33
|
Line 25
|
#include <errno.h> |
#include <errno.h> |
#include "php_win32_globals.h" |
#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; | MyGetSystemTimeAsFileTime timefunc = NULL; |
__int64 ff; | HMODULE hMod = LoadLibrary("kernel32.dll"); |
|
|
GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */ | if (hMod) { |
/* resolution seems to be 0.01 sec */ | /* Max possible resolution <1us, win8/server2012 */ |
ff = *(__int64*)(&ft); | timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); |
time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600); | |
time_Info->tv_usec = (int)(ff % 10000000)/10; | if(!timefunc) { |
return 0; | /* 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; |
| ULARGE_INTEGER fft; |
|
|
|
timefunc = get_time_func(); |
|
if (timefunc) { |
|
timefunc(&ft); |
|
} else { |
|
GetSystemTimeAsFileTime(&ft); |
|
} |
|
|
|
/* |
|
* 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 / 1000000Ui64); |
|
tv->tv_usec = (long)(ff % 1000000Ui64); |
|
|
|
return 0; |
|
} |
|
|
PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) |
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 */ |
/* Get the time, if they want it */ |
if (time_Info != NULL) { |
if (time_Info != NULL) { |
if (PW32G(starttime).tv_sec == 0) { | getfilesystemtime(time_Info); |
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); | |
} | |
| |
} |
} |
/* Get the timezone, if they want it */ |
/* Get the timezone, if they want it */ |
if (timezone_Info != NULL) { |
if (timezone_Info != NULL) { |