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: time.c,v 1.1.1.3 2013/07/22 01:32:15 misho Exp $ */
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 get_time_func(void)
31: {
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;
46: }
47:
48: int getfilesystemtime(struct timeval *tv)
49: {
50: FILETIME ft;
51: unsigned __int64 ff = 0;
52: MyGetSystemTimeAsFileTime timefunc;
53: ULARGE_INTEGER fft;
54:
55: timefunc = get_time_func();
56: if (timefunc) {
57: timefunc(&ft);
58: } else {
59: GetSystemTimeAsFileTime(&ft);
60: }
61:
62: /*
63: * Do not cast a pointer to a FILETIME structure to either a
64: * ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
65: * via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
66: */
67: fft.HighPart = ft.dwHighDateTime;
68: fft.LowPart = ft.dwLowDateTime;
69: ff = fft.QuadPart;
70:
71: ff /= 10Ui64; /* convert to microseconds */
72: ff -= 11644473600000000Ui64; /* convert to unix epoch */
73:
74: tv->tv_sec = (long)(ff / 1000000Ui64);
75: tv->tv_usec = (long)(ff % 1000000Ui64);
76:
77: return 0;
78: }
79:
80: PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
81: {
82: /* Get the time, if they want it */
83: if (time_Info != NULL) {
84: getfilesystemtime(time_Info);
85: }
86: /* Get the timezone, if they want it */
87: if (timezone_Info != NULL) {
88: _tzset();
89: timezone_Info->tz_minuteswest = _timezone;
90: timezone_Info->tz_dsttime = _daylight;
91: }
92: /* And return */
93: return 0;
94: }
95:
96: PHPAPI int usleep(unsigned int useconds)
97: {
98: HANDLE timer;
99: LARGE_INTEGER due;
100:
101: due.QuadPart = -(10 * (__int64)useconds);
102:
103: timer = CreateWaitableTimer(NULL, TRUE, NULL);
104: SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
105: WaitForSingleObject(timer, INFINITE);
106: CloseHandle(timer);
107: return 0;
108: }
109:
110: PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
111: {
112: if (rqtp->tv_nsec > 999999999) {
113: /* The time interval specified 1,000,000 or more microseconds. */
114: errno = EINVAL;
115: return -1;
116: }
117: return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000 );
118: }
119:
120: #if 0 /* looks pretty ropey in here */
121: #ifdef HAVE_SETITIMER
122:
123:
124: #ifndef THREAD_SAFE
125: unsigned int proftimer, virttimer, realtimer;
126: extern LPMSG phpmsg;
127: #endif
128:
129: struct timer_msg {
130: int signal;
131: unsigned int threadid;
132: };
133:
134:
135: LPTIMECALLBACK setitimer_timeout(UINT uTimerID, UINT info, DWORD dwUser, DWORD dw1, DWORD dw2)
136: {
137: struct timer_msg *msg = (struct timer_msg *) info;
138:
139: if (msg) {
140: raise((int) msg->signal);
141: PostThreadMessage(msg->threadid,
142: WM_NOTIFY, msg->signal, 0);
143: free(msg);
144: }
145: return 0;
146: }
147:
148: PHPAPI int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
149: {
150: int timeout = value->it_value.tv_sec * 1000 + value->it_value.tv_usec;
151: int repeat = TIME_ONESHOT;
152:
153: /*make sure the message queue is initialized */
154: PeekMessage(phpmsg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
155: if (timeout > 0) {
156: struct timer_msg *msg = malloc(sizeof(struct timer_msg));
157: msg->threadid = GetCurrentThreadId();
158: if (!ovalue) {
159: repeat = TIME_PERIODIC;
160: }
161: switch (which) {
162: case ITIMER_REAL:
163: msg->signal = SIGALRM;
164: realtimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
165: break;
166: case ITIMER_VIRT:
167: msg->signal = SIGVTALRM;
168: virttimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
169: break;
170: case ITIMER_PROF:
171: msg->signal = SIGPROF;
172: proftimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
173: break;
174: default:
175: errno = EINVAL;
176: return -1;
177: break;
178: }
179: } else {
180: switch (which) {
181: case ITIMER_REAL:
182: timeKillEvent(realtimer);
183: break;
184: case ITIMER_VIRT:
185: timeKillEvent(virttimer);
186: break;
187: case ITIMER_PROF:
188: timeKillEvent(proftimer);
189: break;
190: default:
191: errno = EINVAL;
192: return -1;
193: break;
194: }
195: }
196:
197:
198: return 0;
199: }
200:
201: #endif
202: #endif
203:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>