|
12 | 12 |
|
13 | 13 | /* $Id$ */
|
14 | 14 |
|
15 |
| - /** |
16 |
| - * |
17 |
| - * 04-Feb-2001 |
18 |
| - * - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi> |
19 |
| - * Improves accuracy of msec |
20 |
| - */ |
21 |
| - |
22 | 15 | /* Include stuff ************************************************************ */
|
23 | 16 |
|
24 | 17 | #include <config.w32.h>
|
|
32 | 25 | #include <errno.h>
|
33 | 26 | #include "php_win32_globals.h"
|
34 | 27 |
|
35 |
| -int getfilesystemtime(struct timeval *time_Info) |
| 28 | +typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); |
| 29 | + |
| 30 | +static MyGetSystemTimeAsFileTime get_time_func(void) |
36 | 31 | {
|
37 |
| - FILETIME ft; |
38 |
| - __int64 ff; |
39 |
| - ULARGE_INTEGER convFromft; |
40 |
| - |
41 |
| - GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */ |
42 |
| - /* resolution seems to be 0.01 sec */ |
43 |
| - /* |
44 |
| - * Do not cast a pointer to a FILETIME structure to either a |
45 |
| - * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows. |
46 |
| - * via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx |
47 |
| - */ |
48 |
| - convFromft.HighPart = ft.dwHighDateTime; |
49 |
| - convFromft.LowPart = ft.dwLowDateTime; |
50 |
| - ff = convFromft.QuadPart; |
51 |
| - |
52 |
| - time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600); |
53 |
| - time_Info->tv_usec = (int)(ff % 10000000)/10; |
54 |
| - return 0; |
| 32 | + MyGetSystemTimeAsFileTime timefunc = NULL; |
| 33 | + HMODULE hMod = LoadLibrary("kernel32.dll"); |
| 34 | + |
| 35 | + if (hMod) { |
| 36 | + /* Max possible resolution <1us, win8/server2012 */ |
| 37 | + timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); |
| 38 | + |
| 39 | + if(!timefunc) { |
| 40 | + /* 100ns blocks since 01-Jan-1641 */ |
| 41 | + timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime"); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + return timefunc; |
55 | 46 | }
|
56 | 47 |
|
57 |
| - |
| 48 | +int getfilesystemtime(struct timeval *tv) |
| 49 | +{ |
| 50 | + FILETIME ft; |
| 51 | + unsigned __int64 ff = 0; |
| 52 | + MyGetSystemTimeAsFileTime timefunc; |
| 53 | + |
| 54 | + timefunc = get_time_func(); |
| 55 | + if (timefunc) { |
| 56 | + timefunc(&ft); |
| 57 | + } else { |
| 58 | + GetSystemTimeAsFileTime(&ft); |
| 59 | + } |
| 60 | + |
| 61 | + ff |= ft.dwHighDateTime; |
| 62 | + ff <<= 32; |
| 63 | + ff |= ft.dwLowDateTime; |
| 64 | + ff /= 10; /* convert to microseconds */ |
| 65 | + ff -= 11644473600000000Ui64; /* convert to unix epoch */ |
| 66 | + |
| 67 | + tv->tv_sec = (long)(ff / 1000000UL); |
| 68 | + tv->tv_usec = (long)(ff % 1000000UL); |
| 69 | + |
| 70 | + return 0; |
| 71 | +} |
58 | 72 |
|
59 | 73 | PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
|
60 | 74 | {
|
61 |
| - __int64 timer; |
62 |
| - LARGE_INTEGER li; |
63 |
| - BOOL b; |
64 |
| - double dt; |
65 |
| - TSRMLS_FETCH(); |
66 |
| - |
67 | 75 | /* Get the time, if they want it */
|
68 | 76 | if (time_Info != NULL) {
|
69 |
| - if (PW32G(starttime).tv_sec == 0) { |
70 |
| - b = QueryPerformanceFrequency(&li); |
71 |
| - if (!b) { |
72 |
| - PW32G(starttime).tv_sec = -1; |
73 |
| - } |
74 |
| - else { |
75 |
| - PW32G(freq) = li.QuadPart; |
76 |
| - b = QueryPerformanceCounter(&li); |
77 |
| - if (!b) { |
78 |
| - PW32G(starttime).tv_sec = -1; |
79 |
| - } |
80 |
| - else { |
81 |
| - getfilesystemtime(&PW32G(starttime)); |
82 |
| - timer = li.QuadPart; |
83 |
| - dt = (double)timer/PW32G(freq); |
84 |
| - PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000); |
85 |
| - if (PW32G(starttime).tv_usec < 0) { |
86 |
| - PW32G(starttime).tv_usec += 1000000; |
87 |
| - --PW32G(starttime).tv_sec; |
88 |
| - } |
89 |
| - PW32G(starttime).tv_sec -= (int)dt; |
90 |
| - } |
91 |
| - } |
92 |
| - } |
93 |
| - if (PW32G(starttime).tv_sec > 0) { |
94 |
| - b = QueryPerformanceCounter(&li); |
95 |
| - if (!b) { |
96 |
| - PW32G(starttime).tv_sec = -1; |
97 |
| - } |
98 |
| - else { |
99 |
| - timer = li.QuadPart; |
100 |
| - if (timer < PW32G(lasttime)) { |
101 |
| - getfilesystemtime(time_Info); |
102 |
| - dt = (double)timer/PW32G(freq); |
103 |
| - PW32G(starttime) = *time_Info; |
104 |
| - PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000); |
105 |
| - if (PW32G(starttime).tv_usec < 0) { |
106 |
| - PW32G(starttime).tv_usec += 1000000; |
107 |
| - --PW32G(starttime).tv_sec; |
108 |
| - } |
109 |
| - PW32G(starttime).tv_sec -= (int)dt; |
110 |
| - } |
111 |
| - else { |
112 |
| - PW32G(lasttime) = timer; |
113 |
| - dt = (double)timer/PW32G(freq); |
114 |
| - time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt; |
115 |
| - time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000); |
116 |
| - if (time_Info->tv_usec >= 1000000) { |
117 |
| - time_Info->tv_usec -= 1000000; |
118 |
| - ++time_Info->tv_sec; |
119 |
| - } |
120 |
| - } |
121 |
| - } |
122 |
| - } |
123 |
| - if (PW32G(starttime).tv_sec < 0) { |
124 |
| - getfilesystemtime(time_Info); |
125 |
| - } |
126 |
| - |
| 77 | + getfilesystemtime(time_Info); |
127 | 78 | }
|
128 | 79 | /* Get the timezone, if they want it */
|
129 | 80 | if (timezone_Info != NULL) {
|
|
0 commit comments