OSDN Git Service

Implement POSIX.1-2004 Monotonic Clock.
authoryselkowitz <yselkowitz>
Tue, 10 Aug 2010 01:47:43 +0000 (01:47 +0000)
committeryselkowitz <yselkowitz>
Tue, 10 Aug 2010 01:47:43 +0000 (01:47 +0000)
* hires.h: Change hires_us to hires_ns, with nanosecond resolution.
(hires_ns::primed_ft): Remove.
(hires_ns::nsecs): New prototype.
(hires_ns::usecs): Rewrite in terms of nsecs.
(hires_ns::resolution): New prototype.
* times.cc: Change hires_us to hires_ns.
(ntod): Declare.
(systime): Remove.
(hires_ns::prime): Increase resolution to nanoseconds.
(hires_ns::nsecs): Rename usecs to nsecs to reflect increased resolution.
Remove justdelta argument.
(hires_ns::resolution): New function.
(clock_gettime): Accept CLOCK_MONOTONIC.
Use EINVAL instead of ENOSYS per POSIX.1-2004.
(clock_getres): Ditto.
(clock_setres): Use EINVAL instead of ENOSYS to conform with other
implementations.
* strace.cc (strace::microseconds): Adjust for hires_ns.
* sysconf.cc (sca): Set _SC_MONOTONIC_CLOCK to _POSIX_MONOTONIC_CLOCK.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.

winsup/cygwin/ChangeLog
winsup/cygwin/hires.h
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/strace.cc
winsup/cygwin/sysconf.cc
winsup/cygwin/times.cc

index 3a57418..db86952 100644 (file)
@@ -1,5 +1,29 @@
 2010-08-09  Yaakov Selkowitz  <yselkowitz@users.sourceforge.net>
 
+       Implement POSIX.1-2004 Monotonic Clock.
+       * hires.h: Change hires_us to hires_ns, with nanosecond resolution.
+       (hires_ns::primed_ft): Remove.
+       (hires_ns::nsecs): New prototype.
+       (hires_ns::usecs): Rewrite in terms of nsecs.
+       (hires_ns::resolution): New prototype.
+       * times.cc: Change hires_us to hires_ns.
+       (ntod): Declare.
+       (systime): Remove.
+       (hires_ns::prime): Increase resolution to nanoseconds.
+       (hires_ns::nsecs): Rename usecs to nsecs to reflect increased resolution.
+       Remove justdelta argument.
+       (hires_ns::resolution): New function.
+       (clock_gettime): Accept CLOCK_MONOTONIC.
+       Use EINVAL instead of ENOSYS per POSIX.1-2004.
+       (clock_getres): Ditto.
+       (clock_setres): Use EINVAL instead of ENOSYS to conform with other
+       implementations.
+       * strace.cc (strace::microseconds): Adjust for hires_ns.
+       * sysconf.cc (sca): Set _SC_MONOTONIC_CLOCK to _POSIX_MONOTONIC_CLOCK.
+       * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
+
+2010-08-09  Yaakov Selkowitz  <yselkowitz@users.sourceforge.net>
+
        * fhandler_proc.cc: Add /proc/filesystems virtual file.
        (format_proc_filesystems): New function.
        * mount.cc (fs_names): Move to global scope. Redefine as array
index 6a7fe8c..5f87453 100644 (file)
@@ -29,14 +29,15 @@ class hires_base
   void reset() {inited = false;}
 };
 
-class hires_us : public hires_base
+class hires_ns : public hires_base
 {
-  LARGE_INTEGER primed_ft;
   LARGE_INTEGER primed_pc;
   double freq;
   void prime ();
  public:
-  LONGLONG usecs (bool justdelta);
+  LONGLONG nsecs ();
+  LONGLONG usecs () {return nsecs () / 1000LL;}
+  LONGLONG resolution();
 };
 
 class hires_ms : public hires_base
index 9924e42..efceb53 100644 (file)
@@ -389,12 +389,13 @@ details. */
       227: Add pseudo_reloc_start, pseudo_reloc_end, image_base to per_process.
       228: CW_STRERROR added.
       229: Add mkostemp, mkostemps.
+      230: Add CLOCK_MONOTONIC.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 229
+#define CYGWIN_VERSION_API_MINOR 230
 
      /* There is also a compatibity version number associated with the
        shared memory regions.  It is incremented when incompatible
index 4670f8a..6499983 100644 (file)
@@ -74,8 +74,8 @@ strace::hello ()
 int
 strace::microseconds ()
 {
-  static hires_us now;
-  return (int) now.usecs (true);
+  static hires_ns now;
+  return (int) now.usecs ();
 }
 
 static int __stdcall
index 84aced1..4e14417 100644 (file)
@@ -165,7 +165,7 @@ static struct
   {cons, {c:IOV_MAX}},                 /*  66, _SC_IOV_MAX */
   {cons, {c:_POSIX_IPV6}},             /*  67, _SC_IPV6 */
   {cons, {c:LINE_MAX}},                        /*  68, _SC_LINE_MAX */
-  {cons, {c:-1L}},                     /*  69, _SC_MONOTONIC_CLOCK */
+  {cons, {c:_POSIX_MONOTONIC_CLOCK}},  /*  69, _SC_MONOTONIC_CLOCK */
   {cons, {c:_POSIX_RAW_SOCKETS}},      /*  70, _SC_RAW_SOCKETS */
   {cons, {c:_POSIX_READER_WRITER_LOCKS}},      /*  71, _SC_READER_WRITER_LOCKS */
   {cons, {c:_POSIX_REGEXP}},           /*  72, _SC_REGEXP */
index 3b15416..c911cfe 100644 (file)
@@ -36,6 +36,8 @@ details. */
    to handle that case.  */
 hires_ms gtod __attribute__((section (".cygwin_dll_common"), shared));
 
+hires_ns NO_COPY ntod;
+
 static inline LONGLONG
 systime_ns ()
 {
@@ -48,12 +50,6 @@ systime_ns ()
   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)
@@ -623,7 +619,7 @@ cygwin_tzset ()
 
 #define stupid_printf if (cygwin_finished_initializing) debug_printf
 void
-hires_us::prime ()
+hires_ns::prime ()
 {
   LARGE_INTEGER ifreq;
   if (!QueryPerformanceFrequency (&ifreq))
@@ -642,14 +638,13 @@ hires_us::prime ()
       return;
     }
 
-  primed_ft.QuadPart = systime ();
-  freq = (double) ((double) 1000000. / (double) ifreq.QuadPart);
+  freq = (double) ((double) 1000000000. / (double) ifreq.QuadPart);
   inited = true;
   SetThreadPriority (GetCurrentThread (), priority);
 }
 
 LONGLONG
-hires_us::usecs (bool justdelta)
+hires_ns::nsecs ()
 {
   if (!inited)
     prime ();
@@ -668,8 +663,7 @@ hires_us::usecs (bool justdelta)
 
   // FIXME: Use round() here?
   now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
-  LONGLONG res = justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
-  return res;
+  return now.QuadPart;
 }
 
 void
@@ -706,23 +700,53 @@ hires_ms::nsecs ()
 extern "C" int
 clock_gettime (clockid_t clk_id, struct timespec *tp)
 {
-  if (clk_id != CLOCK_REALTIME)
+  switch (clk_id)
     {
-      set_errno (ENOSYS);
-      return -1;
+      case CLOCK_REALTIME:
+        {
+          LONGLONG now = gtod.nsecs ();
+          if (now == (LONGLONG) -1)
+            return -1;
+          tp->tv_sec = now / NSPERSEC;
+          tp->tv_nsec = (now % NSPERSEC) * (1000000000 / NSPERSEC);
+          break;
+        }
+
+      case CLOCK_MONOTONIC:
+        {
+          LONGLONG now = ntod.nsecs ();
+          if (now == (LONGLONG) -1)
+            return -1;
+
+          tp->tv_sec = now / 1000000000;
+          tp->tv_nsec = (now % 1000000000);
+          break;
+        }
+
+      default:
+        set_errno (EINVAL);
+        return -1;
     }
 
-  LONGLONG now = gtod.nsecs ();
-  if (now == (LONGLONG) -1)
-    return -1;
-
-  tp->tv_sec = now / NSPERSEC;
-  tp->tv_nsec = (now % NSPERSEC) * (1000000000 / NSPERSEC);
   return 0;
 }
 
 static DWORD minperiod;        // FIXME: Maintain period after a fork.
 
+LONGLONG
+hires_ns::resolution()
+{
+  if (!inited)
+    prime ();
+  if (inited < 0)
+    {
+      set_errno (ENOSYS);
+      return (long long) -1;
+    }
+
+  return (LONGLONG) freq;
+}
+
 UINT
 hires_ms::resolution ()
 {
@@ -753,17 +777,29 @@ hires_ms::resolution ()
 extern "C" int
 clock_getres (clockid_t clk_id, struct timespec *tp)
 {
-  if (clk_id != CLOCK_REALTIME)
+  switch (clk_id)
     {
-      set_errno (ENOSYS);
-      return -1;
+      case CLOCK_REALTIME:
+        {
+          DWORD period = gtod.resolution ();
+          tp->tv_sec = period / 1000;
+          tp->tv_nsec = (period % 1000) * 1000000;
+          break;
+        }
+
+      case CLOCK_MONOTONIC:
+        {
+          LONGLONG period = ntod.resolution ();
+          tp->tv_sec = period / 1000000000;
+          tp->tv_nsec = period % 1000000000;
+          break;
+        }
+
+      default:
+        set_errno (EINVAL);
+        return -1;
     }
 
-  DWORD period = gtod.resolution ();
-
-  tp->tv_sec = period / 1000;
-  tp->tv_nsec = (period % 1000) * 1000000;
-
   return 0;
 }
 
@@ -773,7 +809,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
   static NO_COPY bool period_set;
   if (clk_id != CLOCK_REALTIME)
     {
-      set_errno (ENOSYS);
+      set_errno (EINVAL);
       return -1;
     }