This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] POSIX monotonic clock


On Mon, 2010-08-02 at 20:37 -0400, Christopher Faylor wrote:
> But that changes the sense of the errno.  EINVAL would indicate an unsupported
> argument.  At least some of the cases fail because of an unimplemented NT
> function call, e.g., ENOSYS.  Regardless of what POSIX says, I think that ENOSYS
> is ok, in at least some cases, for Cygwin since I believe QueryPerformanceCounter
> doesn't work on NT3.5 and NT4.

Thanks for the review.  This patch uses ENOSYS for QueryPerformance*
failures and EINVAL for unsupported/illegal CLOCK_* arguments.  If this
is OK, then I'll proceed with the newlib patch, which needs to be
applied first.


Yaakov

2010-08-02  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.

Index: hires.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/hires.h,v
retrieving revision 1.15
diff -u -r1.15 hires.h
--- hires.h	26 May 2010 14:48:17 -0000	1.15
+++ hires.h	3 Aug 2010 05:40:41 -0000
@@ -29,14 +29,15 @@
   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: strace.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/strace.cc,v
retrieving revision 1.68
diff -u -r1.68 strace.cc
--- strace.cc	18 May 2010 14:30:51 -0000	1.68
+++ strace.cc	3 Aug 2010 05:40:41 -0000
@@ -74,8 +74,8 @@
 int
 strace::microseconds ()
 {
-  static hires_us now;
-  return (int) now.usecs (true);
+  static hires_ns now;
+  return (int) now.usecs ();
 }
 
 static int __stdcall
Index: sysconf.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/sysconf.cc,v
retrieving revision 1.53
diff -u -r1.53 sysconf.cc
--- sysconf.cc	12 Nov 2009 14:40:47 -0000	1.53
+++ sysconf.cc	3 Aug 2010 05:40:41 -0000
@@ -165,7 +165,7 @@
   {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: times.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/times.cc,v
retrieving revision 1.102
diff -u -r1.102 times.cc
--- times.cc	12 Jun 2010 16:34:26 -0000	1.102
+++ times.cc	3 Aug 2010 05:40:41 -0000
@@ -36,6 +36,8 @@
    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 @@
   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 @@
 
 #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 @@
       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 @@
 
   // 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 @@
 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 @@
 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 @@
   static NO_COPY bool period_set;
   if (clk_id != CLOCK_REALTIME)
     {
-      set_errno (ENOSYS);
+      set_errno (EINVAL);
       return -1;
     }
 
Index: include/cygwin/version.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v
retrieving revision 1.319
diff -u -r1.319 version.h
--- include/cygwin/version.h	19 Jul 2010 18:22:40 -0000	1.319
+++ include/cygwin/version.h	3 Aug 2010 05:40:41 -0000
@@ -389,12 +389,13 @@
       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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]