Improve clock_gettime and utimensat resolution.
* hires.h (hires_ms): Change initime_us to initime_ns, with 10x more resolution. (hires_ms::nsecs): New prototype. (hires_ms::usecs, hires_ms::msecs, hires_ms::uptime): Adjust. * times.cc (systime_ns): New helper function. (hires_ms::prime): Use it for more resolution. (hires_ms::usecs): Change to... (hires_ms::nsecs): ...with more resolution. (clock_gettime): Use more resolution. (systime): Rewrite in terms of systime_ns. (timespec_to_filetime): Rewrite math to reflect true operation. * fhandler_disk_file.cc (utimens_fs): Use higher resolution.
This commit is contained in:
		@@ -1,3 +1,18 @@
 | 
			
		||||
2009-10-13  Eric Blake  <ebb9@byu.net>
 | 
			
		||||
 | 
			
		||||
	* hires.h (hires_ms): Change initime_us to initime_ns, with 10x
 | 
			
		||||
	more resolution.
 | 
			
		||||
	(hires_ms::nsecs): New prototype.
 | 
			
		||||
	(hires_ms::usecs, hires_ms::msecs, hires_ms::uptime): Adjust.
 | 
			
		||||
	* times.cc (systime_ns): New helper function.
 | 
			
		||||
	(hires_ms::prime): Use it for more resolution.
 | 
			
		||||
	(hires_ms::usecs): Change to...
 | 
			
		||||
	(hires_ms::nsecs): ...with more resolution.
 | 
			
		||||
	(clock_gettime): Use more resolution.
 | 
			
		||||
	(systime): Rewrite in terms of systime_ns.
 | 
			
		||||
	(timespec_to_filetime): Rewrite math to reflect true operation.
 | 
			
		||||
	* fhandler_disk_file.cc (utimens_fs): Use higher resolution.
 | 
			
		||||
 | 
			
		||||
2009-10-12  Corinna Vinschen  <corinna@vinschen.de>
 | 
			
		||||
 | 
			
		||||
	* external.cc (cygwin_internal): Return 0 in CW_SET_DOS_FILE_WARNING
 | 
			
		||||
 
 | 
			
		||||
@@ -1306,8 +1306,7 @@ fhandler_base::utimens_fs (const struct timespec *tvp)
 | 
			
		||||
      closeit = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gettimeofday (reinterpret_cast<struct timeval *> (&timeofday), 0);
 | 
			
		||||
  timeofday.tv_nsec *= 1000;
 | 
			
		||||
  clock_gettime (CLOCK_REALTIME, &timeofday);
 | 
			
		||||
  if (!tvp)
 | 
			
		||||
    tmp[1] = tmp[0] = timeofday;
 | 
			
		||||
  else
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* hires.h: Definitions for hires clock calculations
 | 
			
		||||
 | 
			
		||||
   Copyright 2002, 2003, 2004, 2005 Red Hat, Inc.
 | 
			
		||||
   Copyright 2002, 2003, 2004, 2005, 2009 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
This file is part of Cygwin.
 | 
			
		||||
 | 
			
		||||
@@ -39,14 +39,15 @@ class hires_us : hires_base
 | 
			
		||||
 | 
			
		||||
class hires_ms : hires_base
 | 
			
		||||
{
 | 
			
		||||
  LONGLONG initime_us;
 | 
			
		||||
  LONGLONG initime_ns;
 | 
			
		||||
  void prime ();
 | 
			
		||||
 public:
 | 
			
		||||
  LONGLONG usecs ();
 | 
			
		||||
  LONGLONG msecs () {return usecs () / 1000LL;}
 | 
			
		||||
  LONGLONG nsecs ();
 | 
			
		||||
  LONGLONG usecs () {return nsecs () / 10LL;}
 | 
			
		||||
  LONGLONG msecs () {return nsecs () / 10000LL;}
 | 
			
		||||
  UINT dmsecs () { return timeGetTime (); }
 | 
			
		||||
  UINT resolution ();
 | 
			
		||||
  LONGLONG uptime () {return (usecs () - initime_us) / 1000LL;}
 | 
			
		||||
  LONGLONG uptime () {return (nsecs () - initime_ns) / 10000LL;}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern hires_ms gtod;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ details. */
 | 
			
		||||
#define NSPERSEC 10000000LL
 | 
			
		||||
 | 
			
		||||
static inline LONGLONG
 | 
			
		||||
systime ()
 | 
			
		||||
systime_ns ()
 | 
			
		||||
{
 | 
			
		||||
  LARGE_INTEGER x;
 | 
			
		||||
  FILETIME ft;
 | 
			
		||||
@@ -37,10 +37,15 @@ systime ()
 | 
			
		||||
  x.HighPart = ft.dwHighDateTime;
 | 
			
		||||
  x.LowPart = ft.dwLowDateTime;
 | 
			
		||||
  x.QuadPart -= FACTOR;		/* Add conversion factor for UNIX vs. Windows base time */
 | 
			
		||||
  x.QuadPart /= 10;		/* Convert to microseconds */
 | 
			
		||||
  return x.QuadPart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline LONGLONG
 | 
			
		||||
systime ()
 | 
			
		||||
{
 | 
			
		||||
  return systime_ns () / 10;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Cygwin internal */
 | 
			
		||||
static unsigned long long __stdcall
 | 
			
		||||
__to_clock_t (FILETIME *src, int flag)
 | 
			
		||||
@@ -191,7 +196,7 @@ timespec_to_filetime (const struct timespec *time_in, FILETIME *out)
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      long long x = time_in->tv_sec * NSPERSEC +
 | 
			
		||||
			    time_in->tv_nsec / (NSPERSEC/100000) + FACTOR;
 | 
			
		||||
			    time_in->tv_nsec / (1000000000/NSPERSEC) + FACTOR;
 | 
			
		||||
      out->dwHighDateTime = x >> 32;
 | 
			
		||||
      out->dwLowDateTime = x;
 | 
			
		||||
    }
 | 
			
		||||
@@ -667,7 +672,7 @@ hires_ms::prime ()
 | 
			
		||||
    {
 | 
			
		||||
      int priority = GetThreadPriority (GetCurrentThread ());
 | 
			
		||||
      SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
 | 
			
		||||
      initime_us = systime () - (((LONGLONG) timeGetTime ()) * 1000LL);
 | 
			
		||||
      initime_ns = systime_ns () - (((LONGLONG) timeGetTime ()) * 10000LL);
 | 
			
		||||
      inited = true;
 | 
			
		||||
      SetThreadPriority (GetCurrentThread (), priority);
 | 
			
		||||
    }
 | 
			
		||||
@@ -675,18 +680,18 @@ hires_ms::prime ()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LONGLONG
 | 
			
		||||
hires_ms::usecs ()
 | 
			
		||||
hires_ms::nsecs ()
 | 
			
		||||
{
 | 
			
		||||
  if (!inited)
 | 
			
		||||
    prime ();
 | 
			
		||||
 | 
			
		||||
  LONGLONG t = systime ();
 | 
			
		||||
  LONGLONG res = initime_us + (((LONGLONG) timeGetTime ()) * 1000LL);
 | 
			
		||||
  if (res < (t - 40000LL))
 | 
			
		||||
  LONGLONG t = systime_ns ();
 | 
			
		||||
  LONGLONG res = initime_ns + (((LONGLONG) timeGetTime ()) * 10000LL);
 | 
			
		||||
  if (res < (t - 40 * 10000LL))
 | 
			
		||||
    {
 | 
			
		||||
      inited = false;
 | 
			
		||||
      prime ();
 | 
			
		||||
      res = initime_us + (((LONGLONG) timeGetTime ()) * 1000LL);
 | 
			
		||||
      res = initime_ns + (((LONGLONG) timeGetTime ()) * 10000LL);
 | 
			
		||||
    }
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
@@ -700,12 +705,12 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  LONGLONG now = gtod.usecs ();
 | 
			
		||||
  LONGLONG now = gtod.nsecs ();
 | 
			
		||||
  if (now == (LONGLONG) -1)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  tp->tv_sec = now / 1000000;
 | 
			
		||||
  tp->tv_nsec = (now % 1000000) * 1000;
 | 
			
		||||
  tp->tv_sec = now / NSPERSEC;
 | 
			
		||||
  tp->tv_nsec = (now % NSPERSEC) * (1000000000 / NSPERSEC);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user