File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / win32 / time.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:32:15 2013 UTC (10 years, 11 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29p0, v5_4_29, v5_4_20p0, v5_4_20, v5_4_17, HEAD
5.4.17

    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>