Annotation of embedaddon/php/win32/time.c, revision 1.1.1.3
1.1 misho 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:
1.1.1.2 misho 13: /* $Id$ */
1.1 misho 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:
1.1.1.3 ! misho 28: typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
! 29:
! 30: static MyGetSystemTimeAsFileTime get_time_func(void)
1.1 misho 31: {
1.1.1.3 ! misho 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: }
1.1 misho 44:
1.1.1.3 ! misho 45: return timefunc;
1.1 misho 46: }
47:
1.1.1.3 ! misho 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: }
1.1 misho 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) {
1.1.1.3 ! misho 84: getfilesystemtime(time_Info);
1.1 misho 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>