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>
* 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;
}
gettimeofday (reinterpret_cast<struct timeval *> (&timeofday), 0);
timeofday.tv_nsec *= 1000;
clock_gettime (CLOCK_REALTIME, &timeofday);
if (!tvp)
tmp[1] = tmp[0] = timeofday;
else

View File

@ -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;

View File

@ -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;
}