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:
Eric Blake 2009-10-13 02:26:33 +00:00
parent 2fc007681e
commit b8a35083c6
4 changed files with 39 additions and 19 deletions

View File

@ -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> 2009-10-12 Corinna Vinschen <corinna@vinschen.de>
* external.cc (cygwin_internal): Return 0 in CW_SET_DOS_FILE_WARNING * external.cc (cygwin_internal): Return 0 in CW_SET_DOS_FILE_WARNING

View File

@ -1306,8 +1306,7 @@ fhandler_base::utimens_fs (const struct timespec *tvp)
closeit = true; closeit = true;
} }
gettimeofday (reinterpret_cast<struct timeval *> (&timeofday), 0); clock_gettime (CLOCK_REALTIME, &timeofday);
timeofday.tv_nsec *= 1000;
if (!tvp) if (!tvp)
tmp[1] = tmp[0] = timeofday; tmp[1] = tmp[0] = timeofday;
else else

View File

@ -1,6 +1,6 @@
/* hires.h: Definitions for hires clock calculations /* 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. This file is part of Cygwin.
@ -39,14 +39,15 @@ class hires_us : hires_base
class hires_ms : hires_base class hires_ms : hires_base
{ {
LONGLONG initime_us; LONGLONG initime_ns;
void prime (); void prime ();
public: public:
LONGLONG usecs (); LONGLONG nsecs ();
LONGLONG msecs () {return usecs () / 1000LL;} LONGLONG usecs () {return nsecs () / 10LL;}
LONGLONG msecs () {return nsecs () / 10000LL;}
UINT dmsecs () { return timeGetTime (); } UINT dmsecs () { return timeGetTime (); }
UINT resolution (); UINT resolution ();
LONGLONG uptime () {return (usecs () - initime_us) / 1000LL;} LONGLONG uptime () {return (nsecs () - initime_ns) / 10000LL;}
}; };
extern hires_ms gtod; extern hires_ms gtod;

View File

@ -29,7 +29,7 @@ details. */
#define NSPERSEC 10000000LL #define NSPERSEC 10000000LL
static inline LONGLONG static inline LONGLONG
systime () systime_ns ()
{ {
LARGE_INTEGER x; LARGE_INTEGER x;
FILETIME ft; FILETIME ft;
@ -37,10 +37,15 @@ systime ()
x.HighPart = ft.dwHighDateTime; x.HighPart = ft.dwHighDateTime;
x.LowPart = ft.dwLowDateTime; x.LowPart = ft.dwLowDateTime;
x.QuadPart -= FACTOR; /* Add conversion factor for UNIX vs. Windows base time */ x.QuadPart -= FACTOR; /* Add conversion factor for UNIX vs. Windows base time */
x.QuadPart /= 10; /* Convert to microseconds */
return x.QuadPart; return x.QuadPart;
} }
static inline LONGLONG
systime ()
{
return systime_ns () / 10;
}
/* Cygwin internal */ /* Cygwin internal */
static unsigned long long __stdcall static unsigned long long __stdcall
__to_clock_t (FILETIME *src, int flag) __to_clock_t (FILETIME *src, int flag)
@ -191,7 +196,7 @@ timespec_to_filetime (const struct timespec *time_in, FILETIME *out)
else else
{ {
long long x = time_in->tv_sec * NSPERSEC + 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->dwHighDateTime = x >> 32;
out->dwLowDateTime = x; out->dwLowDateTime = x;
} }
@ -667,7 +672,7 @@ hires_ms::prime ()
{ {
int priority = GetThreadPriority (GetCurrentThread ()); int priority = GetThreadPriority (GetCurrentThread ());
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
initime_us = systime () - (((LONGLONG) timeGetTime ()) * 1000LL); initime_ns = systime_ns () - (((LONGLONG) timeGetTime ()) * 10000LL);
inited = true; inited = true;
SetThreadPriority (GetCurrentThread (), priority); SetThreadPriority (GetCurrentThread (), priority);
} }
@ -675,18 +680,18 @@ hires_ms::prime ()
} }
LONGLONG LONGLONG
hires_ms::usecs () hires_ms::nsecs ()
{ {
if (!inited) if (!inited)
prime (); prime ();
LONGLONG t = systime (); LONGLONG t = systime_ns ();
LONGLONG res = initime_us + (((LONGLONG) timeGetTime ()) * 1000LL); LONGLONG res = initime_ns + (((LONGLONG) timeGetTime ()) * 10000LL);
if (res < (t - 40000LL)) if (res < (t - 40 * 10000LL))
{ {
inited = false; inited = false;
prime (); prime ();
res = initime_us + (((LONGLONG) timeGetTime ()) * 1000LL); res = initime_ns + (((LONGLONG) timeGetTime ()) * 10000LL);
} }
return res; return res;
} }
@ -700,12 +705,12 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
return -1; return -1;
} }
LONGLONG now = gtod.usecs (); LONGLONG now = gtod.nsecs ();
if (now == (LONGLONG) -1) if (now == (LONGLONG) -1)
return -1; return -1;
tp->tv_sec = now / 1000000; tp->tv_sec = now / NSPERSEC;
tp->tv_nsec = (now % 1000000) * 1000; tp->tv_nsec = (now % NSPERSEC) * (1000000000 / NSPERSEC);
return 0; return 0;
} }