1 /*****************************************************************************
2 * *
3 * DH_TIME.C *
4 * *
5 * Freely redistributable and modifiable. Use at your own risk. *
6 * *
7 * Copyright 1994 The Downhill Project *
8 *
9 * Modified by Shane Caraveo for use with PHP
10 *
11 *****************************************************************************/
12
13 /* Include stuff ************************************************************ */
14
15 #include <config.w32.h>
16
17 #include "time.h"
18 #include "unistd.h"
19 #include "signal.h"
20 #include <windows.h>
21 #include <winbase.h>
22 #include <mmsystem.h>
23 #include <errno.h>
24 #include "php_win32_globals.h"
25
26 typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
27
28 static MyGetSystemTimeAsFileTime timefunc = NULL;
29
30 #ifdef PHP_EXPORTS
get_time_func(void)31 static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void)
32 {/*{{{*/
33 MyGetSystemTimeAsFileTime timefunc = NULL;
34 HMODULE hMod = GetModuleHandle("kernel32.dll");
35
36 if (hMod) {
37 /* Max possible resolution <1us, win8/server2012 */
38 timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
39 }
40
41 if(!timefunc) {
42 /* 100ns blocks since 01-Jan-1641 */
43 timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime;
44 }
45
46 return timefunc;
47 }/*}}}*/
48
php_win32_init_gettimeofday(void)49 void php_win32_init_gettimeofday(void)
50 {/*{{{*/
51 timefunc = get_time_func();
52 }/*}}}*/
53 #endif
54
getfilesystemtime(struct timeval * tv)55 static zend_always_inline int getfilesystemtime(struct timeval *tv)
56 {/*{{{*/
57 FILETIME ft;
58 unsigned __int64 ff = 0;
59 ULARGE_INTEGER fft;
60
61 timefunc(&ft);
62
63 /*
64 * Do not cast a pointer to a FILETIME structure to either a
65 * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
66 * via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
67 */
68 fft.HighPart = ft.dwHighDateTime;
69 fft.LowPart = ft.dwLowDateTime;
70 ff = fft.QuadPart;
71
72 ff /= 10Ui64; /* convert to microseconds */
73 ff -= 11644473600000000Ui64; /* convert to unix epoch */
74
75 tv->tv_sec = (long)(ff / 1000000Ui64);
76 tv->tv_usec = (long)(ff % 1000000Ui64);
77
78 return 0;
79 }/*}}}*/
80
gettimeofday(struct timeval * time_Info,struct timezone * timezone_Info)81 PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
82 {/*{{{*/
83 /* Get the time, if they want it */
84 if (time_Info != NULL) {
85 getfilesystemtime(time_Info);
86 }
87 /* Get the timezone, if they want it */
88 if (timezone_Info != NULL) {
89 _tzset();
90 timezone_Info->tz_minuteswest = _timezone;
91 timezone_Info->tz_dsttime = _daylight;
92 }
93 /* And return */
94 return 0;
95 }/*}}}*/
96
usleep(unsigned int useconds)97 PHPAPI int usleep(unsigned int useconds)
98 {/*{{{*/
99 HANDLE timer;
100 LARGE_INTEGER due;
101
102 due.QuadPart = -(10 * (__int64)useconds);
103
104 timer = CreateWaitableTimer(NULL, TRUE, NULL);
105 SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
106 WaitForSingleObject(timer, INFINITE);
107 CloseHandle(timer);
108 return 0;
109 }/*}}}*/
110
nanosleep(const struct timespec * rqtp,struct timespec * rmtp)111 PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
112 {/*{{{*/
113 if (rqtp->tv_nsec > 999999999) {
114 /* The time interval specified 1,000,000 or more microseconds. */
115 errno = EINVAL;
116 return -1;
117 }
118 return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000 );
119 }/*}}}*/
120