Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-09-07 09:18:01 +0400
committerChristopher Faylor <me@cgf.cx>2003-09-07 09:18:01 +0400
commited2287adcd6b16a0ef34defb443d5c61fc7830d7 (patch)
tree4b567ae87a505f3fb4bc5ba3329db06a1936df78 /winsup
parent6cce721b15c6ac75e7d6ae86a4354aa02bcf14d8 (diff)
* 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. 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog23
-rw-r--r--winsup/cygwin/fhandler_raw.cc2
-rw-r--r--winsup/cygwin/hires.h18
-rw-r--r--winsup/cygwin/signal.cc19
-rw-r--r--winsup/cygwin/times.cc47
5 files changed, 77 insertions, 32 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b8eb9245b..e74675be1 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc
index 5fdf462ab..5ccaa4292 100644
--- a/winsup/cygwin/fhandler_raw.cc
+++ b/winsup/cygwin/fhandler_raw.cc
@@ -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:
diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h
index b4599cb1b..df4c44c4a 100644
--- a/winsup/cygwin/hires.h
+++ b/winsup/cygwin/hires.h
@@ -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__*/
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 2b890dd62..133f192b4 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -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
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index 0d4bc7112..9eea3352d 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -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