OSDN Git Service

* signal.cc (nanosleep): Improve test for valid values. Round delay up to
authorcgf <cgf>
Sun, 7 Sep 2003 05:18:01 +0000 (05:18 +0000)
committercgf <cgf>
Sun, 7 Sep 2003 05:18:01 +0000 (05:18 +0000)
resolution.  Fix test for negative remainder.  Use timeGetTime through gtod.
(sleep): Round up return value.  Christopher Faylor <cgf@redhat.com>
* hires.h (HIRES_DELAY_MAX): Define.
(hires_ms::minperiod): Declare static.
(hires_ms::resolution): New.
(hires_ms::dmsecs): New.
(hires_ms::prime): Return UINT.
(gtod): Declare.
* times.cc (hires_ms::prime): Always calculate minperiod and set it to 1 in
case of failure.  Return minperiod.
(hires_ms::resolution): Define.
(hires_ms::~hires_ms): Delete.
(hires_ms::usecs): Check minperiod to prime.
(gtod) Define as global.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/hires.h
winsup/cygwin/signal.cc
winsup/cygwin/times.cc

index b8eb924..e74675b 100644 (file)
@@ -1,3 +1,26 @@
+2003-09-07  Pierre Humblet <pierre.humblet@ieee.org>
+
+       * signal.cc (nanosleep): Improve test for valid values.  Round delay up
+       to resolution.  Fix test for negative remainder.  Use timeGetTime
+       through gtod.
+       (sleep): Round up return value.
+
+2003-09-07  Pierre Humblet <pierre.humblet@ieee.org>
+           Christopher Faylor  <cgf@redhat.com>
+
+       * hires.h (HIRES_DELAY_MAX): Define.
+       (hires_ms::minperiod): Declare static.
+       (hires_ms::resolution): New.
+       (hires_ms::dmsecs): New.
+       (hires_ms::prime): Return UINT.
+       (gtod): Declare.
+       * times.cc (hires_ms::prime): Always calculate minperiod and set it to
+       1 in case of failure.  Return minperiod.
+       (hires_ms::resolution): Define.
+       (hires_ms::~hires_ms): Delete.
+       (hires_ms::usecs): Check minperiod to prime.
+       (gtod) Define as global.
+
 2003-09-06  Christopher Faylor  <cgf@redhat.com>
 
        Remove left coercion throughout.
index 5fdf462..5ccaa42 100644 (file)
@@ -329,7 +329,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t& ulen)
        }
     }
 
-  (ssize_t) ulen = bytes_read;
+  ulen = (size_t) bytes_read;
   return;
 
 err:
index b4599cb..df4c44c 100644 (file)
@@ -13,11 +13,18 @@ details. */
 
 #include <mmsystem.h>
 
+/* Largest delay in ms for sleep and alarm calls.
+   Allow actual delay to exceed requested delay by 10 s.
+   Express as multiple of 1000 (i.e. seconds) + max resolution
+   The tv_sec argument in timeval structures cannot exceed
+   HIRES_DELAY_MAX / 1000 - 1, so that adding fractional part
+   and rounding won't exceed HIRES_DELAY_MAX */
+#define HIRES_DELAY_MAX (((UINT_MAX - 10000) / 1000) * 1000) + 10
+
 class hires_base
 {
  protected:
   int inited;
-  virtual void prime () {}
  public:
   virtual LONGLONG usecs (bool justdelta) {return 0LL;}
   virtual ~hires_base () {}
@@ -37,9 +44,14 @@ class hires_ms : hires_base
 {
   DWORD initime_ms;
   LARGE_INTEGER initime_us;
-  UINT minperiod;
-  void prime ();
+  static UINT minperiod;
+  UINT prime ();
  public:
   LONGLONG usecs (bool justdelta);
+  UINT dmsecs () { return timeGetTime (); }
+  UINT resolution () { return minperiod ?: prime (); }
+
 };
+
+extern hires_ms gtod;
 #endif /*__HIRES_H__*/
index 2b890dd..133f192 100644 (file)
@@ -17,6 +17,7 @@ details. */
 #include <sys/cygwin.h>
 #include "sigproc.h"
 #include "pinfo.h"
+#include "hires.h"
 
 int sigcatchers;       /* FIXME: Not thread safe. */
 
@@ -73,20 +74,22 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
   sigframe thisframe (mainthread);
   pthread_testcancel ();
 
-  if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec > 999999999)
+  if ((unsigned int) rqtp->tv_sec > (HIRES_DELAY_MAX / 1000 - 1)
+      || (unsigned int) rqtp->tv_nsec > 999999999)
     {
       set_errno (EINVAL);
       return -1;
     }
-
-  DWORD req = rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 500000) / 1000000;
-  DWORD start_time = GetTickCount ();
-  DWORD end_time = start_time + req;
+  DWORD resolution = gtod.resolution ();
+  DWORD req = ((rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000
+               + resolution - 1) / resolution ) * resolution;
+  DWORD end_time = gtod.dmsecs () + req;
   syscall_printf ("nanosleep (%ld)", req);
 
   int rc = pthread::cancelable_wait (signal_arrived, req);
-  DWORD now = GetTickCount ();
-  DWORD rem = (rc == WAIT_TIMEOUT || now >= end_time) ? 0 : end_time - now;
+  DWORD rem;
+  if ((rem = end_time - gtod.dmsecs ()) > HIRES_DELAY_MAX)
+    rem = 0;
   if (rc == WAIT_OBJECT_0)
     {
       (void) thisframe.call_signal_handler ();
@@ -111,7 +114,7 @@ sleep (unsigned int seconds)
   req.tv_sec = seconds;
   req.tv_nsec = 0;
   nanosleep (&req, &rem);
-  return rem.tv_sec + (rem.tv_nsec + 500000000) / 1000000000;
+  return rem.tv_sec + (rem.tv_nsec > 0);
 }
 
 extern "C" unsigned int
index 0d4bc71..9eea335 100644 (file)
@@ -142,11 +142,13 @@ totimeval (struct timeval *dst, FILETIME *src, int sub, int flag)
   dst->tv_sec = x / (long long) (1e6);
 }
 
+hires_ms gtod;
+UINT NO_COPY hires_ms::minperiod;
+
 /* FIXME: Make thread safe */
 extern "C" int
 gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  static hires_ms gtod;
   static bool tzflag;
   LONGLONG now = gtod.usecs (false);
   if (now == (LONGLONG) -1)
@@ -620,37 +622,42 @@ hires_us::usecs (bool justdelta)
   return justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
 }
 
-void
+UINT
 hires_ms::prime ()
 {
   TIMECAPS tc;
   FILETIME f;
-  int priority = GetThreadPriority (GetCurrentThread ());
-  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
 
-  if (timeGetDevCaps (&tc, sizeof (tc)) != TIMERR_NOERROR)
-    minperiod = 0;
-  else
-    {
-      minperiod = min (max (tc.wPeriodMin, 1), tc.wPeriodMax);
-      timeBeginPeriod (minperiod);
-    }
+  if (!minperiod)
+    if (timeGetDevCaps (&tc, sizeof (tc)) != TIMERR_NOERROR)
+      minperiod = 1;
+    else
+      {
+       minperiod = min (max (tc.wPeriodMin, 1), tc.wPeriodMax);
+       timeBeginPeriod (minperiod);
+      }
 
-  initime_ms = timeGetTime ();
-  GetSystemTimeAsFileTime (&f);
-  SetThreadPriority (GetCurrentThread (), priority);
+  if (!inited)
+    {
+      int priority = GetThreadPriority (GetCurrentThread ());
+      SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
+      initime_ms = timeGetTime ();
+      GetSystemTimeAsFileTime (&f);
+      SetThreadPriority (GetCurrentThread (), priority);
 
-  inited = 1;
-  initime_us.HighPart = f.dwHighDateTime;
-  initime_us.LowPart = f.dwLowDateTime;
-  initime_us.QuadPart -= FACTOR;
-  initime_us.QuadPart /= 10;
+      inited = 1;
+      initime_us.HighPart = f.dwHighDateTime;
+      initime_us.LowPart = f.dwLowDateTime;
+      initime_us.QuadPart -= FACTOR;
+      initime_us.QuadPart /= 10;
+    }
+  return minperiod;
 }
 
 LONGLONG
 hires_ms::usecs (bool justdelta)
 {
-  if (!inited)
+  if (!minperiod) /* NO_COPY variable */
     prime ();
   DWORD now = timeGetTime ();
   // FIXME: Not sure how this will handle the 49.71 day wrap around