RE: [PHP-CVS] cvs: php4 /win32 time.c
| From: | James Moore | Date: | Sun, 04 Feb 2001 16:09:59 +0000 |
| Subject: | RE: [PHP-CVS] cvs: php4 /win32 time.c | ||
| References: | 1 | Groups: | php.cvs php.dev |
| Request: | Send a blank email to php-dev+get-45728@lists.php.net to get a copy of this message | ||
This patch reduces accuracy to milliseconds rather than microseconds but the
results are actaully accurate rather than before where the time was
collected in two function calls (so seconds would be out of sync with the
number of microseconds). Some acuraccy has been lost but the function
actually works now. Ill look and see if theres a way to make it as accurate
as the *nix version.
James
> -----Original Message-----
> From: James Moore [mailto:James@phpuk.org]
> Sent: 04 February 2001 15:53
> To: php-cvs@lists.php.net
> Subject: [PHP-CVS] cvs: php4 /win32 time.c
>
>
> jmoore Sun Feb 4 07:52:33 2001 EDT
>
> Modified files:
> /php4/win32 time.c
> Log:
> Fix for time.c under win32. Patch By: "Vanhanen, Reijo"
> <Reijo.Vanhanen@helsoft.fi>
>
> @- microtime under windows now returns accurate values (James)
>
>
>
> Index: php4/win32/time.c
> diff -u php4/win32/time.c:1.4 php4/win32/time.c:1.5
> --- php4/win32/time.c:1.4 Wed Jun 16 10:06:53 1999
> +++ php4/win32/time.c Sun Feb 4 07:52:32 2001
> @@ -11,7 +11,15 @@
> *
>
> ******************************************************************
> ***********/
>
> +/* $Id: time.c,v 1.5 2001/02/04 15:52:32 jmoore Exp $ */
>
> + /**
> + *
> + * 04-Feb-2001
> + * - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi>
> + * Improves accuracy of msec
> + */
> +
> /* Include stuff
> ************************************************************ */
>
> #include "time.h"
> @@ -21,22 +29,92 @@
> #include <mmsystem.h>
> #include <errno.h>
>
> +int getfilesystemtime(struct timeval *time_Info)
> +{
> +FILETIME ft;
> +__int64 ff;
> +
> + GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */
> + /* resolution seems to be
> 0.01 sec */
> + ff = *(__int64*)(&ft);
> + time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600);
> + time_Info->tv_usec = (int)(ff % 10000000)/10;
> + return 0;
> +}
> +
> +
> +
> int gettimeofday(struct timeval *time_Info, struct timezone
> *timezone_Info)
> {
> - _int64 mstimer, freq;
> +
> + static struct timeval starttime = {0, 0};
> + static __int64 lasttime = 0;
> + static __int64 freq = 0;
> + __int64 timer;
> + LARGE_INTEGER li;
> + BOOL b;
> + double dt;
> +
> /* Get the time, if they want it */
> if (time_Info != NULL) {
> - time_Info->tv_sec = time(NULL);
> - /* get ticks-per-second of the performance counter
> - Note the necessary typecast to a LARGE_INTEGER structure
> - */
> - if (!QueryPerformanceFrequency((LARGE_INTEGER *) & freq)) {
> - time_Info->tv_usec = 0;
> - } else {
> - QueryPerformanceCounter((LARGE_INTEGER *) &
> mstimer);
> - mstimer = (__int64) (mstimer * .8);
> - time_Info->tv_usec = (long) (mstimer % 0x0FFFFFFF);
> - }
> + if (starttime.tv_sec == 0) {
> + b = QueryPerformanceFrequency(&li);
> + if (!b) {
> + starttime.tv_sec = -1;
> + }
> + else {
> + freq = li.QuadPart;
> + b = QueryPerformanceCounter(&li);
> + if (!b) {
> + starttime.tv_sec = -1;
> + }
> + else {
> + getfilesystemtime(&starttime);
> + timer = li.QuadPart;
> + dt = (double)timer/freq;
> + starttime.tv_usec -= (int)((dt-(int)dt)*1000000);
> + if (starttime.tv_usec < 0) {
> + starttime.tv_usec += 1000000;
> + --starttime.tv_sec;
> + }
> + starttime.tv_sec -= (int)dt;
> + }
> + }
> + }
> + if (starttime.tv_sec > 0) {
> + b = QueryPerformanceCounter(&li);
> + if (!b) {
> + starttime.tv_sec = -1;
> + }
> + else {
> + timer = li.QuadPart;
> + if (timer < lasttime) {
> + getfilesystemtime(time_Info);
> + dt = (double)timer/freq;
> + starttime = *time_Info;
> + starttime.tv_usec -= (int)((dt-(int)dt)*1000000);
> + if (starttime.tv_usec < 0) {
> + starttime.tv_usec += 1000000;
> + --starttime.tv_sec;
> + }
> + starttime.tv_sec -= (int)dt;
> + }
> + else {
> + lasttime = timer;
> + dt = (double)timer/freq;
> + time_Info->tv_sec = starttime.tv_sec + (int)dt;
> + time_Info->tv_usec = starttime.tv_usec +
> (int)((dt-(int)dt)*1000000);
> + if (time_Info->tv_usec > 1000000) {
> + time_Info->tv_usec -= 1000000;
> + ++time_Info->tv_sec;
> + }
> + }
> + }
> + }
> + if (starttime.tv_sec < 0) {
> + getfilesystemtime(time_Info);
> + }
> +
> }
> /* Get the timezone, if they want it */
> if (timezone_Info != NULL) {
> @@ -52,21 +130,32 @@
> /* this usleep isnt exactly accurate but should do ok */
> void usleep(unsigned int useconds)
> {
> - __int64 mstimer, freq;
> - long now, then;
> - if (QueryPerformanceFrequency((LARGE_INTEGER *) & freq)) {
> - QueryPerformanceCounter((LARGE_INTEGER *) & mstimer);
> - now = (long) (((__int64) (mstimer * .8)) % 0x0FFFFFFF);
> - then = now + useconds;
> - while (now < then) {
> - QueryPerformanceCounter((LARGE_INTEGER *) &
> mstimer);
> - now = (long) (((__int64) (mstimer * .8)) %
> 0x0FFFFFFF);
> - }
> - } else {
> - /*workaround for systems without performance counter
> - this is actualy a millisecond sleep */
> - Sleep((int) (useconds / 1000));
> - }
> +struct timeval tnow, tthen, t0;
> +
> + gettimeofday(&tthen, NULL);
> + t0 = tthen;
> + tthen.tv_usec += useconds;
> + while (tthen.tv_usec > 1000000) {
> + tthen.tv_usec -= 1000000;
> + tthen.tv_sec++;
> + }
> +
> + if (useconds > 10000) {
> + useconds -= 10000;
> + Sleep(useconds/1000);
> + }
> +
> + while (1) {
> + gettimeofday(&tnow, NULL);
> + if (tnow.tv_sec > tthen.tv_sec) {
> + break;
> + }
> + if (tnow.tv_sec == tthen.tv_sec) {
> + if (tnow.tv_usec > tthen.tv_usec) {
> + break;
> + }
> + }
> + }
> }
>
>
>
>
>
> --
> PHP CVS Mailing List (http://www.php.net/)
> To unsubscribe, e-mail: php-cvs-unsubscribe@lists.php.net
> For additional commands, e-mail: php-cvs-help@lists.php.net
> To contact the list administrators, e-mail: php-list-admin@lists.php.net