Return to time.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / win32 |
1.1 misho 1:
2: /*****************************************************************************
3: * *
4: * DH_TIME.C *
5: * *
6: * Freely redistributable and modifiable. Use at your own risk. *
7: * *
8: * Copyright 1994 The Downhill Project *
9: *
10: * Modified by Shane Caraveo for use with PHP
11: *
12: *****************************************************************************/
13:
1.1.1.2 ! misho 14: /* $Id$ */
1.1 misho 15:
16: /**
17: *
18: * 04-Feb-2001
19: * - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi>
20: * Improves accuracy of msec
21: */
22:
23: /* Include stuff ************************************************************ */
24:
25: #include <config.w32.h>
26:
27: #include "time.h"
28: #include "unistd.h"
29: #include "signal.h"
30: #include <windows.h>
31: #include <winbase.h>
32: #include <mmsystem.h>
33: #include <errno.h>
34: #include "php_win32_globals.h"
35:
36: int getfilesystemtime(struct timeval *time_Info)
37: {
38: FILETIME ft;
39: __int64 ff;
40:
41: GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */
42: /* resolution seems to be 0.01 sec */
43: ff = *(__int64*)(&ft);
44: time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600);
45: time_Info->tv_usec = (int)(ff % 10000000)/10;
46: return 0;
47: }
48:
49:
50:
51: PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
52: {
53: __int64 timer;
54: LARGE_INTEGER li;
55: BOOL b;
56: double dt;
57: TSRMLS_FETCH();
58:
59: /* Get the time, if they want it */
60: if (time_Info != NULL) {
61: if (PW32G(starttime).tv_sec == 0) {
62: b = QueryPerformanceFrequency(&li);
63: if (!b) {
64: PW32G(starttime).tv_sec = -1;
65: }
66: else {
67: PW32G(freq) = li.QuadPart;
68: b = QueryPerformanceCounter(&li);
69: if (!b) {
70: PW32G(starttime).tv_sec = -1;
71: }
72: else {
73: getfilesystemtime(&PW32G(starttime));
74: timer = li.QuadPart;
75: dt = (double)timer/PW32G(freq);
76: PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
77: if (PW32G(starttime).tv_usec < 0) {
78: PW32G(starttime).tv_usec += 1000000;
79: --PW32G(starttime).tv_sec;
80: }
81: PW32G(starttime).tv_sec -= (int)dt;
82: }
83: }
84: }
85: if (PW32G(starttime).tv_sec > 0) {
86: b = QueryPerformanceCounter(&li);
87: if (!b) {
88: PW32G(starttime).tv_sec = -1;
89: }
90: else {
91: timer = li.QuadPart;
92: if (timer < PW32G(lasttime)) {
93: getfilesystemtime(time_Info);
94: dt = (double)timer/PW32G(freq);
95: PW32G(starttime) = *time_Info;
96: PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
97: if (PW32G(starttime).tv_usec < 0) {
98: PW32G(starttime).tv_usec += 1000000;
99: --PW32G(starttime).tv_sec;
100: }
101: PW32G(starttime).tv_sec -= (int)dt;
102: }
103: else {
104: PW32G(lasttime) = timer;
105: dt = (double)timer/PW32G(freq);
106: time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt;
107: time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000);
108: if (time_Info->tv_usec >= 1000000) {
109: time_Info->tv_usec -= 1000000;
110: ++time_Info->tv_sec;
111: }
112: }
113: }
114: }
115: if (PW32G(starttime).tv_sec < 0) {
116: getfilesystemtime(time_Info);
117: }
118:
119: }
120: /* Get the timezone, if they want it */
121: if (timezone_Info != NULL) {
122: _tzset();
123: timezone_Info->tz_minuteswest = _timezone;
124: timezone_Info->tz_dsttime = _daylight;
125: }
126: /* And return */
127: return 0;
128: }
129:
130: PHPAPI int usleep(unsigned int useconds)
131: {
132: HANDLE timer;
133: LARGE_INTEGER due;
134:
135: due.QuadPart = -(10 * (__int64)useconds);
136:
137: timer = CreateWaitableTimer(NULL, TRUE, NULL);
138: SetWaitableTimer(timer, &due, 0, NULL, NULL, 0);
139: WaitForSingleObject(timer, INFINITE);
140: CloseHandle(timer);
141: return 0;
142: }
143:
144: PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp )
145: {
146: if (rqtp->tv_nsec > 999999999) {
147: /* The time interval specified 1,000,000 or more microseconds. */
148: errno = EINVAL;
149: return -1;
150: }
151: return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000 );
152: }
153:
154: #if 0 /* looks pretty ropey in here */
155: #ifdef HAVE_SETITIMER
156:
157:
158: #ifndef THREAD_SAFE
159: unsigned int proftimer, virttimer, realtimer;
160: extern LPMSG phpmsg;
161: #endif
162:
163: struct timer_msg {
164: int signal;
165: unsigned int threadid;
166: };
167:
168:
169: LPTIMECALLBACK setitimer_timeout(UINT uTimerID, UINT info, DWORD dwUser, DWORD dw1, DWORD dw2)
170: {
171: struct timer_msg *msg = (struct timer_msg *) info;
172:
173: if (msg) {
174: raise((int) msg->signal);
175: PostThreadMessage(msg->threadid,
176: WM_NOTIFY, msg->signal, 0);
177: free(msg);
178: }
179: return 0;
180: }
181:
182: PHPAPI int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
183: {
184: int timeout = value->it_value.tv_sec * 1000 + value->it_value.tv_usec;
185: int repeat = TIME_ONESHOT;
186:
187: /*make sure the message queue is initialized */
188: PeekMessage(phpmsg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
189: if (timeout > 0) {
190: struct timer_msg *msg = malloc(sizeof(struct timer_msg));
191: msg->threadid = GetCurrentThreadId();
192: if (!ovalue) {
193: repeat = TIME_PERIODIC;
194: }
195: switch (which) {
196: case ITIMER_REAL:
197: msg->signal = SIGALRM;
198: realtimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
199: break;
200: case ITIMER_VIRT:
201: msg->signal = SIGVTALRM;
202: virttimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
203: break;
204: case ITIMER_PROF:
205: msg->signal = SIGPROF;
206: proftimer = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
207: break;
208: default:
209: errno = EINVAL;
210: return -1;
211: break;
212: }
213: } else {
214: switch (which) {
215: case ITIMER_REAL:
216: timeKillEvent(realtimer);
217: break;
218: case ITIMER_VIRT:
219: timeKillEvent(virttimer);
220: break;
221: case ITIMER_PROF:
222: timeKillEvent(proftimer);
223: break;
224: default:
225: errno = EINVAL;
226: return -1;
227: break;
228: }
229: }
230:
231:
232: return 0;
233: }
234:
235: #endif
236: #endif
237: