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..573c4c0 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -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; } -- 1.6.5.rc1