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