diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 1e6a781..eb40d05 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1282,6 +1282,22 @@ fhandler_base::utimens_fs (const struct timespec *tvp) struct timespec tmp[2]; bool closeit = false; + clock_gettime (CLOCK_REALTIME, &timeofday); + if (!tvp) + tmp[1] = tmp[0] = timeofday; + else + { + if ((tvp[0].tv_nsec < UTIME_NOW || tvp[0].tv_nsec > 999999999L) + || (tvp[1].tv_nsec < UTIME_NOW || tvp[1].tv_nsec > 999999999L)) + { + set_errno (EINVAL); + return -1; + } + tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0]; + tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1]; + } + debug_printf ("incoming lastaccess %08x %08x", tmp[0].tv_sec, tmp[0].tv_nsec); + if (!get_handle ()) { query_open (query_write_attributes); @@ -1301,25 +1317,6 @@ fhandler_base::utimens_fs (const struct timespec *tvp) closeit = true; } - gettimeofday (reinterpret_cast (&timeofday), 0); - timeofday.tv_nsec *= 1000; - if (!tvp) - tmp[1] = tmp[0] = timeofday; - else - { - if ((tvp[0].tv_nsec < UTIME_NOW || tvp[0].tv_nsec > 999999999L) - || (tvp[1].tv_nsec < UTIME_NOW || tvp[1].tv_nsec > 999999999L)) - { - if (closeit) - close_fs (); - set_errno (EINVAL); - return -1; - } - tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0]; - tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1]; - } - debug_printf ("incoming lastaccess %08x %08x", tmp[0].tv_sec, tmp[0].tv_nsec); - IO_STATUS_BLOCK io; FILE_BASIC_INFORMATION fbi; diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h index 3c7bd27..e91df06 100644 --- a/winsup/cygwin/hires.h +++ b/winsup/cygwin/hires.h @@ -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; diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index f89a72a..ceb6a28 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -26,7 +26,10 @@ details. */ #include "ntdll.h" #define FACTOR (0x19db1ded53e8000LL) -#define NSPERSEC 10000000LL +#define NSPERMS 10000LL /* 100ns ticks per millisecond */ +#define MILLION 1000000LL /* microseconds per second */ +#define NSPERSEC 10000000LL /* 100ns ticks per second */ +#define BILLION 1000000000LL /* nanoseconds per second */ static inline LONGLONG systime () @@ -41,6 +44,18 @@ systime () return x.QuadPart; } +static inline LONGLONG +systime_ns () +{ + LARGE_INTEGER x; + FILETIME ft; + GetSystemTimeAsFileTime (&ft); + x.HighPart = ft.dwHighDateTime; + x.LowPart = ft.dwLowDateTime; + x.QuadPart -= FACTOR; /* Add conversion factor for UNIX vs. Windows base time */ + return x.QuadPart; +} + /* Cygwin internal */ static unsigned long long __stdcall __to_clock_t (FILETIME *src, int flag) @@ -154,8 +169,8 @@ gettimeofday (struct timeval *tv, void *tzvp) if (now == (LONGLONG) -1) return -1; - tv->tv_sec = now / 1000000; - tv->tv_usec = now % 1000000; + tv->tv_sec = now / MILLION; + tv->tv_usec = now % MILLION; if (tz != NULL) { @@ -191,7 +206,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 / (BILLION / NSPERSEC) + FACTOR; out->dwHighDateTime = x >> 32; out->dwLowDateTime = x; } @@ -202,7 +217,7 @@ void __stdcall timeval_to_filetime (const struct timeval *time_in, FILETIME *out) { long long x = time_in->tv_sec * NSPERSEC + - time_in->tv_usec * (NSPERSEC/1000000) + FACTOR; + time_in->tv_usec * (NSPERSEC / MILLION) + FACTOR; out->dwHighDateTime = x >> 32; out->dwLowDateTime = x; } @@ -228,15 +243,15 @@ timeval_to_timespec (const struct timeval *tvp, struct timespec *tmp) tmp[0].tv_nsec = tvp[0].tv_usec * 1000; if (tmp[0].tv_nsec < 0) tmp[0].tv_nsec = 0; - else if (tmp[0].tv_nsec > 999999999) - tmp[0].tv_nsec = 999999999; + else if (tmp[0].tv_nsec >= BILLION) + tmp[0].tv_nsec = BILLION - 1; tmp[1].tv_sec = tvp[1].tv_sec; tmp[1].tv_nsec = tvp[1].tv_usec * 1000; if (tmp[1].tv_nsec < 0) tmp[1].tv_nsec = 0; - else if (tmp[1].tv_nsec > 999999999) - tmp[1].tv_nsec = 999999999; + else if (tmp[1].tv_nsec >= BILLION) + tmp[1].tv_nsec = BILLION - 1; return tmp; } @@ -631,7 +646,7 @@ hires_us::prime () } primed_ft.QuadPart = systime (); - freq = (double) ((double) 1000000. / (double) ifreq.QuadPart); + freq = (double) ((double) (1e6) / (double) ifreq.QuadPart); inited = true; SetThreadPriority (GetCurrentThread (), priority); } @@ -667,7 +682,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 ()) * NSPERMS); inited = true; SetThreadPriority (GetCurrentThread (), priority); } @@ -675,18 +690,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 ()) * NSPERMS); + if (res < (t - 40 * NSPERMS)) { inited = false; prime (); - res = initime_us + (((LONGLONG) timeGetTime ()) * 1000LL); + res = initime_ns + (((LONGLONG) timeGetTime ()) * NSPERMS); } return res; } @@ -700,12 +715,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) * (BILLION / NSPERSEC); return 0; } @@ -750,7 +765,7 @@ clock_getres (clockid_t clk_id, struct timespec *tp) DWORD period = gtod.resolution (); tp->tv_sec = period / 1000; - tp->tv_nsec = (period % 1000) * 1000000; + tp->tv_nsec = (period % 1000) * MILLION; return 0; } @@ -768,7 +783,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp) if (period_set) timeEndPeriod (minperiod); - DWORD period = (tp->tv_sec * 1000) + ((tp->tv_nsec) / 1000000); + DWORD period = (tp->tv_sec * 1000) + ((tp->tv_nsec) / MILLION); if (timeBeginPeriod (period)) { -- 1.6.5.rc1