xref: /PHP-7.0/win32/time.c (revision 06332e67)
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 		if(!timefunc) {
43 			/* 100ns blocks since 01-Jan-1641 */
44 			timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
45 		}
46 	}
47 
48 	return timefunc;
49 }
50 
php_win32_init_gettimeofday(void)51 BOOL php_win32_init_gettimeofday(void)
52 {
53 	timefunc = get_time_func();
54 
55 	return (NULL != timefunc);
56 }
57 #endif
58 
getfilesystemtime(struct timeval * tv)59 static zend_always_inline int getfilesystemtime(struct timeval *tv)
60 {
61 	FILETIME ft;
62 	unsigned __int64 ff = 0;
63 	ULARGE_INTEGER fft;
64 
65 	timefunc(&ft);
66 
67         /*
68 	 * Do not cast a pointer to a FILETIME structure to either a
69 	 * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
70 	 * via  http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
71 	 */
72 	fft.HighPart = ft.dwHighDateTime;
73 	fft.LowPart = ft.dwLowDateTime;
74 	ff = fft.QuadPart;
75 
76 	ff /= 10Ui64; /* convert to microseconds */
77 	ff -= 11644473600000000Ui64; /* convert to unix epoch */
78 
79 	tv->tv_sec = (long)(ff / 1000000Ui64);
80 	tv->tv_usec = (long)(ff % 1000000Ui64);
81 
82 	return 0;
83 }
84 
gettimeofday(struct timeval * time_Info,struct timezone * timezone_Info)85 PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
86 {
87 	/* Get the time, if they want it */
88 	if (time_Info != NULL) {
89 		getfilesystemtime(time_Info);
90 	}
91 	/* Get the timezone, if they want it */
92 	if (timezone_Info != NULL) {
93 		_tzset();
94 		timezone_Info->tz_minuteswest = _timezone;
95 		timezone_Info->tz_dsttime = _daylight;
96 	}
97 	/* And return */
98 	return 0;
99 }
100 
usleep(unsigned int useconds)101 PHPAPI int usleep(unsigned int useconds)
102 {
103 	HANDLE timer;
104 	LARGE_INTEGER due;
105 
106 	due.QuadPart = -(10 * (__int64)useconds);
107 
108 	timer = CreateWaitableTimer(NULL, TRUE, NULL);
109 	SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
110 	WaitForSingleObject(timer, INFINITE);
111 	CloseHandle(timer);
112 	return 0;
113 }
114 
nanosleep(const struct timespec * rqtp,struct timespec * rmtp)115 PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
116 {
117 	if (rqtp->tv_nsec > 999999999) {
118 		/* The time interval specified 1,000,000 or more microseconds. */
119 		errno = EINVAL;
120 		return -1;
121 	}
122 	return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000  );
123 }
124 
125 /*
126  * Local variables:
127  * tab-width: 4
128  * c-basic-offset: 4
129  * End:
130  * vim600: sw=4 ts=4 fdm=marker
131  * vim<600: sw=4 ts=4
132  */
133